PRACTICAL GUIDE / Playwright testInfo errorContext aria snapshot
Playwright testInfo errorContext ARIA Snapshot Debugging
Learn Playwright testInfo errorContext aria snapshot with working code, failure cases, debugging steps, and CI evidence for reliable QA automation.
In this guide12 sections
- Locate errorContext on the Error, Not testInfo
- Understand When the Context Is Created
- Build a Failure that Has Semantic Meaning
- Collect Errors Available When afterEach Runs
- Choose the Right Diagnostic Artifact
- Respect Worker, Hook, and Reporter Boundaries
- Test the Boundary and Failure Matrix
- Preserve Multi-Error Identity in the Triage Record
- Debug from the Recorded Receiver Outward
- Govern Error Context in CI
- Frequently Asked Questions
- Where is errorContext available in Playwright Test?
- What does TestInfoError.errorContext contain?
- Does errorContext replace traces and screenshots?
- Why is errorContext undefined for some failures?
- How should CI publish errorContext safely?
- Rehearse Failure Triage in QABattle
What you will learn
- Locate errorContext on the Error, Not testInfo
- Understand When the Context Is Created
- Build a Failure that Has Semantic Meaning
- Collect Errors Available When afterEach Runs
Playwright testInfo errorContext aria snapshot diagnostics expose semantic context recorded with a failed assertion. In afterEach, inspect testInfo.errors, keep entries whose optional errorContext is present, and attach them without replacing the original message or stack. The first failure boundary is assertion recording: a caught or non-locator error may have no ARIA context at all.
This field makes a timeout more actionable when the receiver's role, accessible name, state, and nearby structure explain what Playwright actually saw. It is not a universal page dump and not a signal that the application failed for an accessibility reason. Treat it as one evidence channel with explicit lifecycle, privacy, and reporter boundaries.
Locate errorContext on the Error, Not testInfo
testInfo exposes error and errors. testInfo.error is the first recorded TestInfoError; testInfo.errors contains all recorded errors for the current test attempt. The optional errorContext property belongs to each of those error objects. Code that reads testInfo.errorContext is using a property that does not exist in the 1.61.1 public type.
A hard assertion normally stops the test body and records its error before afterEach runs. A soft assertion records an error while allowing the body to continue, so several entries can exist. Hooks and teardown can add failures too. Iterate the array when the diagnostic system must preserve all contexts rather than assuming the first error tells the whole story.
The official TestInfoError reference defines errorContext as additional context, such as the ARIA snapshot of a matcher receiver at the time of an expect(...) failure. The words "such as" and the optional TypeScript property are important: callers must handle absence without treating it as another failure.
Use the Playwright ARIA snapshot accessibility guide to interpret semantic YAML. The snapshot describes accessible output, not raw DOM or visual layout. A missing button can mean wrong scope, a changed role, hidden state, or a page that never reached the expected step.
Understand When the Context Is Created
Playwright locator matchers receive diagnostic data from the locator assertion path. In the installed 1.61.1 runner, matcher ARIA snapshot data is serialized onto TestInfoError.errorContext. That makes failed assertions such as text, state, or accessibility checks candidates for semantic context around the locator receiver.
Ordinary exceptions have different evidence. A thrown Error may provide a message, stack, and cause but no ARIA context. A primitive thrown value uses the error value field. A generic expect(total).toBe(42) assertion has no locator receiver to snapshot. Setup can fail before any page exists. The hook must preserve each case without inventing a placeholder tree.
Timing also matters. The recorded context belongs to the failure moment. By the time afterEach runs, the page may have advanced, an animation may have finished, or cleanup may already be changing state. A fresh page.ariaSnapshot() in the hook can supplement the record, but it is not a replacement for the receiver snapshot captured with the assertion.
Do not catch a failing matcher merely to read its internal error object and then let the test pass. A caught error may never enter testInfo.errors, and the release result no longer represents the failed requirement. If a failure is expected, use an explicit negative test or assertion contract. If it is diagnostic, allow Playwright to record it and process the public TestInfoError in the hook.
The Playwright release notes list testInfoError.errorContext as a 1.60 addition. Pinning 1.61.1 in the evidence job keeps the type and serialization behavior known while the team adopts it.
Build a Failure that Has Semantic Meaning
Use a fixture where a failed state assertion can be explained by the receiver's accessible structure. This example models a disclosure that should expose a named region after activation.
Fixture: account security disclosure
<main aria-label="Account security">
<button aria-expanded="false" aria-controls="recovery-options">
Recovery options
</button>
<section id="recovery-options" aria-label="Recovery options" hidden>
<h2>Recovery options</h2>
<button>Add recovery email</button>
</section>
</main>Suppose a regression leaves aria-expanded="false" and the section hidden after click. A failed toHaveAttribute('aria-expanded', 'true') or missing region assertion has useful semantic neighbors: the button's name and state, the main landmark, and perhaps the absent region. That evidence can direct triage toward the disclosure transition rather than a generic timeout increase.
The fixture should use deterministic data and no personal recovery address. Error context can include visible and accessible text. Synthetic values reduce the need to mutate a failure artifact after capture, which helps preserve its diagnostic integrity.
Collect Errors Available When afterEach Runs
The collection sequence should be predictable:
- Let product assertions fail normally so Playwright records the original error.
- Enter
afterEachand read the errors available for the current attempt when that hook begins. - Preserve the array index, message category, and whether context exists.
- Attach each nonempty
errorContextas its own YAML artifact with a unique name. - Never replace the original error message, stack, or status with attachment success.
- Apply retention and access policy based on the test's data classification.
- Let reporters publish the attachment while CI classifies product and evidence-pipeline failures separately.
Playwright 1.61.1 example: attach all ARIA error contexts
import { test, expect } from '@playwright/test';
test.afterEach(async ({}, testInfo) => {
for (const [index, error] of testInfo.errors.entries()) {
if (!error.errorContext) continue;
await testInfo.attach(`assertion-aria-context-${index + 1}`, {
body: error.errorContext,
contentType: 'text/yaml',
});
}
});
test('recovery options expand', async ({ page }) => {
await page.goto('/settings/security');
const toggle = page.getByRole('button', { name: 'Recovery options' });
await toggle.click();
await expect(toggle).toHaveAttribute('aria-expanded', 'true');
await expect(page.getByRole('region', { name: 'Recovery options' }))
.toBeVisible();
});The hook does not fail when no context exists, because absence is valid for several failure types. It also does not combine multiple snapshots without boundaries. Separate attachment names preserve the order visible at that moment and let a reporter link the right semantic context to each failed assertion.
This hook cannot promise every final attempt error. A later afterEach hook or fixture teardown can append another error after this code has already read the array. Playwright 1.61.1 builds its runner-owned error-context.md attachment in the final test-artifact phase after teardown, so use that attachment or a reporter consuming the finalized result when complete attempt coverage is required. Keep the custom hook only when individual per-error YAML attachments available at hook time serve a declared workflow.
If the repository wraps this behavior, keep the API small and typed. The custom matcher guide is relevant when failures originate in team matchers: return Playwright-compatible results and preserve locator diagnostics instead of throwing a generic replacement error.
Choose the Right Diagnostic Artifact
No single artifact explains every failure. Use this decision table to avoid attaching everything by default.
| Diagnostic | Best question | Strength | Limitation |
|---|---|---|---|
| Error message and stack | What assertion failed and where? | Primary failure identity and source location | May not show the receiver's current semantics |
TestInfoError.errorContext | What accessible structure did the failed matcher receive? | Compact roles, names, states, and nearby text | Optional, string-based, and not a pixel or timeline record |
| Trace | Which actions, waits, requests, and page states led here? | Chronology and interactive debugging | Larger artifact with broader data exposure |
| Screenshot | What did the rendered page look like? | Clipping, overlap, color, and visual-state evidence | Does not explain accessible names or hidden semantics |
Explicit scoped ariaSnapshot() | What semantic region should be retained by policy? | Caller controls root, mode, depth, and capture moment | May occur after the original failure state |
| Application logs | What backend or client event explains the state? | Domain and system context | Correlation can be wrong without a test-owned identifier |
Start with the error and its recorded context. Add a trace when chronology is uncertain, a screenshot when pixels matter, and a scoped snapshot when the receiver context is too narrow for the owned component. The visual snapshot CI debugging guide covers environment and rendering evidence that ARIA context cannot provide.
The official ARIA snapshot guide helps decode the YAML form. Do not parse the string into a long-term analytics schema without versioning that parser. The public contract exposes diagnostic text, not a stable ErrorContextNode[] data model.
Respect Worker, Hook, and Reporter Boundaries
TestInfoError is available through testInfo inside the worker. The 1.61.1 reporter-facing TestError type does not declare errorContext. A custom reporter should not reach into an undeclared field and hope serialization keeps it. Attach the context during afterEach; reporters can then publish ordinary TestResult.attachments through their supported interface.
This boundary also determines where sanitization can happen. A reporter sees the attachment after the worker created it. If policy requires redaction before publication, perform that transformation inside the worker or, better, use synthetic data and a scoped test so the captured semantic text is already safe. Do not write an unsanitized attachment and promise to clean it after upload.
Hooks can fail. An attachment write error should be reported as an evidence-pipeline or hook failure, but it must not erase the assertion that triggered collection. Keep the hook simple, avoid network calls, and let the standard output directory manage files. External upload belongs after the run, where retries and credentials cannot alter the product test's browser state.
Retries create a new test attempt with its own testInfo, errors, and attachments. Keep the retry index in artifact paths or reporter metadata. Never merge a first-attempt context with a passing retry and label the combined record simply "passed." A flaky result needs both attempt histories to explain instability.
The AI-generated Playwright test evidence checklist is useful when a model consumes failure artifacts. Require it to cite the error index and attachment rather than summarizing a mixed bundle with no chain of custody.
Test the Boundary and Failure Matrix
The matrix below defines what collection should do for each failure class.
| Boundary | Failure case | Expected errorContext behavior | Governance response |
|---|---|---|---|
| Hard locator assertion | toBeVisible times out on a named region | Context may contain the failed receiver's ARIA snapshot | Attach it and preserve original failure |
| Multiple soft assertions | Name and expanded-state checks both fail | More than one recorded error may carry context | Iterate all errors; never keep only the last |
| Generic assertion | Numeric total is wrong | Context can be undefined because no locator received the matcher | Use message, stack, and domain evidence |
| Setup error | Navigation fixture throws before page creation | No ARIA receiver exists | Classify setup failure without an empty YAML attachment |
| Caught matcher | Test catches the assertion and continues | Failure may not be recorded in testInfo.errors | Remove catch or model the expected failure explicitly |
| Hook failure | Context attachment cannot be written | Original assertion and hook error both matter | Preserve both and route evidence failure separately |
| Retry | First attempt fails, second passes | Each attempt owns different error context | Retain attempt identity and report flaky status |
| Reporter | Custom reporter expects undeclared TestError.errorContext | Field is unavailable in the reporter type | Publish worker-created attachments instead |
| Sensitive fixture | Accessible text contains an account identifier | Context is diagnostically useful but restricted | Use synthetic data, access controls, and short retention |
| Page drift | Hook takes a new snapshot after UI changes | Fresh capture differs from failure-time context | Label capture time; do not overwrite recorded context |
Write collector tests for hard, soft, generic, caught, hook, retry, and sensitive cases. Those tests belong to the evidence helper, not every application suite. They prove that missing context remains a valid state and that multi-error failures do not lose information.
The Playwright locator guide helps improve the assertions that produce these diagnostics. A narrow, user-facing receiver gives more useful context than a body locator wrapped around an unrelated text search.
Preserve Multi-Error Identity in the Triage Record
Playwright 1.61 changed testInfo.errors so each sub-error of an AggregateError appears as a separate entry. Soft assertions can also produce several recorded errors before the test ends. A collector designed around one message and one snapshot can therefore discard valid failure evidence even when its loop appears to work for ordinary hard assertions.
Treat array position as attempt-local identity. Include the retry index and error index in every attachment name or accompanying manifest. Do not use only the matcher name, because two toBeVisible failures can occur in the same flow. The test ID, project, retry, and index together let a reviewer connect the artifact to the original result without copying the full private message into a storage key.
Keep a small metadata manifest beside the YAML attachments. It can record whether context was present, the error category, attachment name, and a sanitized first-line summary. It should not duplicate the full ARIA string in JSON. One canonical payload reduces accidental exposure and prevents a reporter from showing two slightly different sanitized versions as though they came from separate failures.
TestInfoError can also carry a cause. If the team wraps domain failures with JavaScript error causes, decide whether the collector traverses that chain. A recursive collector should preserve parent-child order, cap depth, and avoid attaching the same context twice. Most suites can begin with top-level entries and add cause traversal only after a real wrapped-error case demonstrates the need.
Do not aggregate contexts into one unlabeled prompt. Two soft failures may describe different components at different moments. An AI system given both without boundaries can attribute the first tree to the second message. If model-assisted triage is approved, send one indexed error package at a time or use explicit delimiters and metadata that the response must cite.
Context availability is not a quality score. A generic assertion with no ARIA text is not less serious than a locator assertion with a rich tree. Likewise, a detailed accessibility snapshot does not show that an issue violates a standard. Use the accessibility testing tools guide when the release question concerns audit rules, and keep errorContext focused on explaining the failed receiver.
Visual evidence needs equally clear pairing. If a screenshot is attached for error three, give it the same attempt and error identity or state that it represents the test's terminal page instead. The visual accessibility scenario guide illustrates why a semantic failure and a pixel observation may concern different user barriers even when both originate in one component.
Finally, define partial collection behavior. If context one attaches and context two fails to write, report the second attachment failure without deleting the first. Preserve the product errors and mark evidence completeness as failed. An all-or-nothing uploader can turn a minor storage incident into total diagnostic loss, while a silent best-effort hook can make CI claim that required evidence exists when it does not.
Debug from the Recorded Receiver Outward
Read the primary message first: expected value, received value, timeout, and locator. Then inspect errorContext for the receiver's role, name, state, and children. Ask whether the test found the wrong element, reached the wrong application state, or observed a genuine semantic regression. This order prevents a visually plausible screenshot from overriding a precise matcher failure.
If the expected node is absent, use a broader scoped locator and capture a diagnostic ARIA snapshot. If the node is present with the wrong name, trace labels and accessible-name sources. If state is stale, inspect the action and product milestone. If the context is undefined, return to the error class instead of repeatedly capturing the page.
Do not automatically update an ARIA expectation based on error context. The recorded tree is actual evidence, not approved behavior. Review role, name, state, hierarchy, and copy with the component owner. The ARIA snapshot article explains partial matching and semantic update review in more detail.
For focus or activation failures, combine context with keyboard navigation testing. A receiver can have the correct role and name while focus remains elsewhere or keyboard activation fails. Error context narrows the semantic state; it cannot replay the interaction.
If an AI assistant proposes a fix, require it to distinguish product, test, data, and infrastructure causes. A recommendation that replaces a role locator with a brittle CSS selector merely because the expected node is absent should fail review. Context is most useful when it raises a specific hypothesis that another artifact or assertion can verify.
Govern Error Context in CI
Define collection and retention before enabling broad publication. Record Playwright version, browser project, retry index, test ID, error index, and attachment name. Keep passing-run collection off unless a sampled baseline has a stated purpose. Failure context can contain names, values, links, and user-authored text even when screenshots are disabled.
Separate three statuses in reports. Product status comes from the assertions. Evidence status records whether required diagnostics were captured and published. Analysis status records whether a human or model classified the failure. A missing attachment must not convert a product failure into an unknown pass, and a confident model summary must not reverse the deterministic result.
Do not retry solely because context is missing. Retry policy should address a known transient product or infrastructure boundary. If the collector is unreliable, test and repair it as an owned component. Repeated product execution to obtain a prettier artifact can mutate data and hide the original state.
Use access controls and short default retention. Promote only incident artifacts that an owner is actively investigating, and document why longer retention is needed. If an external model receives context, send a scoped, policy-approved derivative and retain the provider request identifier without copying private raw text into logs.
Review framework upgrades with contract fixtures. Confirm hard and soft locator failures still populate optional context as expected, generic failures remain valid without it, and reporter attachments retain attempt identity. Keep source links and the pinned version in the review so a future maintainer can distinguish public API guarantees from observed runner behavior.
For generated tests, connect the CI rule to the AI evidence review checklist. Require explicit assertion intent, no swallowed failures, and a deterministic release decision before accepting any automated diagnosis.
Frequently Asked Questions
Where is errorContext available in Playwright Test?
errorContext is an optional property on each TestInfoError. During a hook such as afterEach, read testInfo.error?.errorContext for the first error or iterate testInfo.errors for every recorded failure. It is not a property directly on testInfo, and ordinary errors may leave it undefined.
What does TestInfoError.errorContext contain?
It contains additional diagnostic text associated with the error. For a failed Playwright locator matcher, that text can be an ARIA snapshot of the matcher receiver at failure time. The field is a string, not a parsed accessibility-tree object, and its presence is optional rather than guaranteed for every assertion.
Does errorContext replace traces and screenshots?
No. ARIA context explains roles, names, text, states, and nearby semantic structure. A trace explains chronology, calls, and page snapshots; a screenshot explains pixels; logs can explain application or network events. Keep the smallest evidence set that answers the failure, because each artifact covers a different boundary.
Why is errorContext undefined for some failures?
A generic JavaScript error, a non-locator assertion, setup failure, or manually caught matcher may not create recorded ARIA context. The property is intentionally optional. Preserve the original message and stack, classify the failure source, and never convert missing context into an empty snapshot that suggests the page had no accessible content.
How should CI publish errorContext safely?
Collect it in afterEach, attach only recorded nonempty values, and keep the original error index and test identity. Use synthetic data because ARIA text can include user content. Restrict artifact access and retention, and let deterministic assertions decide release status rather than asking an AI summary to reinterpret the failure.
Rehearse Failure Triage in QABattle
Create one locator assertion failure, one generic assertion failure, and two soft failures. Verify which recorded errors contain context and whether every attachment keeps its attempt and error index. Then diagnose from the original message outward instead of taking a new whole-page snapshot as the first reaction.
Use QABattle battles for the next scenario. Write the expected semantic state, trigger a purposeful mismatch, and practice assigning product, test, data, and evidence ownership. The goal is not to collect the largest failure bundle. It is to preserve the smallest trustworthy record that makes the next engineering decision faster and correct.
// LIVE COURSE / THE TESTING ACADEMY
Playwright Automation Mastery
Go beyond Selenium. Master Playwright with JS/TS in 90 days.
From the instructor behind this guide.
Playwright jobs are growing 8x faster than Selenium. 90 days / 75+ live hrs / Tue-Thu-Sat 7 AM IST.
PRIMARY REFERENCES
Verify the details at the source
QABattle guides are practical explanations. Product behavior, standards, and APIs can change, so use these primary references for the canonical details.
- 01Official playwright.dev reference
playwright.dev
Primary documentation selected and verified for the claims in this guide.
- 02Official playwright.dev reference
playwright.dev
Primary documentation selected and verified for the claims in this guide.
- 03Official playwright.dev reference
playwright.dev
Primary documentation selected and verified for the claims in this guide.
- 04Official playwright.dev reference
playwright.dev
Primary documentation selected and verified for the claims in this guide.
FAQ / QUICK ANSWERS
Questions testers ask
Where is errorContext available in Playwright Test?
errorContext is an optional property on each TestInfoError. During a hook such as afterEach, read testInfo.error?.errorContext for the first error or iterate testInfo.errors for every recorded failure. It is not a property directly on testInfo, and ordinary errors may leave it undefined.
What does TestInfoError.errorContext contain?
It contains additional diagnostic text associated with the error. For a failed Playwright locator matcher, that text can be an ARIA snapshot of the matcher receiver at failure time. The field is a string, not a parsed accessibility-tree object, and its presence is optional rather than guaranteed for every assertion.
Does errorContext replace traces and screenshots?
No. ARIA context explains roles, names, text, states, and nearby semantic structure. A trace explains chronology, calls, and page snapshots; a screenshot explains pixels; logs can explain application or network events. Keep the smallest evidence set that answers the failure, because each artifact covers a different boundary.
Why is errorContext undefined for some failures?
A generic JavaScript error, a non-locator assertion, setup failure, or manually caught matcher may not create recorded ARIA context. The property is intentionally optional. Preserve the original message and stack, classify the failure source, and never convert missing context into an empty snapshot that suggests the page had no accessible content.
How should CI publish errorContext safely?
Collect it in afterEach, attach only recorded nonempty values, and keep the original error index and test identity. Use synthetic data because ARIA text can include user content. Restrict artifact access and retention, and let deterministic assertions decide release status rather than asking an AI summary to reinterpret the failure.
RELATED GUIDES
Continue the learning route
GUIDE 01
Playwright ARIA Snapshots for Testing Accessible Structure
Use Playwright ARIA snapshots to verify roles, names, states, and hierarchy with scoped templates, deliberate strictness, reviewable updates, and layered a11y tests.
GUIDE 02
Custom Playwright Matchers: Extend and Merge expect Safely
Create retry-aware Playwright custom matchers, merge expect modules without collisions, and preserve useful negation, timeout, and failure output.
GUIDE 03
Playwright Locators Guide: Find Elements Reliably
Playwright locators guide for stable UI tests with role selectors, filters, assertions, strict mode, debugging, and flaky selector fixes in CI.
GUIDE 04
Review AI-Generated Playwright Tests with an Evidence Checklist
Master review AI generated Playwright tests with practical examples, architecture decisions, failure analysis, CI guidance, metrics, and scenario-led interview answers.
GUIDE 05
Debug Playwright Visual Snapshot Diffs That Appear Only in CI
Isolate Playwright CI screenshot differences across render environments, fonts, motion, data, and baselines without approving real visual regressions.