Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Experimental Service Worker Network Events #15684

Closed
rwoll opened this issue Jul 14, 2022 · 24 comments
Closed

[Feature] Experimental Service Worker Network Events #15684

rwoll opened this issue Jul 14, 2022 · 24 comments

Comments

@rwoll
Copy link
Member

rwoll commented Jul 14, 2022

Currently, Playwright supports an experimental feature to inspect and route Network traffic made by Service Workers (in Chrome / Chromium). To learn more and enable, please read: https://playwright.dev/docs/service-workers-experimental.

Please comment here if you use this feature (even if you just try it), and share your use case with us. This will help us prioritize removing the experimental nature of the feature and bringing support to the other browser integrations.

NB: If you're just looking to do network mocking, and service workers are getting in your way, see: https://playwright.dev/docs/network#missing-network-events-and-service-workers

@joshbrooks
Copy link

I tried this, our use case is in being able to mock 404's and 500's from service worker requests, to test an offline-first experience handling both GET and PUT/POST requests from service workers. Using the "experimental" flag "PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS" from Python with 1.25.2 seems to have no effect:

os.environ["PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS"] = "1"
  route.fulfill(
      status=HTTPStatus.INTERNAL_SERVER_ERROR,
      content_type="text/plain",
      body="not found!"
  )

This still returns a 200 from the service worker. Other (non-service-worker) requests return a 500 though

As a workaround, for some tests it's sufficient just to block service workers

context = browser.new_context(service_workers='block')

@wentokay
Copy link

wentokay commented Oct 5, 2022

Thanks for adding this experimental feature. I'm using it when testing a chrome browser extension.

Network requests are made from the background script (which is a serviceworker due to manifest v3 requirements)

It seems to be doing what I need right now but will report back if there are any issues.

@damienforster
Copy link

Interested in this also for Playwright testing a manifest v3 extension. Currently I'm not seeing requests from the service worker getting picked up, even with the PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS flag

@smokir
Copy link

smokir commented Nov 9, 2022

@damienforster I had the same problem because I was using jest-playwright-preset instead of @playwright/test

@MSOwnExperiment
Copy link

Thanks for adding this experimental feature. I'm using it when testing a chrome browser extension.

Network requests are made from the background script (which is a serviceworker due to manifest v3 requirements)

It seems to be doing what I need right now but will report back if there are any issues.

I also have the same use case. I could fetch the background page for Manifest V3. However, this part is not working for me.
const [request] = await Promise.all([
background.waitForRequest(request => request.postDataJSON().)
])

@rjones-sw
Copy link

Thanks for adding this experimental feature! Like wentokay I'm also using it when testing a chrome browser extension (which is similarly using service workers due to manifest v3 requirements)

@orenyomtov
Copy link
Contributor

This is not working for me trying to intercept/log requests originating from a chrome extension's background page using manifest v3, using playwright v1.29.1 and setting env var PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS=1

It seems that it worked for @wentokay @smokir @rjones-sw , but didn't work for @joshbrooks @damienforster @MSOwnExperiment

Any suggestions would be welcome

@MSOwnExperiment
Copy link

This is not working for me trying to intercept/log requests originating from a chrome extension's background page using manifest v3, using playwright v1.29.1 and setting env var PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS=1

It seems that it worked for @wentokay @smokir @rjones-sw , but didn't work for @joshbrooks @damienforster @MSOwnExperiment

Any suggestions would be welcome

I could resolve this. I did not have to use background page for manifest V3 and I could read events from context.

@orenyomtov
Copy link
Contributor

Found a solution!
You must explicitly set serviceWorkers: "allow", although allow is the default value!

orenyomtov added a commit to orenyomtov/playwright that referenced this issue Jan 4, 2023
In the implementation of adding the serviceWorkers option (microsoft#14714), the default value was not properly set.

This PR fixes the workaround needed here:
microsoft#15684 (comment)

As you can see, it is documented to default to `"allow"`:
https://github.com/rwoll/playwright/blob/main/docs/src/api/params.md#context-option-service-worker-policy

Signed-off-by: Oren <[email protected]>
@akaltar
Copy link

akaltar commented Mar 8, 2023

Thanks for this experimental feature.
I'm using this to test that a service worker fetch handler can be turned on/off with feature flags reliably, and that it can reconstruct range requests from the cache. Also planning to test what happens in case of IndexedDB errors and performance/memory usage in various network conditions

@adrienbrault
Copy link

I am testing a browser extension that makes http requests within a service worker. I am using context.routeFromHAR to be able to play my tests offline. However, http requests made by the service worker are not included in the HAR file.

Using PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS=1 fixes this: requests made by the service worker are correctly saved to the HAR file. When update: false it also works as expected and the service worker requests use the HAR file.

Support for Microsoft Edge would be nice!

@anirudh1713
Copy link

Thanks for this experimental feature! We want to use it for testing browser extension. (We make requests from background service worker).

@vbolshutkin
Copy link

A lovely feature! Really looking forward to get it available in Java API.

We use Service Worker as a backend for offline-enabled app

@jojobii-arks
Copy link

Thank you! Using this to test browser extension service worker network requests as well 👍

@BeeMargarida
Copy link
Contributor

This is a very useful feature! I've been using it to intercept requests made from the service worker we use for a offline-first PWA.

@CiaranMn
Copy link

I would like to use this feature to inspect websocket messages sent from a service worker (an extension background script).

I can see other network requests the service worker sends via context.on("request") and context.route – which is great! – but not websocket activity from the service worker. Is there an equivalent to page.on("websocket") for service workers, or other way of achieving this? The websocket is being opened and messages sent to the API during the test.

@davidstrouk
Copy link

I am using this feature in order to mock requests in Chrome extension with manifest v3. Thank you for letting us use this experimental feature!

@useadmin-jany
Copy link

I am trying to obtain the network and console of the service worker. I tried to call up the extension through v3, but currently I have not obtained the desired information

@mnholtz
Copy link

mnholtz commented Apr 11, 2024

We are using this feature in order to support testing our browser extension; it has satisfied our needs so far! The support is much appreciated.

@turt2live
Copy link

Dropping in to say we tried using the experimental support, but it ended up not working out for us. Our use case was to use the service worker to append Authorization headers to requests in <img /> tags, with credentials being stored in IndexedDB. This means we very quickly ran into #11164 because service workers cannot access localstorage, making the mock/shim unusable.

@GorvGoyl
Copy link

Here's what worked for me to intercept api calls from chrome extension (head as well as headless):

fixture.ts:

export const test = base.extend<{ context: BrowserContext; extensionId: string[] }>({
    context: async ({context}, use) => {
        const chatGptWriterExtensionPath = resolve(process.cwd(), './build/chrome-mv3-prod');
        const browserContext = await chromium.launchPersistentContext('', {
            headless: false,
            args: [
                `--headless=new`, //can comment this line to see browser
                `--disable-extensions-except=${chatGptWriterExtensionPath}`,
                `--load-extension=${chatGptWriterExtensionPath}`,
                `--disable-blink-features=AutomationControlled`,
                `--disable-dev-shm-usage`,
            ],
        });
        await use(browserContext);
        await browserContext.close();
    },
    extensionId: async ({ context }, use) => {
        let [background] = context.serviceWorkers();
        const serviceWorkers = context.serviceWorkers();
        const extensionIds = serviceWorkers.map((worker) => worker.url().split('/')[2]);
        if (!background) {
            background = await context.waitForEvent('serviceworker');
        }
        await use(extensionIds);
    },
});

export const expect = test.expect;

test:

// https://playwright.dev/docs/service-workers-experimental

process.env.PW_EXPERIMENTAL_SERVICE_WORKER_NETWORK_EVENTS = '1';

test('is request body ok', async ({ page, context, extensionId }) => {

    let [background] = context.serviceWorkers();
    if (!background) {
        background = await context.waitForEvent('serviceworker');
    }

    context.on('request', (worker) => {
        if (worker.url().includes('api/ai/generateStreamingResponse')) {
            apiBody = worker.postData();
            expect(apiBody).toBe(expectedApiBody);
        }
    });

    await performActionOnExtension(page);

});

@denniscual
Copy link

Im using this feature to set custom headers to all requests, including service worker, made by app to a list of servers.

@BrunoBernardino
Copy link

I'm using this feature to test if a service worker registers successfully (confirming it doesn't throw any error on setup).

@awerchniak
Copy link

I would like to use this feature to monitor network events from a chrome extension running within my test environment. Unfortunately I don't believe that it's possible with playwright Python today, but if it is please let me know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests