Skip to content

fix(trace): keep client paths out of remote launch options - #42436

Open
Devin Rousso (dcrousso) wants to merge 1 commit into
microsoft:mainfrom
dcrousso:fix-42394
Open

fix(trace): keep client paths out of remote launch options#42436
Devin Rousso (dcrousso) wants to merge 1 commit into
microsoft:mainfrom
dcrousso:fix-42394

Conversation

@dcrousso

Copy link
Copy Markdown
Contributor

remote browser servers can receive Playwright Test worker paths and try to write trace files on the client filesystem

remove artifactsDir and tracesDir from remote launch options

fixes #42394

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@aczekajski

Copy link
Copy Markdown

A bit of a nitpick, but it seems like the options coming from the x-playwright-launch-options header are filtered on the server side to begin with here:

launchOptions = filterLaunchOptions(launchOptions, isExtension || !!this._options.unsafe);

and the filtering function looking like this:
function filterLaunchOptions(options: LaunchOptionsWithTimeout, allowUnsafe: boolean): LaunchOptionsWithTimeout {
return {
channel: options.channel,
args: allowUnsafe ? options.args : undefined,
ignoreAllDefaultArgs: allowUnsafe ? options.ignoreAllDefaultArgs : undefined,
ignoreDefaultArgs: allowUnsafe ? options.ignoreDefaultArgs : undefined,
timeout: options.timeout,
headless: options.headless,
proxy: options.proxy,
chromiumSandbox: allowUnsafe ? options.chromiumSandbox : undefined,
firefoxUserPrefs: (isUnderTest() || allowUnsafe) ? options.firefoxUserPrefs : undefined,
slowMo: options.slowMo,
executablePath: (isUnderTest() || allowUnsafe) ? options.executablePath : undefined,
downloadsPath: allowUnsafe ? options.downloadsPath : undefined,
artifactsDir: (isUnderTest() || allowUnsafe) ? options.artifactsDir : undefined,
};
}

so the tracesDir was being filtered out anyway and artifactsDir was in fact allowed only when isUnsafe was being passed. And it is true that in my case where I had an error, I was launching the server with --usafe flag. My guess is that passing artifactsDir as a launch option is something used by the extension so it cannot be completely filtered out in there. Maybe the that filtering fn should make a distinction between "extension mode" and "--unsafe"? 🤔

@aczekajski

Copy link
Copy Markdown

Btw backporting just this small change to 1.62.1 also makes the apiRequestContext._wrapApiCall: End of central directory record signature not found. Either not a zip file, or file is truncated error gone for me ^^

Comment thread packages/playwright/src/index.ts Outdated
headers: {
// HTTP headers are ASCII only (not UTF-8).
'x-playwright-launch-options': jsonStringifyForceASCII(_browserOptions),
'x-playwright-launch-options': jsonStringifyForceASCII({

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filters like this should be done on the server side. In fact, we already do something along these lines in packages/playwright-core/src/remote/playwrightServer.ts (see filterLaunchOptions) - why doesn't that work?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my earlier comment, it's because of the --unsafe flag. I need that flag but now it causes the artifactsDir to be passed from client to server, making server try to access path that might not exist there. But since it's probably used by the VSCode extension, it probably cannot be completely filtered out on server side. I think removing it on the client side is not wrong. What might be wrong is that the --unsafe flag is treated identically as "extension mode".

remote servers started with `--unsafe` can use Playwright Test worker paths that only exist on the client

allow client `artifactsDir` only in extension mode
@github-actions

Copy link
Copy Markdown
Contributor

Test results for "tests 1"

5 flaky ⚠️ [installation tests] › connect-to-selenium.spec.ts:20 › connect to selenium `@package-installations-ubuntu-latest`
⚠️ [installation tests] › playwright-electron-should-work.spec.ts:31 › electron should work `@package-installations-ubuntu-latest`
⚠️ [chromium-library] › library/video.spec.ts:736 › screencast › should work with video+trace `@chromium-ubuntu-22.04-arm-node20`
⚠️ [chromium-library] › library/popup.spec.ts:260 › should not throw when click closes popup `@chromium-ubuntu-22.04-node24`
⚠️ [firefox-page] › page/page-event-request.spec.ts:181 › should return response body when Cross-Origin-Opener-Policy is set `@firefox-ubuntu-22.04-node20`

51272 passed, 1240 skipped


Merge workflow run.

@github-actions

Copy link
Copy Markdown
Contributor

Test results for "MCP"

1 failed
❌ [firefox] › mcp/cli-save-as.spec.ts:26 › screenshot @mcp-windows-latest-firefox

8258 passed, 1361 skipped


Merge workflow run.

@github-actions

Copy link
Copy Markdown
Contributor

Hi, I'm the Playwright bot and I took a look at the CI failures here.

🟢 The PR is clear — the one failure is a pre-existing Firefox flake

The single red test, mcp/cli-save-as.spec.ts:26 › screenshot <ref> on @mcp-windows-latest-firefox, has nothing to do with this change. This PR only strips artifactsDir/tracesDir from remote launch options in playwrightServer.ts (plus a browsertype-connect test); it never reaches the MCP screenshot/save-as flow. The test is a known bimodal flake: on Firefox/Windows it failed 5 of 704 runs (~0.7%) and passed 699, on SHAs unrelated to this PR. The tests 1 report has no failures at all — only flakes rescued on retry.

Details

Overall: no failure is attributable to this PR. One real red, confirmed pre-existing flake; the rest is retry-rescued noise.

Pre-existing flake / infra

Triaged by the Playwright bot - agent run

@dgozman

Copy link
Copy Markdown
Collaborator

Devin, what are we trying to fix here? I don't think passing --unsafe and then expecting things to be "safe" is what we are after. Perhaps there is a usecase I don't understand, but I wasn't able to figure that out from the linked issue.

@aczekajski

Copy link
Copy Markdown

Dmitry Gozman (@dgozman) Sorry this is not clear from the original issue, I discovered it's happening because of --unsafe only after this PR was created. The case is that for some specific tests I need to pass the ignoreDefaultArgs option (namely to re-enable scrollbars for some screenshots). However, that option is filtered out by the filterLaunchOptions on the server side. However, the ignoreDefaultArgs is guarded by the "unsafe" check - so it is possible to pass it to the server but to be able to do it, --unsafe flag has to be used. However, coincidentally the artifactsDir option is also guarded by that same "unsafe" check. At the same time, the test runner that connects to remote server via PW_TEST_CONNECT_WS_ENDPOINT, always passes it's own local absolute path as artifactsDir (and the user has no control over it) which from the server's perspective, is never correct, unless the server runs on exactly same logical machine (which is not really the use case of WS endpoint). So the current WS setup works kinda "by accident" from my perspective, because in standard cases, without the "unsafe" flag, the incorrect artifactsDir passed to the server is filtered out. But in case of remote server, it should not be passed to begin with because the remote server most likely does not share filesystem with the test runner.

@dcrousso

Copy link
Copy Markdown
Contributor Author

filterLaunchOptions did not entirely work here because --unsafe and extension mode were both collapsed into allowUnsafe, so artifactsDir was allowed in both cases

artifactsDir should be allowed in extension mode because it's used by local tooling (i.e. the client and server share a filesystem)

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

Labels

None yet

Projects

None yet

3 participants