Intelligent Guided Tests

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
Not for use with personal data

The analyze tool can run Deque's Automated Intelligent Guided Tests (IGTs) against the page it scans, in the same call, right after the Axe scan. Pass the optional igtTools array naming which IGTs to run:

Value IGT What it checks
"keyboard" Keyboard Tab order, elements unreachable by keyboard, focus traps, missing or weak focus indicators, and elements that submit forms on focus
"interactive-elements" Interactive Elements Whether buttons, links, and custom controls have the right accessible name, role, and state. See Interactive Elements IGT.
"modal" Modal Dialog Whether focus stays inside a modal, the modal's dialog semantics, and (when given a trigger) whether it can be closed and where focus goes afterward. See Modal Dialog IGT.
{
  "url": "http://localhost:3000",
  "igtTools": ["keyboard"]
}

Prompt your AI agent in natural language — the agent translates your intent into the tool call:

Scan http://localhost:3000 for accessibility issues and run the keyboard IGT on it

Each requested IGT runs in sequence after the Axe scan, in the order you list them, against the same page, in the same browser, at the same viewport width. Anything that prepares the page runs once and applies to the scan and every IGT: before actions, cookie injection, and the viewport parameters.

{
  "url": "http://localhost:3000",
  "igtTools": ["keyboard"],
  "before": [
    {
      "action": "fill",
      "selector": "#username",
      "value": "<resolved-from-.env.local>"
    },
    { "action": "click", "selector": "button[type=submit]" },
    { "action": "waitFor", "selector": "#main-content" }
  ]
}

Response shape

Setting igtTools changes the shape of data. Without it, data is the Axe issues array. With it, data has two keys at the same level, axe and igt, with one igt entry per requested IGT:

{
  "pageUrl": "http://localhost:3000",
  "data": {
    "axe": [],
    "igt": {
      "keyboard": {
        "status": "complete",
        "issues": [],
        "igtElements": [],
        "terminatedReason": "keyboard-trap"
      },
      "modal": {
        "status": "complete",
        "issues": [],
        "igtElements": []
      }
    }
  }
}
  • status"complete" or "error". Check it before reading anything else: issues and igtElements are present only on "complete", and error only on "error". Phased selection adds three more statuses for the Interactive Elements IGT.
  • issues — the accessibility problems the IGT found. The issue count is the length of this array.
  • igtElementsevery element the IGT processed, not just the ones with problems. Entries with analysisFailed: true could not be analyzed by AI and should be reviewed manually. Each entry is trimmed to identifying fields only: vnodeId, selector, tagName, role, accessibleName, states, and analysisFailed, each present only when the element carries it.
  • terminatedReason — present only when the run ended before every step finished, so results may be partial. It is not an error. See Termination reasons.
note

A call without igtTools is unchanged. data remains the Axe issues array exactly as before, so existing prompts, agent instructions, and integrations keep working without modification.

Termination reasons

terminatedReason IGT Meaning
insufficient-credits Any The account ran out of AI credits during the run.
subscription-missing Any The account doesn't have the Axe DevTools for Web subscription the IGT requires.
keyboard-trap Keyboard The test hit a focus trap it could not escape.
dismissibility-unavailable Modal There was no trigger (a modalSelector-only or before-only run), so the test couldn't check whether the modal can be closed. Expected when those modes assess the modal successfully, not a failure.
focus-restoration-unavailable Modal There was no trigger for focus to return to, so the test couldn't check where focus goes after the modal closes. Expected for no-trigger modes, not a failure.
modal-not-detected Modal No modal was found to assess.
modal-dismiss-failed Modal The modal could not be closed during the assessment.
trigger-not-resolved Modal modalTriggerSelector matched no element on the page, so no modal was opened.
modal-selector-not-resolved Modal modalSelector matched no element on the page.
modal-selector-not-visible Modal modalSelector matched an element that isn't visible. If the modal opens from an interaction, open it with before.
modal-fallback-not-resolved Modal The fallback modalSelector (passed with a trigger) matched no element on the page.
modal-fallback-not-visible Modal The fallback modalSelector (passed with a trigger) matched an element that isn't visible.

The Interactive Elements IGT has no termination reasons of its own. A page with no interactive elements returns a "complete" result with empty arrays.

Failures are isolated

An IGT that fails does not fail the call and never affects the Axe results or the other IGTs. The failure is reported as that IGT's own status: "error" with a message. The Axe results and every other IGT's results come back normally. This includes when your organization's machine learning setting is disabled, in which case each IGT's entry explains that machine learning is required.

Credit usage

IGTs are AI-powered and are part of the AI Credit Management System. Each run consumes AI credits from your organization's monthly allocation; the Axe scan itself does not. Request IGTs deliberately rather than adding them to every scan. For the Interactive Elements IGT, scoping or choosing elements reduces the number of elements analyzed, and so the credits used.

tip

If your custom agent instructions tell the agent to call the standalone igt tool, update them to use analyze with igtTools instead — one call covers both the scan and the IGT, and the standalone tool is deprecated.

Interactive Elements IGT

The Interactive Elements IGT finds the buttons, links, and custom controls on the page and uses AI to check each one's accessible name, role, and state. By default it analyzes every interactive element it finds in a single call:

{
  "url": "http://localhost:3000",
  "igtTools": ["interactive-elements"]
}
Analyze http://localhost:3000 and run the interactive elements guided test

Each element analyzed consumes AI credits, so on a large page — a data grid, a long navigation menu, a product listing — the default run can use a lot. Two options limit what gets analyzed.

Scoping with includeSelectors

Pass includeSelectors, an array of CSS selectors, to analyze only the elements that match. Elements outside the selectors are not analyzed:

{
  "url": "http://localhost:3000",
  "igtTools": ["interactive-elements"],
  "includeSelectors": ["#main", "nav.primary"]
}
Analyze http://localhost:3000 and run the interactive elements guided test,
but only on the elements inside #main and nav.primary

includeSelectors is different from analyze's selector. selector limits which part of the page the Axe scan covers, while includeSelectors limits which elements the Interactive Elements IGT analyzes. You can use either one, or both. includeSelectors requires "interactive-elements" in igtTools.

Choosing which elements to test

When you don't know in advance which elements matter, use phased selection. It splits the test into two tool calls, with a pause in between so you can choose what gets analyzed:

  1. First call — find elements. The agent calls analyze with interactive: true. The Axe scan runs as usual, and the IGT finds the page's interactive elements but runs no AI analysis on them. The run pauses and returns the list of elements it found, plus a sessionID.
  2. You choose. The agent shows you the list — each element's role, accessible name, and state, grouped by component or role where possible — and you tell it which ones to test.
  3. Second call — analyze. The agent calls analyze again with the sessionID and the selectedIDs you chose. The paused run continues in the same browser session, without loading the page or finding elements again, and returns a normal "complete" result for only the selected elements.

A prompt that asks for it:

Analyze http://localhost:3000 and run the interactive elements guided test.
Show me the interactive elements it finds first and let me choose which
ones to test.

The first call:

{
  "url": "http://localhost:3000",
  "igtTools": ["interactive-elements"],
  "interactive": true
}

returns the Axe results and the candidates:

{
  "pageUrl": "http://localhost:3000",
  "data": {
    "axe": [],
    "igt": {
      "interactive-elements": {
        "status": "needs_selection",
        "sessionID": "3f9c…",
        "candidates": [
          { "vnodeId": 12, "role": "button", "name": "Add to cart" },
          { "vnodeId": 31, "role": "link", "name": "Checkout" }
        ],
        "componentGroups": { "intelligent": [], "role": [] }
      }
    }
  }
}

The second call names the chosen candidates by vnodeId:

{
  "url": "http://localhost:3000",
  "igtTools": ["interactive-elements"],
  "sessionID": "3f9c…",
  "selectedIDs": [12]
}

Keep the following in mind when using phased selection:

  • It runs the Interactive Elements IGT only. igtTools must be exactly ["interactive-elements"] on both calls. To run the Keyboard or Modal IGTs as well, run them in a separate call.
  • The second call omits data.axe. The Axe results came back on the first call. On the second call, every setup parameter (viewportWidth, viewportHeight, cookies, before, selector, advancedRules, screenshot, chromePath) is ignored, because the paused browser session is reused as-is. url is still required.
  • includeSelectors still applies. Pass it on the first call to limit which elements appear in the list.
  • selectedIDs must come from the list. If any ID wasn't in the candidates, the call returns status: "invalid_selection" with the unknown IDs in unknownIDs. The run stays paused, so the agent can retry with valid IDs.
  • Paused runs expire. A run that isn't continued within 3 minutes is closed and returns status: "session_expired". At most 3 paused runs can be open at once. Both limits are configurable with SELECTION_SESSION_TTL_MS and MAX_SELECTION_SESSIONS. After an expiry, start over with a new interactive: true call.
tip

Phased selection is the most credit-efficient way to test a large page. The first call runs no AI analysis on interactive elements, and the second call analyzes only the elements you chose.

The Modal Dialog IGT checks a single modal dialog on the page. It checks that keyboard focus stays inside the modal while it is open and that the modal has the correct dialog semantics (aria-modal and the role of the modal container). When the test has the element that opens the modal, it also checks that the modal can be closed and that focus returns to a sensible place afterward.

The test needs to know which modal to check. There are three ways to tell it:

Targeting mode How What's assessed
Trigger (recommended) modalTriggerSelector — the element that opens the modal Focus containment, dialog semantics, closing, and focus return
Modal element modalSelector — the modal element itself Focus containment and dialog semantics only
before steps only No selector — your before actions open the modal Focus containment and dialog semantics only

Use modalTriggerSelector whenever the modal has a trigger — it's the only mode that checks everything. The test clicks the trigger itself:

{
  "url": "http://localhost:3000",
  "igtTools": ["modal"],
  "modalTriggerSelector": "#open-dialog"
}
Analyze http://localhost:3000 and run the modal guided test on the dialog
opened by #open-dialog

Use modalSelector when there's no trigger to click, such as a modal that's open when the page loads. If the modal only appears after some interaction, use before to open it first:

{
  "url": "http://localhost:3000",
  "igtTools": ["modal"],
  "modalSelector": "#newsletter-dialog"
}

With neither selector, the test checks whatever modal is open once the before steps finish. Use this for modals that no single element opens, such as one that appears after a sequence of keystrokes or a session timeout:

{
  "url": "http://localhost:3000",
  "igtTools": ["modal"],
  "before": [
    { "action": "click", "selector": "#settings" },
    { "action": "click", "selector": "#delete-account" }
  ]
}

Both selectors accept a CSS string for an element in the top frame, or an array of selectors to reach an element inside an iframe (for example, ["iframe#app", "#open-dialog"]), the same format as selector.

important

Without a trigger, an empty issues list doesn't mean the modal can be closed. When a modalSelector-only or before-only run finds and assesses the modal, it ends with terminatedReason: "dismissibility-unavailable". This is expected and means closing and focus return were not assessed — not that they passed. If the modal can't be found, the run ends with a different reason instead, such as modal-not-detected or modal-selector-not-resolved; see Termination reasons.

Providing a fallback modal selector

If you know both the trigger and the modal element, pass both. The test still starts from the trigger and still checks everything. The modalSelector is used only if the test can't identify the modal after clicking the trigger — typically because the modal uses non-standard markup:

{
  "url": "http://localhost:3000",
  "igtTools": ["modal"],
  "modalTriggerSelector": "#open-dialog",
  "modalSelector": "#custom-dialog"
}

The result doesn't say whether the fallback was used. A run that needed it checked an element the test couldn't recognize as a modal, so treat an empty issues list from a run with both selectors as weaker evidence than one from a trigger-only run.

Don't open the modal yourself

When you pass modalTriggerSelector, the test clicks the trigger to open the modal. If the modal is already open, that click usually closes it again. So:

  • Don't click the trigger in before. A before click on the same selector as modalTriggerSelector is rejected with an error. Use before to reach the page state the trigger lives in, such as logging in or going to a particular view.
  • Don't pass a trigger for a modal that's already open, either on page load or from a before step. Use modalSelector on its own instead.

modalTriggerSelector and modalSelector each require "modal" in igtTools.

Running Everything in One Call

Each IGT has its own options, so one analyze call can run the Axe scan, Advanced Rules, and every IGT on the same page. The page is loaded and prepared once, and each result comes back under its own key.

Analyze http://localhost:3000 for accessibility issues with thorough
advanced rules. Also run the keyboard, interactive elements, and modal
guided tests (test the modal triggered by button#open-dialog).

The agent resolves the prompt and calls the analyze tool with a payload similar to:

{
  "url": "http://localhost:3000",
  "advancedRules": "thorough",
  "igtTools": ["keyboard", "interactive-elements", "modal"],
  "modalTriggerSelector": "button#open-dialog"
}

and receives the Axe results (including Advanced Rules findings) under data.axe and one entry per IGT under data.igt:

{
  "pageUrl": "http://localhost:3000",
  "advancedRules": { "value": "thorough", "source": "tool_arg" },
  "data": {
    "axe": [],
    "igt": {
      "keyboard": { "status": "complete", "issues": [], "igtElements": [] },
      "interactive-elements": {
        "status": "complete",
        "issues": [],
        "igtElements": []
      },
      "modal": { "status": "complete", "issues": [], "igtElements": [] }
    }
  }
}

The IGTs run one after another, in the order listed in igtTools, and each reports separately — a keyboard trap or a modal that can't be found doesn't stop the others. This works with every other analyze option too: before steps and cookies for a page behind a login, viewportWidth for a mobile breakpoint, selector to scope the Axe scan, and screenshot.

note

Phased selection can't be combined with other IGTs. To limit the Interactive Elements IGT in a multi-IGT call, use includeSelectors.

The igt Tool

caution

The igt tool is deprecated. Use the analyze tool's igtTools parameter instead — it runs the same Intelligent Guided Tests against the same page in a single call, alongside the Axe scan.

igt remains fully functional and returns the same results as before, so nothing breaks today. It will be removed in a future release. If your custom agent instructions name the igt tool, update them to call analyze with igtTools.

The igt tool runs Deque's Automated Intelligent Guided Tests against a web page as a standalone call. Everything it does, analyze now does in the same call as the accessibility scan — see the rest of this page for usage and credit consumption, which are the same for both.

The per-test result object is also the same for both — status, issues, igtElements, and an optional terminatedReason, as described in Response shape. Only the envelope differs: igt returns its results directly under data, keyed by test name (data.keyboard), whereas analyze nests them under data.igt alongside data.axe.