From 981cc8ed918c79c78ba1f83a60f12cb6496a1943 Mon Sep 17 00:00:00 2001 From: Devin Rousso Date: Wed, 29 Jul 2026 10:55:17 -0600 Subject: [PATCH] chore(firefox): remove the `WebSocket` handshake `Worker` workaround `D310690` preserves the original `LoadInfo` when Firefox creates the handshake channel, which keeps the worker browsing context associated with its `WebSocket` request require `requestData` again in `FrameManager.onWebSocketRequest` and assert that `_onWebSocketOpened` receives it remove the Firefox guards for the worker `locale` and `setExtraHTTPHeaders` coverage because the association now reaches both handshake paths this requires the Firefox `154` roll that first includes `D310690` --- .../playwright-core/src/server/firefox/ffPage.ts | 16 +++++----------- packages/playwright-core/src/server/frames.ts | 7 +++---- tests/library/browsercontext-locale.spec.ts | 6 ++---- tests/library/web-socket.spec.ts | 3 +-- 4 files changed, 11 insertions(+), 21 deletions(-) diff --git a/packages/playwright-core/src/server/firefox/ffPage.ts b/packages/playwright-core/src/server/firefox/ffPage.ts index 0449f341b97ee..23e812b450260 100644 --- a/packages/playwright-core/src/server/firefox/ffPage.ts +++ b/packages/playwright-core/src/server/firefox/ffPage.ts @@ -159,23 +159,17 @@ export class FFPage implements PageDelegate { } _onWebSocketOpened(event: Protocol.Page.webSocketOpenedPayload) { - const socketId = webSocketId(event.frameId, event.wsid); const request = this._webSocketRequests.get(event.requestId); + assert(request); + const response = this._webSocketResponses.get(event.requestId); - // A `WebSocket` opened inside a worker is reported here, but its upgrade request is - // never seen by the network stack, so there is no handshake metadata to attach. - // TODO: Remove this workaround and make `requestData` required in `FrameManager.onWebSocketRequest` - // once Playwright's bundled Firefox includes https://phabricator.services.mozilla.com/D310690. - if (!request || !response) { - this._page.frameManager.onWebSocketRequest(socketId); - return; - } + assert(response); this._webSocketRequests.delete(event.requestId); this._webSocketResponses.delete(event.requestId); - this._page.frameManager.onWebSocketRequest(socketId, request); - this._page.frameManager.onWebSocketResponse(socketId, response); + this._page.frameManager.onWebSocketRequest(webSocketId(event.frameId, event.wsid), request); + this._page.frameManager.onWebSocketResponse(webSocketId(event.frameId, event.wsid), response); } _onWebSocketClosed(event: Protocol.Page.webSocketClosedPayload) { diff --git a/packages/playwright-core/src/server/frames.ts b/packages/playwright-core/src/server/frames.ts index 7c63126c6c8d5..8d87d25b0e513 100644 --- a/packages/playwright-core/src/server/frames.ts +++ b/packages/playwright-core/src/server/frames.ts @@ -433,20 +433,19 @@ export class FrameManager { this._webSockets.set(requestId, ws); } - onWebSocketRequest(requestId: string, requestData?: { headers: types.HeadersArray, wallTimeMs?: number }) { + onWebSocketRequest(requestId: string, requestData: { headers: types.HeadersArray, wallTimeMs?: number }) { const ws = this._webSockets.get(requestId); if (!ws) return; - ws.setWallTimeMs(requestData?.wallTimeMs); + ws.setWallTimeMs(requestData.wallTimeMs); if (ws.markAsNotified()) { this._page.emit(Page.Events.WebSocket, ws); this._page.browserContext.emit(BrowserContext.Events.WebSocket, ws, this._page); } - if (requestData) - ws.requestSent(requestData.headers); + ws.requestSent(requestData.headers); } onWebSocketResponse(requestId: string, responseData: { status: number, statusText: string, headers: types.HeadersArray }) { diff --git a/tests/library/browsercontext-locale.spec.ts b/tests/library/browsercontext-locale.spec.ts index b9780fe43eead..9846f2997b0aa 100644 --- a/tests/library/browsercontext-locale.spec.ts +++ b/tests/library/browsercontext-locale.spec.ts @@ -225,8 +225,7 @@ it('should send user Accept-Language header', { it('should send Accept-Language header on WebSocket handshake', { annotation: [{ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/23732' }], -}, async ({ browser, server, browserName, browserMajorVersion, isBidi }) => { - it.fixme(browserName === 'firefox' && !isBidi, 'Firefox/Juggler does not send Accept-Language on WebSocket handshake'); +}, async ({ browser, server, browserName, browserMajorVersion }) => { it.fixme(browserName === 'chromium' && browserMajorVersion < 151, 'Chromium before 151 sends the browser Accept-Language instead of the emulated locale on WebSocket handshake'); const context = await browser.newContext({ locale: 'en-GB' }); @@ -241,8 +240,7 @@ it('should send Accept-Language header on WebSocket handshake', { it('should send Accept-Language header on WebSocket handshake from a worker', { annotation: [{ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/13919' }], -}, async ({ browser, server, browserName, browserMajorVersion, isBidi }) => { - it.fixme(browserName === 'firefox' && !isBidi, 'Firefox/Juggler does not associate a WebSocket opened inside a worker with its browsing context'); +}, async ({ browser, server, browserName, browserMajorVersion }) => { it.fixme(browserName === 'chromium' && browserMajorVersion < 151, 'Chromium before 151 sends the browser Accept-Language instead of the emulated locale on WebSocket handshake'); const context = await browser.newContext({ locale: 'en-GB' }); diff --git a/tests/library/web-socket.spec.ts b/tests/library/web-socket.spec.ts index ddc6bca903fff..60acc51268934 100644 --- a/tests/library/web-socket.spec.ts +++ b/tests/library/web-socket.spec.ts @@ -259,9 +259,8 @@ it('should send extra HTTP headers on WebSocket handshake', { it('should send extra HTTP headers on WebSocket handshake from a worker', { annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/28948' }, -}, async ({ page, server, browserName, browserMajorVersion, isBidi }) => { +}, async ({ page, server, browserName, browserMajorVersion }) => { it.fixme(browserName === 'chromium' && browserMajorVersion < 151, 'Chromium before 151 does not send extra HTTP headers on WebSocket handshake'); - it.fixme(browserName === 'firefox' && !isBidi, 'Firefox/Juggler does not associate a WebSocket opened inside a worker with its browsing context'); await page.setExtraHTTPHeaders({ foo: 'bar' }); await page.goto(server.EMPTY_PAGE);