-
Notifications
You must be signed in to change notification settings - Fork 61
feat(sdk-utils): export canonical iframe-capture helpers (single source of truth) #2319
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c89f46d
d18b70f
c451d5e
2ced997
4a490b0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -35,6 +35,57 @@ function clampIframeDepth(raw) { | |
| return Math.min(Math.floor(n), HARD_MAX_IFRAME_DEPTH); | ||
| } | ||
|
|
||
| // Canonical list of iframe `src` URL prefixes that out-of-process SDK frame | ||
| // walks (Capybara, Nightwatch, Playwright, Puppeteer, Selenium, ...) must NOT | ||
| // switch into / serialize: browser-internal pages, non-HTTP schemes, and | ||
| // pseudo-protocols that either can't be navigated cross-process or are unsafe | ||
| // to recurse into. SINGLE SOURCE OF TRUTH — every SDK previously hand-copied | ||
| // this list (it drifted into 4 divergent versions), so they now consume it | ||
| // from here instead. `startsWith`, case-insensitive. | ||
| const UNSUPPORTED_IFRAME_SRCS = [ | ||
| 'about:', 'chrome:', 'chrome-extension:', 'devtools:', 'edge:', | ||
| 'opera:', 'view-source:', 'data:', 'javascript:', 'blob:', | ||
| 'vbscript:', 'file:', 'ws:', 'wss:', 'ftp:' | ||
| ]; | ||
|
|
||
| // True when an iframe `src` should be skipped by an SDK frame walk. A missing | ||
| // / empty src is treated as unsupported (nothing to navigate to). | ||
| function isUnsupportedIframeSrc(src) { | ||
| if (!src) return true; | ||
| const s = String(src).toLowerCase(); | ||
| return UNSUPPORTED_IFRAME_SRCS.some(prefix => s.startsWith(prefix)); | ||
| } | ||
|
|
||
| // Normalize a raw ignore-selectors value (array | string | unset) into a | ||
| // clean string[]. PercyDOM does `selectors?.length && selectors.some(...)`, | ||
| // which throws when handed a bare string (has .length, no .some), so SDKs | ||
| // must normalize before forwarding — this is the shared primitive. | ||
| function normalizeIgnoreSelectors(value) { | ||
| if (!value) return []; | ||
| if (Array.isArray(value)) return value.filter(s => typeof s === 'string' && s.length); | ||
| if (typeof value === 'string') return [value]; | ||
| return []; | ||
| } | ||
|
|
||
| // Resolve the effective maxIframeDepth for a snapshot: per-snapshot option | ||
| // wins over the global `percy.config.snapshot.maxIframeDepth`, then the value | ||
| // is clamped to [1, HARD_MAX_IFRAME_DEPTH] (invalid/<1 -> default). | ||
| function resolveMaxFrameDepth(options = {}) { | ||
| let raw = options.maxIframeDepth; | ||
| if (raw == null) raw = percy?.config?.snapshot?.maxIframeDepth; | ||
| return clampIframeDepth(raw); | ||
| } | ||
|
|
||
| // Resolve the effective ignoreIframeSelectors for a snapshot: per-snapshot | ||
| // option wins; when absent, fall back to the global | ||
| // `percy.config.snapshot.ignoreIframeSelectors`. Always returns a string[]. | ||
| function resolveIgnoreSelectors(options = {}) { | ||
| const perSnapshot = normalizeIgnoreSelectors( | ||
| options.ignoreIframeSelectors ?? options.ignoreSelectors); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Medium]
Suggestion: branch on Reviewer: stack:code-reviewer |
||
| if (perSnapshot.length) return perSnapshot; | ||
| return normalizeIgnoreSelectors(percy?.config?.snapshot?.ignoreIframeSelectors); | ||
| } | ||
|
|
||
| export { | ||
| logger, | ||
| percy, | ||
|
|
@@ -52,6 +103,11 @@ export { | |
| DEFAULT_MAX_IFRAME_DEPTH, | ||
| HARD_MAX_IFRAME_DEPTH, | ||
| clampIframeDepth, | ||
| UNSUPPORTED_IFRAME_SRCS, | ||
| isUnsupportedIframeSrc, | ||
| normalizeIgnoreSelectors, | ||
| resolveMaxFrameDepth, | ||
| resolveIgnoreSelectors, | ||
| waitForReadyScript, | ||
| getReadinessConfig, | ||
| isReadinessDisabled, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Low]
s.lengthreads as a truthy check rather than non-empty-string intentReviewer: stack:code-reviewer