Analyzing iframes

This page is not available in the language you requested. You have been redirected to the English version of the page.
Link to this page copied to clipboard

How the Axe DevTools for Web APIs analyze content inside iframes, and how to scope or restrict frame analysis.

Not for use with personal data

Pages often put substantial content inside <iframe> elements: payment forms, media players, embedded maps, chat and help widgets, and third-party components. The Axe DevTools for Web APIs analyze the content of those frames as part of an ordinary page analysis, in every supported language, so framed content isn't a gap in your coverage and doesn't need a separate set of tests.

There is nothing to turn on. axe-core is loaded into the frames of the page, each frame is analyzed along with the top-level document, and the results are combined into a single report for the page.

How Frame Results Are Reported

Results from frames arrive in the same violations, passes, incomplete, and inapplicable arrays as the rest of the page. What identifies them is the target array on each result node: it holds one selector per level of frame nesting, followed by a selector for the element itself.

  • A target with one entry is an element in the top-level document.
  • A target with two entries is an element inside one frame: the first selector finds the frame in the parent document, and the second finds the element inside that frame's document.
  • Each additional entry represents another level of frame nesting.

For the full result structure, see the Browser JavaScript API reference.

Scoping Analysis to or Inside a Frame

Every API that accepts include and exclude selectors also accepts a path through nested frames. The rule is the same in every language: all selectors but the last match successive <iframe> elements, and the last one matches the element to analyze inside the innermost frame. Order matters, because the frame has to come before the element inside it.

Language How to target an element inside a frame Reference
Node.js and JavaScript Pass an array of selectors to include or exclude Browser JavaScript API reference
C# Including/Excluding with several selectors, or a FromFrames selector C# API reference
Java including/excluding with a List<String>, or an IFrameSelector with Hamcrest Selenium testing, Hamcrest API reference
Python including()/excluding() with several selectors Python API reference
Ruby A within clause with an iframe: and selector: hash RSpec
note

Because a list of selectors is always read as a path through frames, it can't be used to select several unrelated elements. To analyze more than one region of a page, call the include or exclude method once per region.

Restricting Frame Analysis

Frames make a page more dynamic, and on pages where frames are added or removed while an analysis is running, injecting axe-core into every frame can fail. The Java API provides a failsafe that limits an analysis to the top-level document: call disableIframeTesting() before running, and axe-core is not injected into any frame. See Selenium testing.

important

The axe-core iframes run option does not turn frame analysis off in these APIs. Because each library injects axe-core into frames through the browser driver rather than letting axe-core walk the frames itself, an analysis reports frame results whether or not the option is set. To limit the scope of an analysis, exclude the frame instead, using the exclude method for your language.

Cross-Origin and Sandboxed Frames

A frame can be analyzed only when axe-core can run inside it and report its results back.

Cross-origin frames are analyzed. Because these APIs drive a real browser session and inject axe-core into each frame through the driver, a frame served from a different origin is analyzed like any other frame, and its results appear with the rest of the page.

Sandboxed frames depend on the library. A frame with a sandbox attribute that omits allow-scripts blocks the script execution axe-core needs. Some libraries work around this and analyze the frame anyway; others report the frame as untested. The Python API exposes without_iframe_sandboxes(), which removes the sandbox attribute so axe-core can run inside those frames. See the Python API reference.

note

Use the axe-core frame-tested rule to tell "no issues in this frame" apart from "this frame was never analyzed." A frame axe-core could not reach is reported as incomplete, and one it did reach passes the rule. It is a best-practice rule, so it appears only when your ruleset includes best-practice rules; a ruleset limited to WCAG rules omits it, and an unanalyzed frame then produces no signal at all.