Repository navigation
fix: skip frames that cannot run scripts instead of hanging - #1478
Draft
scottmries wants to merge 1 commit into
Draft
scottmries wants to merge 1 commit into
scottmries wants to merge 1 commit into
Conversation
A same-origin iframe sandboxed without allow-scripts accepts injected code, but its timers never fire. axe.runPartial needs timers, so analyze() in Playwright and Puppeteer waited forever on that frame. WebDriverJS and WebdriverIO waited for the script timeout, 30 seconds by default. Before running axe in a child frame, each package now checks that a setTimeout callback fires within 1 second. If it does not, the frame is skipped and reported as incomplete by the frame-tested rule. Closes: #1469
There was a problem hiding this comment.
🔵 Needs a closer look
A moderate Playwright timeout-scope issue remains unresolved.
0 open findings
What changed in this PR
Prevents analysis from hanging on sandboxed iframes that cannot run timers by skipping them and reporting incomplete frame coverage.
Changes:
- Adds timer-readiness checks across all browser integrations.
- Preserves and restores WebDriver script timeouts.
- Adds regression tests for skipped frames and timeout handling.
| File | Description |
|---|---|
packages/webdriverjs/test/axe-webdriverjs.spec.ts |
Tests incomplete-frame reporting and timeout restoration. |
packages/webdriverjs/src/index.ts |
Applies timer checks to child frames. |
packages/webdriverjs/src/browser.ts |
Adds script-timeout timer probing. |
packages/webdriverio/test/axe-webdriverio.spec.ts |
Tests incomplete-frame reporting and timeout restoration. |
packages/webdriverio/src/utils.ts |
Handles timer probing for classic and BiDi modes. |
packages/webdriverio/src/types.ts |
Adds script-timeout typing. |
packages/webdriverio/src/index.ts |
Applies timer checks to child frames. |
packages/puppeteer/test/axe-puppeteer.spec.ts |
Tests sandboxed-frame handling. |
packages/puppeteer/src/browser.ts |
Adds timer-aware frame readiness checks. |
packages/playwright/test/axe-playwright.spec.ts |
Tests incomplete-frame reporting. |
packages/playwright/src/index.ts |
Integrates child-frame timer validation. |
packages/playwright/src/browser.ts |
Provides the timer probe. |
🧠 Review effort: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Details
A same-origin iframe sandboxed without
allow-scriptsaccepts injected code, but its timers never fire.axe.runPartialneeds timers, soanalyze()never finished in that frame:Before running axe in a child frame, each package now checks that a
setTimeoutcallback fires within 1 second. If it does not, the frame is skipped and theframe-testedrule reports it as incomplete. Frames that can run scripts pay one extra round trip.WebdriverIO needs two limits. Classic WebDriver blocks later commands until a stuck script hits the script timeout, so the check lowers that timeout to 1 second and then restores the user's value. WebDriver BiDi ignores the script timeout, so the check also gives up from Node after 1 second.
QA notes
<iframe sandbox="allow-same-origin" src="/legal.html"></iframe>. The iframe page should contain an<img>withoutalt.analyze()with each package in its default mode.analyze()to finish in a few seconds, and expectincompleteto includeframe-testedfor the iframe.allow-scriptsto thesandboxattribute and run again. Expectimage-altinviolationswith a target inside the iframe.Closes: #1469