### Install playwright-msw Package Source: https://github.com/valendres/playwright-msw/blob/main/packages/playwright-msw/README.md Installs the playwright-msw dependency as a development dependency using npm or yarn. ```shell npm install playwright-msw --save-dev # or yarn add playwright-msw --dev ``` -------------------------------- ### createWorkerFixture API Source: https://github.com/valendres/playwright-msw/blob/main/packages/playwright-msw/README.md The `createWorkerFixture` function sets up API mocking on a per-test basis, automatically starting the mock service worker. It provides default handlers for all tests and allows optional customization per test using the MockServiceWorker fixture. ```APIDOC ## API ### `createWorkerFixture(handlers, config)` **Description**: Creates a fixture that mocks API calls on a per-test basis. The mock service worker starts automatically. Provided handlers are used by default for all tests. **Method**: Function call **Parameters**: #### Path Parameters None #### Query Parameters None #### Request Body None #### Configuration (`config` object) - **graphqlUrl** (string) - Optional - Default: `"/graphql"` - The URL of the GraphQL endpoint. - **waitForPageLoad** (boolean) - Optional - Default: `true` - Waits for the page to load before mocking API calls. If enabled, `playwright-msw` mirrors `msw` browser behavior where initial static resource requests aren't mocked until after page load. ``` -------------------------------- ### Setup Playwright Worker Fixture with REST Handlers Source: https://github.com/valendres/playwright-msw/blob/main/packages/playwright-msw/README.md Creates a custom Playwright test fixture using `createWorkerFixture` from `playwright-msw`. This setup is specifically for REST API mocking and assumes handlers are provided directly. It extends the base Playwright test with a `worker` fixture and makes the `http` module available. ```typescript import { test as base, expect } from '@playwright/test'; import { http } from 'msw'; import type { MockServiceWorker } from 'playwright-msw'; import { createWorkerFixture } from 'playwright-msw'; import handlers from './handlers'; const test = base.extend({ worker: createWorkerFixture(handlers), http }); export { expect, test }; ``` -------------------------------- ### Create Mock Handlers with MSW (REST API) Source: https://github.com/valendres/playwright-msw/blob/main/packages/playwright-msw/README.md Defines mock handlers for REST API calls using MSW's http module. It includes a GET request handler for '/api/users' that returns a JSON response with a delay. This is a common pattern for setting up mock data in tests. ```typescript import { http, delay, HttpResponse } from 'msw'; /** A collection of handlers to be used by default for all tests. */ export default [ http.get('/api/users', async () => { await delay(500); return HttpResponse.json( [ { id: 'bcff5c0e-10b6-407b-94d1-90d741363885', firstName: 'Rhydian', lastName: 'Greig', }, { id: 'b44e89e4-3254-415e-b14a-441166616b20', firstName: 'Alessandro', lastName: 'Metcalfe', }, { id: '6e369942-6b5d-4159-9b39-729646549183', firstName: 'Erika', lastName: 'Richards', }, ], { status: 200, }, ); }), ]; ``` -------------------------------- ### Handle Multiple HTTP Methods for Same Endpoint with MSW Source: https://context7.com/valendres/playwright-msw/llms.txt Demonstrates handling multiple HTTP methods (GET, POST, PUT, DELETE) for the same URL path by registering individual MSW handlers for each method. This allows for testing distinct CRUD operation behaviors. ```typescript import { test, expect } from './test'; import { http, HttpResponse } from 'msw'; test('handles multiple methods on same endpoint', async ({ page, worker }) => { let userDatabase = [ { id: '1', name: 'Existing User' } ]; await worker.use( // GET - List users http.get('/api/users', () => { return HttpResponse.json(userDatabase); }), // POST - Create user http.post('/api/users', async ({ request }) => { const newUser = await request.json(); const user = { id: String(Date.now()), ...newUser }; userDatabase.push(user); return HttpResponse.json(user, { status: 201 }); }), // PUT - Update user http.put('/api/users/:id', async ({ params, request }) => { const updates = await request.json(); const index = userDatabase.findIndex(u => u.id === params.id); if (index >= 0) { userDatabase[index] = { ...userDatabase[index], ...updates }; return HttpResponse.json(userDatabase[index]); } return HttpResponse.json(null, { status: 404 }); }), // DELETE - Remove user http.delete('/api/users/:id', ({ params }) => { userDatabase = userDatabase.filter(u => u.id !== params.id); return HttpResponse.json({ success: true }, { status: 204 }); }) ); // Test the complete CRUD flow await page.goto('/users'); await expect(page.locator('text="Existing User"')).toBeVisible(); await page.click('button[data-action="add"]'); await page.fill('[name="name"]', 'New User'); await page.click('button[type="submit"]'); await expect(page.locator('text="New User"')).toBeVisible(); }); ``` -------------------------------- ### Create Worker - Manual Initialization for Advanced Use Cases Source: https://context7.com/valendres/playwright-msw/llms.txt Creates a MockServiceWorker instance manually, offering full control over its lifecycle. This is ideal for advanced scenarios needing custom fixture logic, setup, and teardown. It returns a Promise resolving to a MockServiceWorker instance. ```typescript import { test as base, expect } from '@playwright/test'; import { http, HttpResponse } from 'msw'; import { createWorker, MockServiceWorker } from 'playwright-msw'; const handlers = [ http.get('/api/settings', () => { return HttpResponse.json({ theme: 'dark', language: 'en' }); }) ]; const test = base.extend({ worker: [ async ({ page }, use) => { // Custom setup before test const worker = await createWorker(page, handlers, { graphqlUrl: '/graphql', waitForPageLoad: true }); console.log('Worker initialized for test'); // Test executes await use(worker); // Custom cleanup after test worker.resetCookieStore(); console.log('Worker cleaned up after test'); }, { scope: 'test', auto: true } ] }); test('applies custom settings', async ({ page }) => { await page.goto('/settings'); await expect(page.locator('[data-theme="dark"]')).toBeVisible(); }); export { test, expect }; ``` -------------------------------- ### createWorkerFixture with Configuration Source: https://context7.com/valendres/playwright-msw/llms.txt Configure the GraphQL endpoint URL and page load behavior when creating the worker fixture. The `graphqlUrl` option sets the GraphQL endpoint path (defaults to `/graphql`), while `waitForPageLoad` controls whether to wait for initial page load before mocking (defaults to `true` to mirror MSW browser behavior). ```APIDOC ## createWorkerFixture with Configuration ### Description Configure GraphQL endpoint URL and page load behavior when creating the worker fixture. The `graphqlUrl` option sets the GraphQL endpoint path (defaults to `/graphql`), while `waitForPageLoad` controls whether to wait for initial page load before mocking (defaults to `true` to mirror MSW browser behavior). ### Method `createWorkerFixture(handlers: Array, config: Config)` ### Parameters #### Handlers - **handlers** (Array) - Required - An array of MSW request handlers. #### Configuration Options - **config** (Config) - Required - Configuration object for the worker fixture. - **graphqlUrl** (string) - Optional - The URL path for the GraphQL endpoint. Defaults to `/graphql`. - **waitForPageLoad** (boolean) - Optional - Whether to wait for the initial page load before mocking. Defaults to `true`. ### Request Example ```typescript import { test as base, expect } from '@playwright/test'; import { graphql, HttpResponse } from 'msw'; import type { MockServiceWorker, Config } from 'playwright-msw'; import { createWorkerFixture } from 'playwright-msw'; const handlers = [ graphql.query('GetUser', () => { return HttpResponse.json({ data: { user: { id: '1', name: 'John Doe', email: 'john@example.com' } } }); }) ]; // Configure custom GraphQL endpoint and page load behavior const config: Config = { graphqlUrl: '/api/graphql', waitForPageLoad: true }; const test = base.extend({ worker: createWorkerFixture(handlers, config) }); test('loads user data via GraphQL', async ({ page }) => { await page.goto('/profile'); await expect(page.locator('text="john@example.com"')).toBeVisible(); }); export { test, expect }; ``` ### Response This function returns a Playwright fixture configuration object that can be used to extend the Playwright `test` object. ### Response Example N/A (This is a function that returns configuration) ``` -------------------------------- ### Configure Worker Fixture with GraphQL URL and Page Load Behavior (TypeScript) Source: https://context7.com/valendres/playwright-msw/llms.txt Configures the GraphQL endpoint URL and page load behavior for the worker fixture. The `graphqlUrl` option sets the GraphQL endpoint path (defaults to `/graphql`), and `waitForPageLoad` controls whether to wait for initial page load before mocking (defaults to `true`). Dependencies include '@playwright/test', 'msw', and 'playwright-msw'. ```typescript import { test as base, expect } from '@playwright/test'; import { graphql, HttpResponse } from 'msw'; import type { MockServiceWorker, Config } from 'playwright-msw'; import { createWorkerFixture } from 'playwright-msw'; const handlers = [ graphql.query('GetUser', () => { return HttpResponse.json({ data: { user: { id: '1', name: 'John Doe', email: 'john@example.com' } } }); }) ]; // Configure custom GraphQL endpoint const config: Config = { graphqlUrl: '/api/graphql', waitForPageLoad: true }; const test = base.extend({ worker: createWorkerFixture(handlers, config) }); test('loads user data via GraphQL', async ({ page }) => { await page.goto('/profile'); await expect(page.locator('text="john@example.com"')).toBeVisible(); }); export { test, expect }; ``` -------------------------------- ### Create Auto-Initialized Test Fixture with Default Handlers (TypeScript) Source: https://context7.com/valendres/playwright-msw/llms.txt Creates a Playwright fixture that automatically mocks API calls for each test using provided default handlers. It ensures consistent mock behavior across all tests. Returns a tuple containing the fixture function and configuration options. Dependencies include '@playwright/test', 'msw', and 'playwright-msw'. ```typescript import { test as base, expect } from '@playwright/test'; import { http, HttpResponse } from 'msw'; import type { MockServiceWorker } from 'playwright-msw'; import { createWorkerFixture } from 'playwright-msw'; // Define default handlers used across all tests const handlers = [ http.get('/api/users', async () => { return HttpResponse.json([ { id: '1', firstName: 'John', lastName: 'Doe' }, { id: '2', firstName: 'Jane', lastName: 'Smith' } ], { status: 200 }); }) ]; // Extend Playwright test with worker fixture const test = base.extend({ worker: createWorkerFixture(handlers), http }); // Use in tests - default handlers apply automatically test('displays user list with default mocks', async ({ page }) => { await page.goto('/users'); await expect(page.locator('text="John Doe"')).toBeVisible(); }); // Override mocks on a per-test basis test('handles API error gracefully', async ({ page, worker }) => { await worker.use( http.get('/api/users', () => HttpResponse.json(null, { status: 500 })) ); await page.goto('/users'); await expect(page.locator('text="Failed to load"')).toBeVisible(); }); export { test, expect }; ``` -------------------------------- ### createWorker API Source: https://github.com/valendres/playwright-msw/blob/main/packages/playwright-msw/README.md The `createWorker` function generates a server to intercept and mock API calls for a specific Playwright page. It returns a MockServiceWorker object for further adjustments. ```APIDOC ## API ### `createWorker(page: Page, handlers?: RequestHandler[], config?: Config)` **Description**: Creates a server that intercepts and mocks API calls for an individual Playwright page. Returns a MockServiceWorker object for further customization. **Method**: Function call **Parameters**: #### Path Parameters None #### Query Parameters None #### Request Body None #### Parameters - **page** (Page) - Required - The Playwright page object. - **handlers** (RequestHandler[]) - Optional - An array of MSW request handlers. - **config** (Config) - Optional - Configuration object for the worker. ### Request Example ```typescript import { test as base, expect } from '@playwright/test'; import { createWorker, MockServiceWorker } from 'playwright-msw'; import handlers from './handlers'; const test = base.extend<{ worker: MockServiceWorker }>({ worker: [ async ({ page }, use) => { const server = await createWorker(page, handlers); await use(server); }, { scope: 'test', auto: true, }, ], }); export { test, expect }; ``` ``` -------------------------------- ### REST API Mocking with Path Parameters in TypeScript Source: https://context7.com/valendres/playwright-msw/llms.txt Mocks REST endpoints with dynamic path parameters using MSW's syntax. It supports named parameters, wildcards, and regular expressions for flexible request matching, suitable for testing detail pages and dynamic routing. ```typescript import { test, expect } from './test'; import { http, HttpResponse, delay } from 'msw'; test.describe('Dynamic route handling', () => { test('mocks endpoint with path parameter', async ({ page, worker }) => { await worker.use( http.get('/api/users/:userId', async ({ params }) => { await delay(100); return HttpResponse.json({ id: params.userId, firstName: 'Dynamic', lastName: 'User', email: `user-${params.userId}@example.com` }); }) ); await page.goto('/users/12345'); await expect(page.locator('text="user-12345@example.com"')).toBeVisible(); }); test('mocks with wildcard patterns', async ({ page, worker }) => { await worker.use( http.get('/a*i/us*/:userId', () => { return HttpResponse.json({ id: 'wildcard-match', firstName: 'Pattern', lastName: 'Matched' }); }) ); await page.goto('/users/wildcard-match'); await expect(page.locator('text="Pattern Matched"')).toBeVisible(); }); test('mocks with regex patterns', async ({ page, worker }) => { await worker.use( http.get(//api/users/[w-]+/, () => { return HttpResponse.json({ id: 'regex', firstName: 'Regular', lastName: 'Expression' }); }) ); await page.goto('/users/any-id-works'); await expect(page.locator('text="Regular Expression"')).toBeVisible(); }); }); ``` -------------------------------- ### createWorkerFixture - Create Auto-Initialized Test Fixture Source: https://context7.com/valendres/playwright-msw/llms.txt Creates a Playwright fixture that automatically mocks API calls on a per-test basis using provided default handlers. This fixture is auto-initialized, ensuring consistent mock behavior across all tests. It returns a tuple containing the fixture function and configuration options. ```APIDOC ## createWorkerFixture ### Description Creates a Playwright fixture that automatically mocks API calls on a per-test basis using the provided default handlers. The fixture is auto-initialized even when not explicitly used by the test, ensuring consistent mock behavior across all tests. Returns a tuple containing the fixture function and configuration options. ### Method `createWorkerFixture(handlers: Array, config?: Config)` ### Parameters #### Handlers - **handlers** (Array) - Required - An array of MSW request handlers to be used as default mocks. #### Configuration Options - **config** (Config) - Optional - Configuration for the worker fixture. - **graphqlUrl** (string) - Optional - The URL path for the GraphQL endpoint. Defaults to `/graphql`. - **waitForPageLoad** (boolean) - Optional - Whether to wait for the initial page load before mocking. Defaults to `true` to mirror MSW browser behavior. ### Request Example ```typescript import { test as base, expect } from '@playwright/test'; import { http, HttpResponse } from 'msw'; import type { MockServiceWorker } from 'playwright-msw'; import { createWorkerFixture } from 'playwright-msw'; // Define default handlers used across all tests const handlers = [ http.get('/api/users', async () => { return HttpResponse.json([ { id: '1', firstName: 'John', lastName: 'Doe' }, { id: '2', firstName: 'Jane', lastName: 'Smith' } ], { status: 200 }); }) ]; // Extend Playwright test with worker fixture const test = base.extend({ worker: createWorkerFixture(handlers), http // Expose MSW http module }); // Use in tests - default handlers apply automatically test('displays user list with default mocks', async ({ page }) => { await page.goto('/users'); await expect(page.locator('text="John Doe"')).toBeVisible(); }); // Override mocks on a per-test basis test('handles API error gracefully', async ({ page, worker }) => { await worker.use( http.get('/api/users', () => HttpResponse.json(null, { status: 500 })) ); await page.goto('/users'); await expect(page.locator('text="Failed to load"')).toBeVisible(); }); export { test, expect }; ``` ### Response This function returns a Playwright fixture configuration object that can be used to extend the Playwright `test` object. ### Response Example N/A (This is a function that returns configuration) ``` -------------------------------- ### Create MSW Worker Fixture for Playwright (TypeScript) Source: https://github.com/valendres/playwright-msw/blob/main/packages/playwright-msw/README.md Illustrates the usage of the `createWorker` function to set up a Mock Service Worker for an individual Playwright page. This function intercepts and mocks API calls, returning a `MockServiceWorker` object for further customization. It's designed for per-test mocking. ```typescript import { test as base, expect } from '@playwright/test'; import { createWorker, MockServiceWorker } from 'playwright-msw'; import handlers from './handlers'; const test = base.extend({ worker: [ async ({ page }, use) => { const server = await createWorker(page, handlers); await use(server); }, { scope: 'test', auto: true, }, ], }); export { test, expect }; ``` -------------------------------- ### Mock GraphQL Operations with MSW Source: https://context7.com/valendres/playwright-msw/llms.txt Mocks GraphQL queries and mutations by operation name using MSW handlers. Supports custom response data, status codes, and error simulation. Operations are routed to the default '/graphql' endpoint. ```typescript import { test, expect } from './test'; import { graphql, HttpResponse } from 'msw'; test.describe('GraphQL operations', () => { test('mocks GraphQL query successfully', async ({ page, worker }) => { await worker.use( graphql.query('GetSettings', () => { return HttpResponse.json({ data: { settings: { enableNotifications: false, profileVisibility: 'public', language: 'es' } } }); }) ); await page.goto('/settings'); await expect(page.locator('[data-notifications="false"]')).toBeVisible(); await expect(page.locator('[data-visibility="public"]')).toBeVisible(); }); test('mocks GraphQL mutation', async ({ page, worker }) => { await worker.use( graphql.mutation('UpdateSettings', ({ variables }) => { return HttpResponse.json({ data: { updateSettings: { success: true, settings: variables } } }); }) ); await page.goto('/settings'); await page.click('[data-testid="toggle-notifications"]'); await page.click('button[type="submit"]'); await expect(page.locator('text="Settings saved"')).toBeVisible(); }); test('simulates GraphQL error', async ({ page, worker }) => { await worker.use( graphql.query('GetSettings', () => { return HttpResponse.json( { errors: [{ message: 'Failed to fetch settings', extensions: { code: 'INTERNAL_SERVER_ERROR' } }] }, { status: 500 } ); }) ); await page.goto('/settings'); await expect(page.locator('text="Failed to load settings"')).toBeVisible(); }); }); ``` -------------------------------- ### Playwright Test with Default and Overridden MSW Handlers (TypeScript) Source: https://github.com/valendres/playwright-msw/blob/main/packages/playwright-msw/README.md Demonstrates how to use the custom test fixture provided by playwright-msw. The first test uses default handlers, while the second test overrides a specific handler to return a 403 status code, showing how to customize mocks on a per-test basis. ```typescript import { delay, HttpResponse } from 'msw'; import { expect, test } from '../test'; test.describe.parallel("A demo of playwright-msw's functionality", () => { test('should use the default handlers without requiring handlers to be specified on a per-test basis', async ({ page }) => { await page.goto('/'); await expect(page.locator('text="Alessandro Metcalfe"')).toBeVisible(); }); test.only('should allow mocks to be overridden on a per test basis', async ({ page, worker, http }) => { await worker.use( http.get('/api/users', async () => { await delay(250); return new HttpResponse(null, { status: 403, }); }), ); await page.goto('/'); await expect(page.locator('text="Alessandro Metcalfe"')).toBeHidden(); await expect(page.locator('text="Failed to load users"')).toBeVisible(); }); }); ``` -------------------------------- ### Worker Use - Override Mocks for Specific Tests Source: https://context7.com/valendres/playwright-msw/llms.txt Prepends request handlers to the existing list for a specific test, enabling per-test mock customization. Handlers added via `use()` take precedence over defaults, useful for simulating edge cases like API failures or specific data scenarios. ```typescript import { test, expect } from './test'; import { http, HttpResponse, delay } from 'msw'; test.describe('User management with various scenarios', () => { test('simulates slow API response', async ({ page, worker }) => { await worker.use( http.get('/api/users', async () => { await delay(5000); return HttpResponse.json([{ id: '1', name: 'Test User' }]); }) ); await page.goto('/users'); await expect(page.locator('text="Loading..."')).toBeVisible(); }); test('simulates authentication failure', async ({ page, worker }) => { await worker.use( http.get('/api/users', () => { return HttpResponse.json( { error: 'Unauthorized' }, { status: 401 } ); }) ); await page.goto('/users'); await expect(page.locator('text="Please log in"')).toBeVisible(); }); test('handles multiple endpoints', async ({ page, worker }) => { await worker.use( http.get('/api/users', () => HttpResponse.json([{ id: '1', name: 'User' }])), http.get('/api/settings', () => HttpResponse.json({ theme: 'light' })), http.post('/api/users', () => HttpResponse.json({ id: '2' }, { status: 201 })) ); await page.goto('/dashboard'); await expect(page.locator('text="User"')).toBeVisible(); }); }); ``` -------------------------------- ### Worker Reset Handlers - Restore or Set New Mock Configurations Source: https://context7.com/valendres/playwright-msw/llms.txt Resets request handlers to the initial list provided during worker creation or to a new, explicitly provided set. This is useful for restoring default behavior after temporary overrides or switching between different mock configurations within a test. ```typescript import { test, expect } from './test'; import { http, HttpResponse } from 'msw'; test('resets handlers after temporary override', async ({ page, worker }) => { // Override default handler temporarily await worker.use( http.get('/api/users', () => { return HttpResponse.json([], { status: 200 }); }) ); await page.goto('/users'); await expect(page.locator('text="No users found"')).toBeVisible(); // Reset to default handlers await worker.resetHandlers(); await page.reload(); await expect(page.locator('text="John Doe"')).toBeVisible(); }); test('resets to specific handlers', async ({ page, worker }) => { const newHandlers = [ http.get('/api/users', () => { return HttpResponse.json([ { id: '99', firstName: 'New', lastName: 'User' } ]); }) ]; await worker.resetHandlers(...newHandlers); await page.goto('/users'); await expect(page.locator('text="New User"')).toBeVisible(); }); ``` -------------------------------- ### worker.resetCookieStore - Clear Cookie State with TypeScript Source: https://context7.com/valendres/playwright-msw/llms.txt Resets MSW's internal cookie store by removing all cookies. This ensures a clean state between tests. It's useful for manual cookie cleanup mid-test or when not using the `createWorkerFixture`. ```typescript import { test, expect } from './test'; import { http, HttpResponse } from 'msw'; test('manages cookies across test phases', async ({ page, worker }) => { await worker.use( http.post('/api/login', () => { return HttpResponse.json( { success: true }, { status: 200, headers: { 'Set-Cookie': 'sessionId=abc123; Path=/; HttpOnly' } } ); }), http.get('/api/profile', () => { return HttpResponse.json({ username: 'testuser' }); }) ); await page.goto('/login'); await page.fill('[name="username"]', 'test'); await page.click('button[type="submit"]'); await expect(page.locator('text="testuser"')).toBeVisible(); // Clear cookies mid-test worker.resetCookieStore(); await page.reload(); await expect(page.locator('text="Please log in"')).toBeVisible(); }); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.