Analyzing iframes
How Axe Watcher analyzes content inside iframes during your test runs.
Pages often put substantial content inside <iframe> elements: payment forms, media players, embedded maps, chat and help widgets, and third-party components. Axe Watcher analyzes the content of same-origin frames along with the rest of the page, so framed content isn't a gap in your coverage and doesn't need its own tests.
Frame analysis needs no setup, and Watcher's frame handling doesn't depend on the language or test framework you use: axe-core is loaded into the frames of the page, and the results from the frames are analyzed and reported with the page state that contains them.
How Frame Results Are Reported
Issues found inside a frame are attributed to the page state of the page that embeds the frame, not to a separate page state of their own. In Axe Developer Hub they appear with the rest of the issues for that page state.
What identifies an issue as coming from a frame is its element selector, which holds one entry per level of frame nesting followed by a selector for the element itself. A selector with two entries points at an element inside one frame: the first entry finds the frame in the parent document, and the second finds the element inside that frame's document. This means a reported element may not exist in the page's own HTML. Read the selector from the outside in to find where the element actually lives.
Scope and Limitations
- Same-origin frames are analyzed. A violation inside a frame served from the same origin as the page is reported with that page's results, identified by a selector that names the frame and then the element inside it.
- Cross-origin frames are not analyzed unless you allow them. Watcher runs inside the browser alongside your application, so the browser's same-origin policy applies. By default, content in a frame served from a different origin is not analyzed and no violations are reported for it. In Watcher 4.6.0 and later you can opt in per origin with the
allowedOriginsoption, described below. - Frames are analyzed with the page, not separately. Frame content is covered by each analysis of the page that embeds it, so a frame whose content changes is picked up by the analysis of the resulting page state.
- Frames follow page-level configuration. Options that control what Watcher analyzes, such as controlling your scans and excluding URLs, apply to the page as a whole, including its frames. There is no separate setting for frames.
Analyzing Cross-Origin Frames
Watcher 4.6.0 added the allowedOrigins option, which opts in to analyzing the content of frames served from origins you name. Set allowedOrigins in AxeConfiguration (JavaScript/TypeScript integrations) or call setAllowedOrigins() on AxeWatcherOptions (Java integrations). Your own origin is always allowed, so list only the embedded origins you want covered:
axe: {
allowedOrigins: [ 'https://pay.example.com' ]
}Points worth knowing before you enable it:
- Wildcards aren't supported. Every origin must be named explicitly, and an entry Watcher can't use is reported as an error rather than being ignored.
- Every origin you list can drive, and can read the markup of, the page that embeds it. List only origins you trust with the content of the page under test.
- Each origin you allow adds that frame's content to every analysis, which makes analysis slower. The default
analyzeandflushtimeouts are raised when the option is set. - Automatic analysis can't detect changes made inside a frame, so an allowed frame is analyzed as of the last change to the top-level page. Call
analyze()after interacting with content inside a frame.
See the allowedOrigins reference for the full entry format and validation rules.
Enable best practices if you depend on frame coverage. The axe-core frame-tested rule is what distinguishes "no issues in this frame" from "this frame was never analyzed": a frame Watcher could not reach is reported as needing review, and one it did reach passes the rule. Because it is a best-practice rule, a ruleset limited to WCAG rules omits it entirely, and a cross-origin frame you have not allowed then produces no signal of any kind.
