Skip to content

TypeError: Invalid URL when iframes have non-standard URLs (crashes DOM serialization) #2120

@TBakes

Description

@TBakes

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:

  1. @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;
}
})

  1. @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

  1. Yarn patch on @percy/playwright wrapping the new URL() call in try/catch
  2. 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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions