Skip to content

fix(esm): dont bail for preflight requests#39237

Merged
Skn0tt merged 2 commits intomicrosoft:mainfrom
Skn0tt:dont-bail-for-preflight
Feb 26, 2026
Merged

fix(esm): dont bail for preflight requests#39237
Skn0tt merged 2 commits intomicrosoft:mainfrom
Skn0tt:dont-bail-for-preflight

Conversation

@Skn0tt
Copy link
Member

@Skn0tt Skn0tt commented Feb 12, 2026

Closes #39172.

Interestingly, the test without the fix immediately leads to the Error: duplicate test title "another test", first declared in example.spec.ts.esm.preflight:13 bug, so we have a good repro even without tsx. It seems to affect any loader.

@Skn0tt Skn0tt requested a review from dgozman February 12, 2026 09:07
@Skn0tt Skn0tt self-assigned this Feb 12, 2026
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

}

const code = fs.readFileSync(filename, 'utf-8');
const transformed = transformHook(code, filename, moduleUrl);
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd skip this for preflights that we want to bail on, e.g. from node_modules. Since we are not supposed to transform them, we don't need to prepopulate source mapes.

I'd make a custom defaultLoad function that would return void 0 for preflights or call the actual defaultLoad for non-preflights.

Copy link
Member Author

Choose a reason for hiding this comment

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

I didn't like the custom defaultLoad function, but I found a different way of writing it that skips the fs ops and transform for preflights, and looks pretty readable.

@github-actions

This comment has been minimized.

@Skn0tt Skn0tt force-pushed the dont-bail-for-preflight branch from 7fafc93 to be4648f Compare February 12, 2026 14:56
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

moduleUrl = moduleUrl.replace(esmPreflightExtension, '');
const filename = url.fileURLToPath(moduleUrl);
const format = kSupportedFormats.get(context.format) || (fileIsModule(filename) ? 'module' : 'commonjs');
if (isPreflight)
Copy link
Contributor

Choose a reason for hiding this comment

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

This always skips transformHook which is the sole purpose of having a preflight.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

// Node < 18.6: defaultLoad takes 3 arguments.
// Node >= 18.6: nextLoad from the chain takes 2 arguments.
async function load(originalModuleUrl: string, context: { format?: string }, defaultLoad: Function) {
const isPreflight = originalModuleUrl.endsWith(esmPreflightExtension);
Copy link
Member

Choose a reason for hiding this comment

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

Let me offer an alternative as I think this change is somewhat missing the point. The like 65 in the old code is offender, it needs to go.

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

That patch let's through .esm.preflight loads to the next loader, which will fail because it can't find the file. It doesn't pass my reproduction test, and doesn't fix the issue.

Copy link
Member

Choose a reason for hiding this comment

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

As discussed offline, I don't think we have a choice - 'bad' loader can be before us up in the chain.

Copy link
Member Author

@Skn0tt Skn0tt Feb 24, 2026

Choose a reason for hiding this comment

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

i updated the PR to be based on your patch, and i've added the catch for the bad loader and two more tests, take a look.

@Skn0tt Skn0tt force-pushed the dont-bail-for-preflight branch from fb25b36 to f5e4535 Compare February 24, 2026 09:37
@github-actions

This comment has been minimized.

// Bail for node_modules.
if (!shouldTransform(filename))
if (!shouldTransform(filename)) {
if (isPreflight)
Copy link
Member

Choose a reason for hiding this comment

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

This violates the 'assume any order' consideration.

@Skn0tt
Copy link
Member Author

Skn0tt commented Feb 26, 2026

I verified that it still fixes #39172 - the catch makes it work.

@github-actions
Copy link
Contributor

Test results for "tests 1"

4 failed
❌ [default-trace] › debug-tests.spec.ts:431 › should debug global setup when toggle is enabled @vscode-extension
❌ [playwright-test] › playwright.trace.spec.ts:345 › should retain traces for interrupted tests @macos-latest-node20
❌ [playwright-test] › playwright.unhandled.spec.ts:67 › should produce unhandledRejection when context.route raises @macos-latest-node20
❌ [playwright-test] › ui-mode-test-network-tab.spec.ts:371 › should not preserve selection across test runs @macos-latest-node20

4 flaky ⚠️ [chromium-library] › library/popup.spec.ts:258 › should not throw when click closes popup `@ubuntu-22.04-chromium-tip-of-tree`
⚠️ [chromium-library] › library/inspector/cli-codegen-3.spec.ts:226 › cli codegen › should generate frame locators (4) `@chromium-ubuntu-22.04-node20`
⚠️ [firefox-library] › library/inspector/cli-codegen-1.spec.ts:1082 › cli codegen › should not throw csp directive violation errors `@firefox-ubuntu-22.04-node20`
⚠️ [playwright-test] › ui-mode-test-run.spec.ts:779 › should not leak websocket connections `@windows-latest-node20`

38591 passed, 843 skipped


Merge workflow run.

@github-actions
Copy link
Contributor

Test results for "MCP"

5 failed
❌ [chrome] › mcp/autowait.spec.ts:19 › racy navigation destroys context @mcp-ubuntu-latest
❌ [chrome] › mcp/http.spec.ts:199 › http transport browser lifecycle (persistent) @mcp-macos-15
❌ [firefox] › mcp/sse.spec.ts:171 › sse transport browser lifecycle (persistent) @mcp-macos-15
❌ [webkit] › mcp/http.spec.ts:199 › http transport browser lifecycle (persistent) @mcp-macos-15
❌ [webkit] › mcp/sse.spec.ts:171 › sse transport browser lifecycle (persistent) @mcp-macos-15

5115 passed, 171 skipped


Merge workflow run.

@Skn0tt Skn0tt merged commit 23b2c15 into microsoft:main Feb 26, 2026
30 of 35 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Playwright 1.58.0 collects *.esm.preflight files as tests, causing duplicate test title errors

3 participants