# cypress-axe checka11y failed on modal iframe content - how to fix it

## TL;DR

Scope the audit to the frame that holds the modal: cy.frame or cy.iframe into the modal's iframe, inject axe there, and run checkA11y against that context. The default checkA11y audits the top frame, which does not include the modal's iframe DOM. One line of why: axe runs per document, and an iframe is a separate document, so the top-frame audit literally cannot see the modal content.

## The error, verbatim

```text
AssertionError: checkA11y found no violations but modal content was not audited
    hint: modal renders inside a cross-frame iframe
    at Context.eval (cypress/e2e/modal-a11y.cy.js:24:5)

```

## Fix it step by step

### Step 1: Reproduce the blind spot

```bash
npx cypress run --spec cypress/e2e/modal-a11y.cy.js | tail -8
```

Expected: The spec passes or audits only the top frame while the modal iframe goes unchecked.

### Step 2: Enter the iframe

```bash
rg -n 'iframe|frame' cypress/e2e/modal-a11y.cy.js | head -10
```

Expected: Shows whether the spec ever enters the modal iframe; usually it does not.

### Step 3: Inject and check inside the frame

```bash
npx cypress run --spec cypress/e2e/modal-a11y.cy.js | rg -i 'violation|passing|failing' | head -10
```

Expected: After scoping into the iframe, checkA11y reports the modal's real violations.

### Step 4: Re-run to green

```bash
npx cypress run --spec cypress/e2e/modal-a11y.cy.js | tail -4
```

Expected: Spec audits the modal content and passes once its violations are fixed.

### Step 5: Re-run twice to rule out flakes

```bash
npx pa11y https://example.com/ | tail -2
```

Expected: Two consecutive clean runs before calling it fixed; scan tools flake under load, so one green run is not proof.

## When to use this skill

- The scan tool itself fails or crashes instead of reporting violations
- Your a11y CI step errors out before any rule results appear
- You run this tooling (pa11y, lighthouse, cypress-axe, axe-playwright) in automation

## When NOT to use this skill

- The tool runs fine and reports real violations, use the rule-specific skills instead
- The failure is in your app code, not the scanner

## Compatibility

cypress-axe 1.x with cypress-iframe or cy.frame support, Cypress 12/13. Cross-origin iframes cannot be entered, same-origin only. Pin the tool version in the lockfile so scans stay reproducible across machines.

## Variant phrasings

### cypress-axe iframe not audited

Same blind spot, same scoping fix.

### checkA11y modal iframe

Practitioner phrasing for modals rendered in iframes.

### same failure locally and in CI

Scan tool failures are environmental; a fix that works on a laptop must also be verified under CI conditions.

## Why it happens

Axe analyzes one document at a time, and cypress-axe defaults to the top frame. Modals rendered inside iframes (payment forms, embedded widgets) live in a separate document that the top-frame audit never touches, so violations hide there indefinitely. Entering the frame with cy.iframe, injecting axe into it, and running checkA11y in that context is the fix. Cross-origin iframes cannot be scripted into at all, which is a hard browser limit, not a cypress-axe bug. Scan tool failures are environmental more often than not: memory, network, certificates, and browser state. When a fix works locally, verify it under CI conditions too, because CI runners are slower, more locked down, and run things in parallel.

## Edge cases

- Cross-origin iframes are unauditable from the parent page, audit them as standalone pages instead.
- Wait for the iframe to load and the modal to open before injecting axe, timing matters.
- Same-origin iframes work fine, the only blocker is cross-origin script access.
- Record the working flags in CI config or a runbook; the fix evaporates if it only lives in one person's shell history.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_OlCGFNVYyKTrbIr6TZscQg
