Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
playwright-msw
Advanced tools
A Mock Service Worker (MSW) integration layer for Playwright.
As of version 3, playwright-msw
has been updated to utilize MSW 2.x. In order to utilize the latest version of playwright-msw
, you must update your tests to use the new syntax. Please follow MSW's amazing Migration Guide. Apart from updating your tests to use MSW's new syntax, the API for playwright-msw
itself remains unchanged.
If you're not ready to update your tests, please continue to use version 2.x of playwright-msw
.
This library assumes that you have the following peer dependencies are already installed:
To start, install the dependency using your preferred package manager:
npm install playwright-msw --save-dev
# or
yarn add playwright-msw --dev
If you haven't already done so, create some mock handlers for API calls that your app will perform. e.g. within a handlers.ts file:
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,
},
);
}),
];
The next step is to create a custom fixture using the createWorkerFixture function from playwright-msw
. e.g. within a custom test.ts file:
If you're using REST API's, all you need to do is provide your handlers to createWorkerFixture
, no config object is required:
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: MockServiceWorker;
http: typeof http;
}>({
worker: createWorkerFixture(handlers),
http
});
export { expect, test };
Note: if you're using GraphQL, then it is assumed that the calls are made over HTTP. The default uri for the graphql endpoint is /graphql
. This can be customized via configuration object when creating the worker.
The final step is to use the extended test
implementation within your playwright tests. e.g. within a http.spec.ts file:
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();
});
});
createWorkerFixture
The createWorkerFixture(handlers, config)
function creates a fixture that mocks api calls on a per-test basis that is automatically started even if the test does not use it directly. The provided handlers will be used by all tests by default. The created MockServiceWorker fixture can be optionally used to customise mocks on a per-test basis.
Refer to the Getting Started: Create a the worker fixture for a usage example. If this abstraction layer is over-simplified for your use case, the createWorker function can be used instead.
The createWorkerFixture
function supports an optional configuration object with the following parameters:
key | required | default | description |
---|---|---|---|
graphqlUrl | false | "/graphql" | The URL of the GraphQL endpoint to send requests to. |
waitForPageLoad | false | true | Waits for the page to load before mocking API calls. When enabled, it allows playwright-msw to mirror the behaviour of msw when it is running in the browser, where the initial static resource requests will not be mocked because msw will have only been initialized until after page load. |
When enabled, it allows playwright-msw
to emulate the behavior of msw
when running in the browser, i.e. initialize after page load |
createWorker
The createWorker(page: Page, handlers?: RequestHandler[], config?: Config)
function creates a server that intercepts and mocks API calls for an individual playwright page. It returns a MockServiceWorker object which can be used for further customization.
Usage example:
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);
// Test has not started to execute...
await use(server);
// Test has finished executing...
// [insert any cleanup actions here]
},
{
/**
* Scope this fixture on a per test basis to ensure that each test has a
* fresh copy of MSW. Note: the scope MUST be "test" to be able to use the
* `page` fixture as it is not possible to access it when scoped to the
* "worker".
*/
scope: 'test',
/**
* By default, fixtures are lazy; they will not be initalised unless they're
* used by the test. Setting `true` here means that the fixture will be auto-
* initialised even if the test doesn't use it.
*/
auto: true,
},
],
});
export { test, expect };
MockServiceWorker
The MockServiceWorker
instance returned by createWorker or exposed via createWorkerFixture has a number of utility functions to facilitate additional customisations:
use(...customHandlers: RequestHandler[])
: Prepends given request handlers to the list of existing handlers. This is useful for overriding mocks on a per test behaviour, e.g. testing what happens if a particular API call fails.resetHandlers(...customHandlers: RequestHandler[])
: Resets request handlers to the initial list given to the createWorker call, or to the explicit next request handlers list, if given.resetCookieStore()
: Resets MSW's internal cookie store by removing all cookies from it. *Note: this is automatically called at the end of each test.*This library tests itself to make sure the integration between MSW and Playwright is working as expected. For real examples of how it can be used, please refer to: packages/example/README.md
This library does not seek to steal any thunder, it merely unifies two amazing tools that have already been built:
Thank you for making these tools and thank you to the numerous people who have contributed to playwright-msw
🙂
If the target application is already running MSW in the browser (e.g. a local dev server), this will need to be disabled while the Playwright tests are executing. It is recommended to test against the production bundle. ↩
FAQs
A Mock Service Worker API for Playwright.
The npm package playwright-msw receives a total of 49,921 weekly downloads. As such, playwright-msw popularity was classified as popular.
We found that playwright-msw demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.