From 8f292e09bf4e0485395689eb634efddaf3bc47bf Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Fri, 24 Jun 2022 10:48:16 -0700 Subject: [PATCH] cherry-pick(#15112): fix(route): match against updated url while chaining --- .../src/client/browserContext.ts | 4 +++- packages/playwright-core/src/client/page.ts | 4 +++- tests/library/browsercontext-route.spec.ts | 20 +++++++++++++++++++ tests/page/page-request-fallback.spec.ts | 2 +- tests/page/page-route.spec.ts | 20 +++++++++++++++++++ 5 files changed, 47 insertions(+), 3 deletions(-) diff --git a/packages/playwright-core/src/client/browserContext.ts b/packages/playwright-core/src/client/browserContext.ts index 5c45e564fd..be6de760a9 100644 --- a/packages/playwright-core/src/client/browserContext.ts +++ b/packages/playwright-core/src/client/browserContext.ts @@ -145,8 +145,10 @@ export class BrowserContext extends ChannelOwner } async _onRoute(route: network.Route, request: network.Request) { - const routeHandlers = this._routes.filter(r => r.matches(request.url())); + const routeHandlers = this._routes.slice(); for (const routeHandler of routeHandlers) { + if (!routeHandler.matches(request.url())) + continue; if (routeHandler.willExpire()) this._routes.splice(this._routes.indexOf(routeHandler), 1); const handled = await routeHandler.handle(route, request); diff --git a/packages/playwright-core/src/client/page.ts b/packages/playwright-core/src/client/page.ts index 12688638cb..fd4283b18d 100644 --- a/packages/playwright-core/src/client/page.ts +++ b/packages/playwright-core/src/client/page.ts @@ -179,8 +179,10 @@ export class Page extends ChannelOwner implements api.Page } private async _onRoute(route: Route, request: Request) { - const routeHandlers = this._routes.filter(r => r.matches(request.url())); + const routeHandlers = this._routes.slice(); for (const routeHandler of routeHandlers) { + if (!routeHandler.matches(request.url())) + continue; if (routeHandler.willExpire()) this._routes.splice(this._routes.indexOf(routeHandler), 1); const handled = await routeHandler.handle(route, request); diff --git a/tests/library/browsercontext-route.spec.ts b/tests/library/browsercontext-route.spec.ts index 8b7ae35a4e..0e8aa06fa6 100644 --- a/tests/library/browsercontext-route.spec.ts +++ b/tests/library/browsercontext-route.spec.ts @@ -268,6 +268,26 @@ it('should chain fallback', async ({ context, page, server }) => { expect(intercepted).toEqual([3, 2, 1]); }); +it('should chain fallback w/ dynamic URL', async ({ context, page, server }) => { + const intercepted = []; + await context.route('**/bar', route => { + intercepted.push(1); + route.fallback({ url: server.EMPTY_PAGE }); + }); + await context.route('**/foo', route => { + intercepted.push(2); + route.fallback({ url: 'http://localhost/bar' }); + }); + + await context.route('**/empty.html', route => { + intercepted.push(3); + route.fallback({ url: 'http://localhost/foo' }); + }); + + await page.goto(server.EMPTY_PAGE); + expect(intercepted).toEqual([3, 2, 1]); +}); + it('should not chain fulfill', async ({ context, page, server }) => { let failed = false; await context.route('**/empty.html', route => { diff --git a/tests/page/page-request-fallback.spec.ts b/tests/page/page-request-fallback.spec.ts index 9b14617f7e..b0b196260e 100644 --- a/tests/page/page-request-fallback.spec.ts +++ b/tests/page/page-request-fallback.spec.ts @@ -184,7 +184,7 @@ it('should override request url', async ({ page, server }) => { const request = server.waitForRequest('/global-var.html'); let url: string; - await page.route('**/foo', route => { + await page.route('**/global-var.html', route => { url = route.request().url(); route.continue(); }); diff --git a/tests/page/page-route.spec.ts b/tests/page/page-route.spec.ts index 4a481b4d21..95ada83008 100644 --- a/tests/page/page-route.spec.ts +++ b/tests/page/page-route.spec.ts @@ -321,6 +321,26 @@ it('should not work with redirects', async ({ page, server }) => { expect(chain[i].redirectedTo()).toBe(i ? chain[i - 1] : null); }); +it('should chain fallback w/ dynamic URL', async ({ page, server }) => { + const intercepted = []; + await page.route('**/bar', route => { + intercepted.push(1); + route.fallback({ url: server.EMPTY_PAGE }); + }); + await page.route('**/foo', route => { + intercepted.push(2); + route.fallback({ url: 'http://localhost/bar' }); + }); + + await page.route('**/empty.html', route => { + intercepted.push(3); + route.fallback({ url: 'http://localhost/foo' }); + }); + + await page.goto(server.EMPTY_PAGE); + expect(intercepted).toEqual([3, 2, 1]); +}); + it('should work with redirects for subresources', async ({ page, server }) => { const intercepted = []; await page.route('**/*', route => {