microsoft / microsoft/playwright

[Bug]: Firefox never reports domcontentloaded for a document produced by an XSL transform

Open
#42,417 1 comment 0 reactions 1 assignee View on GitHub

@dcrousso is already working on this.

Since Aug 26, 2026.

v1.64
Dominant language
TypeScript
Stars
96.3k
Forks
6.5k
Avg merge
1d 6h
Merged PRs (30d)
180

Description

### Version

1.62.1

### Steps to reproduce

Serve an XML document that references an XSL stylesheet, then navigate to it with `waitUntil: 'domcontentloaded'`.

```js
import http from 'node:http';
import { chromium, firefox } from 'playwright';

const xsl = `

transformed


`;

const xml = `

hello`;

const server = http.createServer((req, res) => {
const [type, body] = req.url.startsWith('/style.xsl') ? ['text/xsl', xsl] : ['application/xml', xml];
res.writeHead(200, { 'content-type': type });
res.end(body);
});
await new Promise((resolve) => server.listen(0, resolve));
const url = `http://127.0.0.1:${server.address().port}/doc.xml`;

for (const [name, browserType] of Object.entries({ firefox, chromium })) {
const browser = await browserType.launch();
const page = await browser.newPage();
console.log(`\n${name} ${browser.version()}`);

for (const waitUntil of ['domcontentloaded', 'load']) {
const started = Date.now();
try {
await page.goto(url, { waitUntil, timeout: 5000 });
console.log(` goto '${waitUntil}' -> resolved in ${Date.now() - started}ms`);
} catch (error) {
console.log(` goto '${waitUntil}' -> ${error.message.split('\n')[0]}`);
}
}

console.log(` document.readyState: ${await page.evaluate(() => document.readyState)}`);
try {
await page.waitForLoadState('domcontentloaded', { timeout: 5000 });
console.log(' waitForLoadState(domcontentloaded) on the loaded page -> resolved');
} catch (error) {
console.log(` waitForLoadState(domcontentloaded) on the loaded page -> ${error.message.split('\n')[0]}`);
}

await browser.close();
}
server.close();
```

### Expected behavior

goto with waitUntil: 'domcontentloaded' resolves, as it does in Chromium and as waitUntil: 'load' does in Firefox. load cannot fire before DOMContentLoaded, so once the document is loaded, waiting for the earlier event should never block.

### Actual behavior

In Firefox the event is never reported for the transform output, so both goto and waitForLoadState hit their timeout while the document is fully loaded (readyState: 'complete', transformed DOM in place). Retrying and using a fresh browser context change nothing. Chromium is fine.

Any XSL-styled XML page reproduces it, not just the local server above, e.g. `https://yoast.com/sitemap_index.xml`.

### Additional context

_No response_

### Environment

```shell
System:
OS: macOS 26.2
CPU: (14) arm64 Apple M4 Pro
Memory: 237.63 MB / 24.00 GB
Binaries:
Node: 24.15.0 - /Users/.../.nvm/versions/node/v24.15.0/bin/node
npm: 11.12.1 - /Users/.../.nvm/versions/node/v24.15.0/bin/npm
pnpm: 11.15.1 - /opt/homebrew/bin/pnpm
IDEs:
Cursor: 3.15.6 - /usr/local/bin/cursor
Claude Code: 2.1.169 - /Users/.../.local/bin/claude
Languages:
Bash: 3.2.57 - /bin/bash
npmPackages:
@playwright/browser-chromium: 1.62.1 => 1.62.1
@playwright/browser-firefox: 1.62.1 => 1.62.1
playwright: 1.62.1 => 1.62.1
```

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.