From 7233e76d7a73f5200a5dc1283c68df4e7211b68e Mon Sep 17 00:00:00 2001 From: "Yury Semikhatskii (from Dev Box)" Date: Fri, 12 Jun 2026 11:00:28 -0700 Subject: [PATCH 1/2] feat(webkit): launch WebKit in WSL directly over WebSocket transport Launch the Linux WebKit build inside the "playwright" WSL distribution via wsl.exe with --remote-debugging-port=0 and connect to the printed ws:// endpoint from the Windows host (reachable thanks to WSL localhost forwarding). This replaces the reverted intermediate proxy server. Make killForTests wait for the transport disconnect so the kill appears atomic to clients, add a tests_webkit_wsl workflow that runs the WebKit suite headed and headless on the self-hosted Windows pool, and update library/page test expectations for the webkit-wsl channel. Reference: https://github.com/microsoft/playwright/issues/37036 --- .github/workflows/tests_webkit_wsl.yml | 71 +++++++++++++++++++ .../playwright-core/src/server/browser.ts | 4 ++ .../playwright-core/src/server/browserType.ts | 4 +- .../src/server/registry/index.ts | 11 ++- .../src/server/webkit/webkit.ts | 56 +++++++++++++-- tests/library/defaultbrowsercontext-2.spec.ts | 3 +- tests/library/har-websocket.spec.ts | 35 +++++---- tests/library/har.spec.ts | 4 +- tests/library/playwright.config.ts | 15 ---- tests/page/page-event-pageerror.spec.ts | 4 +- tests/page/page-fill.spec.ts | 4 +- tests/page/workers.spec.ts | 3 +- 12 files changed, 168 insertions(+), 46 deletions(-) create mode 100644 .github/workflows/tests_webkit_wsl.yml diff --git a/.github/workflows/tests_webkit_wsl.yml b/.github/workflows/tests_webkit_wsl.yml new file mode 100644 index 0000000000000..1a4919165aca7 --- /dev/null +++ b/.github/workflows/tests_webkit_wsl.yml @@ -0,0 +1,71 @@ +name: "tests webkit wsl" + +on: + push: + branches: + - main + - release-* + pull_request: + paths-ignore: + - 'browser_patches/**' + - 'docs/**' + - 'packages/playwright/src/mcp/**' + - 'tests/mcp/**' + branches: + - main + - release-* + workflow_dispatch: + +env: + # Force terminal colors. @see https://www.npmjs.com/package/colors + FORCE_COLOR: 1 + +permissions: + id-token: write # This is required for OIDC login (azure/login) to succeed + contents: read # This is required for actions/checkout to succeed + +jobs: + test_webkit_wsl: + name: "Tests @ WebKit WSL ${{ matrix.headed && '(headed)' || '(headless)' }}" + # WebKit in WSL needs a Windows host with WSL2 mirrored networking, which the + # GitHub-hosted windows-latest image does not support. Use the self-hosted pool. + runs-on: ["self-hosted", "1ES.Pool=DevDivPlaywrightWindows11"] + strategy: + fail-fast: false + matrix: + headed: [true, false] + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 + with: + node-version: 20 + # WebKit in WSL only reaches servers on the Windows host with mirrored networking. + - name: Enable WSL2 networkingMode=mirrored + shell: powershell + run: Add-Content -Path $env:USERPROFILE\.wslconfig -Value "[wsl2]`nnetworkingMode=mirrored" + - run: npm ci + env: + DEBUG: pw:install + PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 + - run: npm run build + - run: npx playwright install webkit-wsl ffmpeg + - name: Run tests + run: npm run wtest -- ${{ matrix.headed && '--headed' || '' }} + env: + PWTEST_CHANNEL: webkit-wsl + PW_TAG: "@webkit-wsl-${{ matrix.headed && 'headed' || 'headless' }}" + - name: Azure Login + if: ${{ !cancelled() && github.event_name == 'push' && github.repository == 'microsoft/playwright' }} + uses: azure/login@v2 + with: + client-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_TENANT_ID }} + subscription-id: ${{ secrets.AZURE_FLAKINESS_DASHBOARD_SUBSCRIPTION_ID }} + - run: ./utils/upload_flakiness_dashboard.sh ./test-results/report.json + if: ${{ !cancelled() && github.event_name == 'push' && github.repository == 'microsoft/playwright' }} + shell: bash + - uses: actions/upload-artifact@v7 + if: ${{ !cancelled() }} + with: + name: webkit-wsl-${{ matrix.headed && 'headed' || 'headless' }}-results + path: test-results diff --git a/packages/playwright-core/src/server/browser.ts b/packages/playwright-core/src/server/browser.ts index edbc72a480ea9..7e4f0b3b0a016 100644 --- a/packages/playwright-core/src/server/browser.ts +++ b/packages/playwright-core/src/server/browser.ts @@ -199,6 +199,10 @@ export abstract class Browser extends SdkObject { async killForTests(progress: Progress) { await progress.race(this.options.browserProcess.kill()); + // With WebSocket transport the disconnect is not necessarily dispatched before the + // process exit, wait for it explicitly to make the kill appear atomic to the clients. + if (this.isConnected()) + await progress.race(new Promise(x => this.once(Browser.Events.Disconnected, x))); } } diff --git a/packages/playwright-core/src/server/browserType.ts b/packages/playwright-core/src/server/browserType.ts index 5631142825940..3dd0d51969168 100644 --- a/packages/playwright-core/src/server/browserType.ts +++ b/packages/playwright-core/src/server/browserType.ts @@ -273,7 +273,7 @@ export abstract class BrowserType extends SdkObject { const updatedLog = this.doRewriteStartupLog(log); throw new Error(`Failed to launch the browser process.\nBrowser logs:\n${updatedLog}`); } - if (!this.supportsPipeTransport()) { + if (!this.supportsPipeTransport(options)) { transport = await WebSocketTransport.connect(progress, wsEndpoint!); } else { const stdio = launchedProcess.stdio as unknown as [NodeJS.ReadableStream, NodeJS.WritableStream, NodeJS.WritableStream, NodeJS.WritableStream, NodeJS.ReadableStream]; @@ -337,7 +337,7 @@ export abstract class BrowserType extends SdkObject { async prepareUserDataDir(options: types.LaunchOptions, userDataDir: string): Promise { } - supportsPipeTransport(): boolean { + supportsPipeTransport(options: types.LaunchOptions): boolean { return true; } diff --git a/packages/playwright-core/src/server/registry/index.ts b/packages/playwright-core/src/server/registry/index.ts index d8b1836279398..55b59d722fdd5 100644 --- a/packages/playwright-core/src/server/registry/index.ts +++ b/packages/playwright-core/src/server/registry/index.ts @@ -897,12 +897,19 @@ export class Registry { _dependencyGroup: 'webkit', _isHermeticInstallation: true, }); + const wslExecutable = process.platform === 'win32' ? path.join(process.env.SystemRoot || 'C:\\Windows', 'System32', 'wsl.exe') : undefined; this._executables.push({ name: 'webkit-wsl', browserName: 'webkit', directory: webkit.dir, - executablePath: () => webkitExecutable, - executablePathOrDie: (sdkLanguage: string) => executablePathOrDie('webkit', webkitExecutable, webkit.installByDefault, sdkLanguage), + executablePath: () => wslExecutable, + executablePathOrDie: () => { + if (!wslExecutable) + throw new Error(`webkit-wsl is only supported on Windows`); + return wslExecutable; + }, + // WebKit is installed inside the WSL distribution by install_webkit_wsl.ps1. + wslExecutablePath: `/home/pwuser/.cache/ms-playwright/webkit-${webkit.revision}/pw_run.sh`, installType: 'download-on-demand', title: 'Webkit in WSL', _validateHostRequirements: (sdkLanguage: string) => Promise.resolve(), diff --git a/packages/playwright-core/src/server/webkit/webkit.ts b/packages/playwright-core/src/server/webkit/webkit.ts index da412abdc192b..61d0fcf03350d 100644 --- a/packages/playwright-core/src/server/webkit/webkit.ts +++ b/packages/playwright-core/src/server/webkit/webkit.ts @@ -17,11 +17,13 @@ import path from 'path'; +import { ManualPromise } from '@isomorphic/manualPromise'; import { wrapInASCIIBox } from '@utils/ascii'; import { spawnAsync } from '@utils/spawnAsync'; import { kBrowserCloseMessageId } from './wkConnection'; import { Browser } from '../browser'; import { BrowserType, kNoXServerRunningError } from '../browserType'; +import { registry } from '../registry'; import { WKBrowser } from './wkBrowser'; import { connectOverRDP } from './webview/wvBrowser'; @@ -30,8 +32,14 @@ import type { SdkObject } from '../instrumentation'; import type { Progress } from '../progress'; import type { ConnectionTransport } from '../transport'; import type * as types from '../types'; +import type { RecentLogsCollector } from '@utils/debugLogger'; import type * as channels from '@protocol/channels'; +// Must be kept in sync with bin/install_webkit_wsl.ps1 that provisions the distribution. +const kWSLDistribution = 'playwright'; +const kWSLUser = 'pwuser'; +const kWSLHome = '/home/pwuser'; + export class WebKit extends BrowserType { constructor(parent: SdkObject) { super(parent, 'webkit'); @@ -48,10 +56,29 @@ export class WebKit extends BrowserType { override amendEnvironment(env: NodeJS.ProcessEnv, userDataDir: string, isPersistent: boolean, options: types.LaunchOptions): NodeJS.ProcessEnv { return { ...env, - CURL_COOKIE_JAR_PATH: process.platform === 'win32' && isPersistent ? path.join(userDataDir, 'cookiejar.db') : undefined, + // Cookie jar is only used by the Windows port of WebKit. + CURL_COOKIE_JAR_PATH: process.platform === 'win32' && options.channel !== 'webkit-wsl' && isPersistent ? path.join(userDataDir, 'cookiejar.db') : undefined, }; } + override supportsPipeTransport(options: types.LaunchOptions): boolean { + return options.channel !== 'webkit-wsl'; + } + + override async waitForReadyState(options: types.LaunchOptions, browserLogsCollector: RecentLogsCollector): Promise<{ wsEndpoint?: string }> { + if (options.channel !== 'webkit-wsl') + return {}; + const result = new ManualPromise<{ wsEndpoint?: string }>(); + browserLogsCollector.onMessage(message => { + // The browser is listening on the loopback interface inside WSL, the endpoint + // is reachable from the Windows host thanks to WSL localhost forwarding. + const match = message.match(/Playwright listening on (ws:\/\/\S+)/); + if (match) + result.resolve({ wsEndpoint: match[1] }); + }); + return result; + } + override doRewriteStartupLog(logs: string): string { if (logs.includes('Failed to open display') || logs.includes('cannot open display')) logs = '\n' + wrapInASCIIBox(kNoXServerRunningError, 1); @@ -70,14 +97,31 @@ export class WebKit extends BrowserType { throw this._createUserDataDirArgMisuseError('--user-data-dir'); if (args.find(arg => !arg.startsWith('-'))) throw new Error('Arguments can not specify page to be opened'); - const webkitArguments = ['--inspector-pipe']; + const isWSL = options.channel === 'webkit-wsl'; + // wsl.exe does not forward extra file descriptors to the Linux process, so the pipe + // transport cannot work across the WSL boundary. Instead, the browser exposes the + // protocol over a WebSocket server and we connect to it from the Windows host. + const webkitArguments = [isWSL ? '--remote-debugging-port=0' : '--inspector-pipe']; + + if (isWSL) { + if (options.executablePath) + throw new Error('Cannot specify executablePath when using the "webkit-wsl" channel.'); + // The actual command is `wsl.exe -- `. + webkitArguments.unshift( + '-d', kWSLDistribution, + '-u', kWSLUser, + '--cd', kWSLHome, + '--', + registry.findExecutable('webkit-wsl')!.wslExecutablePath!, + ); + } - if (process.platform === 'win32' && options.channel !== 'webkit-wsl') + if (process.platform === 'win32' && !isWSL) webkitArguments.push('--disable-accelerated-compositing'); if (headless) webkitArguments.push('--headless'); if (isPersistent) - webkitArguments.push(`--user-data-dir=${options.channel === 'webkit-wsl' ? await translatePathToWSL(userDataDir) : userDataDir}`); + webkitArguments.push(`--user-data-dir=${isWSL ? await translatePathToWSL(userDataDir) : userDataDir}`); else webkitArguments.push(`--no-startup-window`); const proxy = options.proxyOverride || options.proxy; @@ -86,7 +130,7 @@ export class WebKit extends BrowserType { webkitArguments.push(`--proxy=${proxy.server}`); if (proxy.bypass) webkitArguments.push(`--proxy-bypass-list=${proxy.bypass}`); - } else if (process.platform === 'linux' || (process.platform === 'win32' && options.channel === 'webkit-wsl')) { + } else if (process.platform === 'linux' || isWSL) { webkitArguments.push(`--proxy=${proxy.server}`); if (proxy.bypass) webkitArguments.push(...proxy.bypass.split(',').map(t => `--ignore-host=${t}`)); @@ -106,6 +150,6 @@ export class WebKit extends BrowserType { } export async function translatePathToWSL(path: string): Promise { - const { stdout } = await spawnAsync('wsl.exe', ['-d', 'playwright', '--cd', '/home/pwuser', 'wslpath', path.replace(/\\/g, '\\\\')]); + const { stdout } = await spawnAsync('wsl.exe', ['-d', kWSLDistribution, '--cd', kWSLHome, 'wslpath', path.replace(/\\/g, '\\\\')]); return stdout.toString().trim(); } diff --git a/tests/library/defaultbrowsercontext-2.spec.ts b/tests/library/defaultbrowsercontext-2.spec.ts index d583cb0b0bf5a..ef8fd830a2c09 100644 --- a/tests/library/defaultbrowsercontext-2.spec.ts +++ b/tests/library/defaultbrowsercontext-2.spec.ts @@ -108,8 +108,9 @@ it('should accept relative userDataDir', async ({ createUserDataDir, browserType await context.close(); }); -it('should restore state from userDataDir', async ({ browserType, server, createUserDataDir }) => { +it('should restore state from userDataDir', async ({ browserType, server, createUserDataDir, channel }) => { it.slow(); + it.fixme(channel === 'webkit-wsl', 'Pending local storage writes are lost on close, see https://github.com/microsoft/playwright-browsers/issues/2275'); const userDataDir = await createUserDataDir(); const browserContext = await browserType.launchPersistentContext(userDataDir); diff --git a/tests/library/har-websocket.spec.ts b/tests/library/har-websocket.spec.ts index f9c90544eb4d1..34d25583240a4 100644 --- a/tests/library/har-websocket.spec.ts +++ b/tests/library/har-websocket.spec.ts @@ -130,7 +130,7 @@ it('should include websocket handshake headers and status', async ({ contextFact expect(responseHeaderNames).toContain('sec-websocket-accept'); }); -async function testWebSocketMessages(contextFactory, server, testInfo, content) { +async function testWebSocketMessages(contextFactory, server, testInfo, content, channel?) { const incomingText = ['x'.repeat(125), 'x'.repeat(126), 'x'.repeat(2 ** 16)]; const incomingBinary = [(new Array(125)).fill(0x01), (new Array(126)).fill(0x01), (new Array(2 ** 16)).fill(0x01)]; const outgoingText = ['y'.repeat(125), 'y'.repeat(126), 'y'.repeat(2 ** 16)]; @@ -198,23 +198,27 @@ async function testWebSocketMessages(contextFactory, server, testInfo, content) ...outgoingText.map(m => ({ type: 'send', opcode: 1, data: m })), ...outgoingBinary.map(m => ({ type: 'send', opcode: 2, data: m })), ]); - for (const m of messages) { - expect(m.time).toBeGreaterThanOrEqual(beforeMs - 1); - expect(m.time).toBeLessThanOrEqual(afterMs + 1); + // The WSL VM clock drifts relative to the Windows host clock, so the browser-reported + // message times cannot be compared against the host wall clock. + if (channel !== 'webkit-wsl') { + for (const m of messages) { + expect(m.time).toBeGreaterThanOrEqual(beforeMs - 1); + expect(m.time).toBeLessThanOrEqual(afterMs + 1); + } } expect(messages[0].time).toBeLessThanOrEqual(messages[1].time); expect(wsEntry.time).toBeGreaterThanOrEqual(messages[messages.length - 1].time - messages[0].time); } -it('should embed websocket messages', async ({ contextFactory, server }, testInfo) => { - await testWebSocketMessages(contextFactory, server, testInfo, 'embed'); +it('should embed websocket messages', async ({ contextFactory, server, channel }, testInfo) => { + await testWebSocketMessages(contextFactory, server, testInfo, 'embed', channel); }); -it('should attach websocket messages', async ({ contextFactory, server }, testInfo) => { - await testWebSocketMessages(contextFactory, server, testInfo, 'attach'); +it('should attach websocket messages', async ({ contextFactory, server, channel }, testInfo) => { + await testWebSocketMessages(contextFactory, server, testInfo, 'attach', channel); }); -it('should attach websocket messages for a still open websocket after stopping', async ({ contextFactory, server }, testInfo) => { +it('should attach websocket messages for a still open websocket after stopping', async ({ contextFactory, server, channel }, testInfo) => { const incomingText = 'incoming'; const incomingBinary = [0x01, 0x02, 0x03, 0x04]; const outgoingText = 'outgoing'; @@ -271,9 +275,13 @@ it('should attach websocket messages for a still open websocket after stopping', { type: 'send', opcode: 2, data: outgoingBinary }, { type: 'receive', opcode: 2, data: incomingBinary }, ]); - for (const m of messages) { - expect(m.time).toBeGreaterThanOrEqual(beforeMs - 1); - expect(m.time).toBeLessThanOrEqual(afterMs + 1); + // The WSL VM clock drifts relative to the Windows host clock, so the browser-reported + // message times cannot be compared against the host wall clock. + if (channel !== 'webkit-wsl') { + for (const m of messages) { + expect(m.time).toBeGreaterThanOrEqual(beforeMs - 1); + expect(m.time).toBeLessThanOrEqual(afterMs + 1); + } } expect(messages[0].time).toBeLessThanOrEqual(messages[1].time); expect(wsEntry.time).toBeGreaterThanOrEqual(messages[messages.length - 1].time - messages[0].time); @@ -283,7 +291,8 @@ it('should omit websocket messages', async ({ contextFactory, server }, testInfo await testWebSocketMessages(contextFactory, server, testInfo, 'omit'); }); -it('should record websocket connection failure', async ({ contextFactory, server }, testInfo) => { +it('should record websocket connection failure', async ({ contextFactory, server, channel }, testInfo) => { + it.skip(channel === 'webkit-wsl', 'Connection to an unbound localhost port from WSL is not refused in mirrored networking mode'); // Reserve a port and immediately release it so the WebSocket connect attempt is refused. const portReservation = net.createServer(); await new Promise(resolve => portReservation.listen(0, '127.0.0.1', () => resolve())); diff --git a/tests/library/har.spec.ts b/tests/library/har.spec.ts index f23d69eadd332..83bac48caf5f7 100644 --- a/tests/library/har.spec.ts +++ b/tests/library/har.spec.ts @@ -624,8 +624,8 @@ it('should have connection details', async ({ contextFactory, server, browserNam expect(securityDetails).toEqual({}); }); -it('should have security details', async ({ contextFactory, httpsServer, browserName, platform, mode, isFrozenWebkit }, testInfo) => { - it.fail(browserName === 'webkit' && platform === 'win32'); +it('should have security details', async ({ contextFactory, httpsServer, browserName, platform, mode, channel, isFrozenWebkit }, testInfo) => { + it.fail(browserName === 'webkit' && platform === 'win32' && channel !== 'webkit-wsl'); it.skip(isFrozenWebkit); const { page, getLog } = await pageWithHar(contextFactory, testInfo); diff --git a/tests/library/playwright.config.ts b/tests/library/playwright.config.ts index a61919e08eb37..077fcbf4a16ee 100644 --- a/tests/library/playwright.config.ts +++ b/tests/library/playwright.config.ts @@ -53,17 +53,6 @@ const reporters = () => { return result; }; -let connectOptions: any; -let webServer: Config['webServer']; - -if (channel === 'webkit-wsl') { - connectOptions = { wsEndpoint: 'ws://localhost:3777/' }; - webServer = { - command: 'set PWTEST_UNDER_TEST=1 && set WSLENV=PWTEST_UNDER_TEST && wsl.exe -d playwright -u pwuser -- bash -lc \'/home/pwuser/node/bin/npx playwright run-server --port=3777\'', - url: 'http://localhost:3777', - }; -} - const config: Config = { testDir, outputDir, @@ -80,10 +69,6 @@ const config: Config { it('should fire illegal character error', { annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/38388' }, -}, async ({ page, server, browserName, isWindows }) => { +}, async ({ page, server, browserName, isWindows, channel }) => { server.setRoute('/error.html', (req, res) => { res.end(` @@ -223,7 +223,7 @@ it('should fire illegal character error', { ]); if (browserName === 'chromium') expect(error.message).toContain('Invalid or unexpected token'); - else if (browserName === 'webkit' && isWindows) + else if (browserName === 'webkit' && isWindows && channel !== 'webkit-wsl') expect(error.message).toContain('No identifiers allowed directly after numeric literal'); else if (browserName === 'webkit') expect(error.message).toContain('Invalid character'); diff --git a/tests/page/page-fill.spec.ts b/tests/page/page-fill.spec.ts index 217a7f395aec9..a59f8cd12e55a 100644 --- a/tests/page/page-fill.spec.ts +++ b/tests/page/page-fill.spec.ts @@ -73,10 +73,10 @@ it('should fill color input', async ({ page }) => { expect(await page.$eval('input', input => input.value)).toBe('#aaaaaa'); }); -it('should fill color input case insensitive', async ({ page, browserName, isWindows }) => { +it('should fill color input case insensitive', async ({ page, browserName, isWindows, channel }) => { await page.setContent(''); await page.fill('input', '#AbCd00'); - if (browserName === 'webkit' && isWindows) + if (browserName === 'webkit' && isWindows && channel !== 'webkit-wsl') expect(await page.$eval('input', input => input.value)).toBe('#AbCd00'); else expect(await page.$eval('input', input => input.value)).toBe('#abcd00'); diff --git a/tests/page/workers.spec.ts b/tests/page/workers.spec.ts index 1544565ef3f35..f7f1b27360649 100644 --- a/tests/page/workers.spec.ts +++ b/tests/page/workers.spec.ts @@ -60,8 +60,9 @@ it('should report console logs', async function({ page }) { expect(page.url()).not.toContain('blob'); }); -it('should have timestamp on worker console messages', async function({ page, isAndroid }) { +it('should have timestamp on worker console messages', async function({ page, isAndroid, channel }) { it.skip(isAndroid, 'there is a time difference between android emulator and host machine'); + it.skip(channel === 'webkit-wsl', 'there is a time difference between WSL VM and host machine'); const before = Date.now() - 1; // Account for the rounding of fractional timestamps. const [message] = await Promise.all([ From f024414cab56634986a54463f0f57bfe4f65ed8a Mon Sep 17 00:00:00 2001 From: "Yury Semikhatskii (from Dev Box)" Date: Mon, 15 Jun 2026 15:44:20 -0700 Subject: [PATCH 2/2] chore(webkit): address review comments - ffmpeg is already pulled in as a webkit-wsl dependency, drop it from the workflow - remove redundant comments --- .github/workflows/tests_webkit_wsl.yml | 2 +- packages/playwright-core/src/server/browser.ts | 2 -- packages/playwright-core/src/server/webkit/webkit.ts | 5 ----- 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/.github/workflows/tests_webkit_wsl.yml b/.github/workflows/tests_webkit_wsl.yml index 1a4919165aca7..9eab050b07423 100644 --- a/.github/workflows/tests_webkit_wsl.yml +++ b/.github/workflows/tests_webkit_wsl.yml @@ -48,7 +48,7 @@ jobs: DEBUG: pw:install PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 - run: npm run build - - run: npx playwright install webkit-wsl ffmpeg + - run: npx playwright install webkit-wsl - name: Run tests run: npm run wtest -- ${{ matrix.headed && '--headed' || '' }} env: diff --git a/packages/playwright-core/src/server/browser.ts b/packages/playwright-core/src/server/browser.ts index 7e4f0b3b0a016..0f441fdcb1cec 100644 --- a/packages/playwright-core/src/server/browser.ts +++ b/packages/playwright-core/src/server/browser.ts @@ -199,8 +199,6 @@ export abstract class Browser extends SdkObject { async killForTests(progress: Progress) { await progress.race(this.options.browserProcess.kill()); - // With WebSocket transport the disconnect is not necessarily dispatched before the - // process exit, wait for it explicitly to make the kill appear atomic to the clients. if (this.isConnected()) await progress.race(new Promise(x => this.once(Browser.Events.Disconnected, x))); } diff --git a/packages/playwright-core/src/server/webkit/webkit.ts b/packages/playwright-core/src/server/webkit/webkit.ts index 61d0fcf03350d..1b90404a296dd 100644 --- a/packages/playwright-core/src/server/webkit/webkit.ts +++ b/packages/playwright-core/src/server/webkit/webkit.ts @@ -70,8 +70,6 @@ export class WebKit extends BrowserType { return {}; const result = new ManualPromise<{ wsEndpoint?: string }>(); browserLogsCollector.onMessage(message => { - // The browser is listening on the loopback interface inside WSL, the endpoint - // is reachable from the Windows host thanks to WSL localhost forwarding. const match = message.match(/Playwright listening on (ws:\/\/\S+)/); if (match) result.resolve({ wsEndpoint: match[1] }); @@ -98,9 +96,6 @@ export class WebKit extends BrowserType { if (args.find(arg => !arg.startsWith('-'))) throw new Error('Arguments can not specify page to be opened'); const isWSL = options.channel === 'webkit-wsl'; - // wsl.exe does not forward extra file descriptors to the Linux process, so the pipe - // transport cannot work across the WSL boundary. Instead, the browser exposes the - // protocol over a WebSocket server and we connect to it from the Windows host. const webkitArguments = [isWSL ? '--remote-debugging-port=0' : '--inspector-pipe']; if (isWSL) {