-
Notifications
You must be signed in to change notification settings - Fork 54
Description
Description
Percy's DOM serialization crashes with TypeError: Invalid URL when the page contains iframes with non-standard or unparseable URLs (e.g., third-party widgets like Intercom in transient states). This silently drops the snapshot — no retry, no error surfaced to the test runner.
The bug exists in two places:
- @percy/playwright — Node.js side
In https://github.com/percy/percy-playwright/blob/master/index.js, cross-origin iframe filtering does:
.filter(frame => frame.url() !== 'about:blank' && new URL(frame.url()).origin !== pageUrl.origin)
new URL(frame.url()) throws TypeError: Invalid URL if the frame URL is non-standard (e.g., a widget iframe in a loading/transient state). The fix is wrapping this in try/catch:
.filter(frame => {
const frameUrl = frame.url();
if (!frameUrl || frameUrl === 'about:blank') return false;
try {
return new URL(frameUrl).origin !== pageUrl.origin;
} catch {
return false;
}
})
- @percy/dom — browser side
The setBaseURI function calls new URL(dom.baseURI) on each iframe's contentDocument without try/catch. When an iframe has an unparseable baseURI, this throws and crashes the entire snapshot serialization.
Impact
In our CI (15+ parallel Playwright shards), we were seeing ~18 TypeError: Invalid URL errors per build, causing 5–9 snapshots to silently fail. The third-party widget responsible was Intercom, which creates iframes that can be in transient URL states during page loads.
Current workaround
- Yarn patch on @percy/playwright wrapping the new URL() call in try/catch
- Runtime helper that detaches iframes with unparseable baseURI before calling percySnapshot(), then re-inserts them after
Environment
- @percy/cli: 1.31.8
- @percy/playwright: 1.0.10
- @percy/dom: 1.31.8
- Playwright: 1.57.x
- Node: 22.17.x