-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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] support route aka request interception for service workers #1090
Comments
Any takers? |
Hi @Francois-Esquire, service workers are only available for secure contexts, which is not the case for your example. Running You could potentially serve the html over localhost with something like the http-server NPM package. Would love to learn why you want to use inline HTML instead. |
Hey @arjun27 , appreciate you taking time to respond! Hmm, I originally had set up a demo server on localhost and that was working as expected. I didn’t consider the secure context, but makes complete sense now in how I was using it... thanks for pointing that out. Maybe I could add:
To the arguments, or change the destination url to The goal essentially is to create a function I can reuse to execute code inside the service worker; on demand and with a portable solution not requiring an http server in place. I just need to register a service worker, thus a simple html page. Is there a better way of achieving this? |
|
@pavelfeldman Thanks for addressing that, and really excited to hear the plan with that! Love the API design with that, very intuitive. What I'm trying to do is register a service worker without a supporting web server to run What could be the cause to this? Am I missing anything else? Again, this works with a conventional web server backing the playwright usage. |
Coming from #5014 . I added my thumbs up to the issue, but I also think it's worth explicitly pointing out that the inability to use |
Hello 😃 First of all I would like to thank the Playwright team for their effort. Great project awaited by me for a long time! Good job 👍 I agree with @Aaron-Pool. The MSW library is a game changer in terms of the mocking of the back-end services and I think that not listening to the service workers requests is a significant drawback. I found this issue when I was looking for myself to integrate the MSW library with the Playwright with no luck. At least now I know the reason behind it. Another reason why this functionality should be prioritized and implemented is the support for GraphQL. It is used in the company that I work for and currently in the Playwright there is no easy possibility to differentiate the GraphQL requests. The MSW library solves this problem but currently Playwright do not like the service workers. I can easily imagine that a lot of people will have the same problem so this is not some kind of an edge case. I would very much like this functionality to be implemented in a reasonable time. Once again thank you for the Playwright 👍 |
Vote up for this feature. |
Is it possible to implement this behavior currently using the |
I think a current workaround could me to launch the browser with the |
This is the beginning of fixing microsoft#1090. There's still quite a bit to be done, but this at least shows an end-to-end path to accomplish the feature.
Hey. MSW author here. I'd very much love to see Playwright and MSW work together, which includes supporting more use cases. We've been testing MSW with Playwright for years and didn't have any issues. I think one of the things that confuses people the most is the execution context difference between your tests and the browser runtime in Playwright. That being said, I'd love to migrate to Let me know if I can be of any help when it comes to Service Worker nuances. |
Playwright + MSW ❤️ 🔥 ❤️ 🔥 These are two of my favorite testing tools and I'd love to see them work together seamlessly. |
Thanks @kettanaito! Happy to hop on a chat and learn more about MSW from your perspective. You can find me on in the Playwright Slack. At this point, this issue is tracking work in Playwright to ensure Network Requests occurring in SW's show up in Playwright's mocking/routing via |
Would love to, @rwoll! Alas, that Slack link is no longer active. Could you per chance generate a new one? I've just had an idea yesterday that may allow Playwright to know when requests are happening in the worker. Would love to tell you more about it and discuss whether it's something Playwright would want to support out of the box or as an extension. |
Oops—sorry about that! It should be updated now! 😄 |
Okay, I'm sharing my proposal below. ContextA brief context to bring everybody onboard. Service Workers execute in their own thread, and have their own scope. Because of this, Playwright doesn’t know when requests are issued by the worker because there’s no standard means to know that. Although the worker’s requests appear in the Network, they still execute in their own (worker) scope. ProposalI propose for Playwright to register a proxy worker that would look somewhat like this: // sw-proxy.js
self.addEventListener('install', () => {
sendToClient({ type: 'event', name: 'install' })
})
self.addEventListener('fetch', (event) => {
sendToClient({
type: 'request',
request: serializeRequest(request)
})
}) The goal is to signal about the worker events back to the client (Playwright). You can use both There’s one catch though: there can only be 1 worker controlling the page. So, obviously, introducing One of the ways to achieve this wrapping is by using the // sw-proxy.
// ...the rest of the proxy worker.
// Import the actual tested worker as the last thing.
// The order of imports affects the order of event
// propagation, so the proxy must always add its
// listeners first.
importScripts('/actual-user-worker.js') When the workers are combined, the same events will bubble through all of them based on the listener declaration order. If the proxy worker adds its listeners first, it will receive events first. On the premise that the proxy must treat events as readonly (never affect their outcome, for example, in the This order of execution may also allow us to influence event resolution in some cases. For example, if a request event matching a defined // sw-proxy.js
self.addEventListener('fetch', (event) => {
signalToClient(
{ type: 'request', ... },
(data) => {
const mockedResponse = JSON.parse(data)
event.respondWith(mockedResponse)
}
)
})
In a nutshell, this is how MSW works. There are 2 technical difficulties with this approach:
Request spying is the most tricky part of this entire proposal. Alternative routeI’m not aware how much Playwright is in control over the underlying Chromium but if it could patch the Service Worker’s global scope, then we could spy on the listeners without having to manage worker nesting and event propagation. Affecting the worker’s scope is rather dangerous so this must be approached with caution. Closing thoughtsIn the end, the challenge is to know when certain worker events happen. And while tools like MSW already implement this client-worker channel that allows to intercept requests, they do not care for other worker events (like life-cycle events), which may be of interest to people who would want to test their workers extensively. At the same time, MSW operates with a single worker, and whenever people have their own worker we just recommend to use |
As a general route, given the scope difference between the client and the worker, it may be a good idea to consider a different API to control worker events/requests other than page.serviceWorker.route('/user') There may be cases when the same resource is fetched on the client and on the worker, and you may want to control those cases differently. |
@kettanaito Thanks for the proposal! I think it's important to separate the discussion into at least two components:
Each can be solved different ways, and patching the browsers themselves is in scope (as needed). As part of #14716 —which allows you to intercept all requests (including the main SW script as well as requests being made inside the SW) via Playwright's native Proxying the SW is a neat idea worth exploring—but hitting limitations and interfering with user code as you've alluded to worries me. In general, we prefer native instrumentation, because it does not interfere with user code and brings us more capabilities. If folks are looking for more ways to test Service Workers themselves, that has yet to be explored as I've mainly focused on their networking components, but PW APIs that give you visibility and hooks into the SW lifecycle/versions etc. will likely show up at some point, but let's have that discussion in a distinct issue to keep this focused on solving the issue of mocking network requests. Footnotes
|
I totally understand and share this direction.
Really looking forward to this! I know it'd help me test some of my worker logic. |
…#14716) Adds Chromium support for Service Worker Networking (interception/routing, Request/Response events, and HAR). Resolves #1090. Depends on #14714 and #14714. Supercedes #14321. Follow up #14711. Landed upstream patches: - https://chromium-review.googlesource.com/c/chromium/src/+/3510917 - https://chromium-review.googlesource.com/c/chromium/src/+/3526571 - https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/3566669 - https://chromium-review.googlesource.com/c/chromium/src/+/3544685 - https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/3610924 - https://chromium-review.googlesource.com/c/chromium/src/+/3689949
#14716 landed which means—on Chromium-only for now—network requests made within Service Workers to external resources (and the initial Service Worker main script request), are now instrumented and visible via More exhaustive docs are still in the works, but for folks who want to try it out, you can try ToT
…and more in that file :) If you have questions—or bugs 🐛 —feel free to file a new issue under the question type and refer to this issue #1090. Please include your use case when filing so we can understand it in context. |
Playwright v1.24.0 was released this week. As part of the new release, we've updated the Playwright Network guide: https://playwright.dev/docs/network#missing-network-events-and-service-workers pertaining to this issue. Please check it out and let us know if you have any questions or if your use case is not addressed by commenting on #15684, or filing a new issue with a description of your use case. Thanks! |
Hi,
I'd like to be able to include markup directly instead of using
page.goto
to a remote address. I currently have a small example here of what I've tried out but it appears that'serviceWorker' in navigator
is returning false and registering a service worker fails.I've tried
page.setContent
as well and I had the same results.Can anyone tell me what I'm missing? The example I am running:
The text was updated successfully, but these errors were encountered: