Skip to content

Commit 80fadac

Browse files
aryanku-devclaude
andcommitted
fix: align iframe depth + unsupported-scheme list with canonical sdk-utils
Bring the inlined iframe helpers into parity with the canonical @percy/sdk-utils single source of truth (percy/cli #2319): - DEFAULT_MAX_FRAME_DEPTH 5 -> 3 (MAX_FRAME_DEPTH_CAP already 10). - isUnsupportedIframeSrc now matches the canonical 15-prefix UNSUPPORTED_IFRAME_SRCS (adds chrome/chrome-extension/devtools/edge/opera/ view-source/blob/file/ws/wss/ftp and the about: prefix) and is case-insensitive, instead of the narrow case-sensitive about:blank/ javascript:/data:/vbscript: check. Updated the clampFrameDepth + resolveMaxFrameDepth default assertions to 3. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent c7ffcb1 commit 80fadac

3 files changed

Lines changed: 26 additions & 11 deletions

File tree

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,11 @@ node_modules/
1212
.vscode
1313
.settings
1414
.DS_Store
15+
16+
# bstack-ai-harness:begin (managed — do not edit between markers)
17+
bstack-ai-harness.yml
18+
.harness-docs.json
19+
.harness-manifest.json
20+
CLAUDE.md
21+
.claude/
22+
# bstack-ai-harness:end

src/main/java/io/percy/selenium/Percy.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -730,16 +730,23 @@ static class PercyContextLostException extends RuntimeException {
730730

731731
// Default maximum nesting depth for cross-origin iframe capture. Mirrors the
732732
// canonical Percy SDK behaviour — depth 1 is a top-level iframe.
733-
private static final int DEFAULT_MAX_FRAME_DEPTH = 5;
733+
private static final int DEFAULT_MAX_FRAME_DEPTH = 3;
734734
private static final int MIN_FRAME_DEPTH = 1;
735735
private static final int MAX_FRAME_DEPTH_CAP = 10;
736736

737+
// Mirrors the canonical @percy/sdk-utils UNSUPPORTED_IFRAME_SRCS list
738+
// (percy/cli #2319): a null/empty src is unsupported, and the check is a
739+
// case-insensitive startsWith over the 15 canonical scheme prefixes.
737740
private boolean isUnsupportedIframeSrc(String src) {
738-
return src == null || src.isEmpty() ||
739-
src.equals("about:blank") ||
740-
src.startsWith("javascript:") ||
741-
src.startsWith("data:") ||
742-
src.startsWith("vbscript:");
741+
if (src == null || src.isEmpty()) return true;
742+
String s = src.toLowerCase();
743+
return s.startsWith("about:") || s.startsWith("chrome:") ||
744+
s.startsWith("chrome-extension:") || s.startsWith("devtools:") ||
745+
s.startsWith("edge:") || s.startsWith("opera:") ||
746+
s.startsWith("view-source:") || s.startsWith("data:") ||
747+
s.startsWith("javascript:") || s.startsWith("blob:") ||
748+
s.startsWith("vbscript:") || s.startsWith("file:") ||
749+
s.startsWith("ws:") || s.startsWith("wss:") || s.startsWith("ftp:");
743750
}
744751

745752
private static String getOrigin(String url) {

src/test/java/io/percy/selenium/IframeFeatureTest.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ public class IframeFeatureTest {
4040
@Test
4141
public void clampFrameDepthBoundsValuesAndDefaults() throws Exception {
4242
int defDepth = (int) invokeStaticPrivate("clampFrameDepth", new Class[]{int.class}, 0);
43-
assertEquals(5, defDepth, "Non-positive depth clamps to default");
43+
assertEquals(3, defDepth, "Non-positive depth clamps to default");
4444

4545
int negDepth = (int) invokeStaticPrivate("clampFrameDepth", new Class[]{int.class}, -3);
46-
assertEquals(5, negDepth, "Negative depth clamps to default");
46+
assertEquals(3, negDepth, "Negative depth clamps to default");
4747

4848
int hugeDepth = (int) invokeStaticPrivate("clampFrameDepth", new Class[]{int.class}, 9999);
4949
assertEquals(10, hugeDepth, "Huge depth clamps to cap (10)");
@@ -86,7 +86,7 @@ public void resolveMaxFrameDepthPrefersOptionThenCliConfigThenDefault() throws E
8686

8787
setField(percy, "cliConfig", new JSONObject().put("snapshot", new JSONObject()));
8888
int def = (int) invokePrivate(percy, "resolveMaxFrameDepth", new Class[]{Map.class}, new HashMap<>());
89-
assertEquals(5, def);
89+
assertEquals(3, def);
9090
}
9191

9292
@Test
@@ -453,11 +453,11 @@ public void collectClosedShadowPairsWalksTreeAndSkipsContentDocuments() throws E
453453
@Test
454454
public void clampFrameDepthZeroReturnsDocumentedDefault() throws Exception {
455455
// Semantic regression test: maxIframeDepth=0 must fall back to the
456-
// documented default (5), matching @percy/sdk-utils behaviour. Anyone
456+
// documented default (3), matching @percy/sdk-utils behaviour. Anyone
457457
// who later changes this to "0 disables CORS capture" would break
458458
// cross-SDK alignment — this test guards against the silent flip.
459459
int fromZero = (int) invokeStaticPrivate("clampFrameDepth", new Class[]{int.class}, 0);
460-
assertEquals(5, fromZero, "maxIframeDepth=0 must use the canonical default (5), not disable nested capture");
460+
assertEquals(3, fromZero, "maxIframeDepth=0 must use the canonical default (3), not disable nested capture");
461461
}
462462

463463
@Test

0 commit comments

Comments
 (0)