Answer
\n
Playwright should not extend accessibility.snapshot() to include omitted ARIA attributes such as aria-describedby or aria-details. The snapshot is intended to reflect the browser's accessibility tree (name, role, state, value, description). Adding raw DOM attributes would blur that purpose and introduce browser‑specific inconsistencies. For attribute‑level audits, use axe‑core directly; combine the two tools when you need both tree‑level and rule‑based validation.
\n
Confirmed facts
\n
\n- Playwright's
accessibility.snapshot() returns a JSON representation of the computed accessibility tree (name, role, value, description, etc.) and deliberately excludes raw ARIA attributes that are not mapped to accessibility properties. \n- axe‑core evaluates the full DOM (including shadow DOM when configured) and can report violations based on attributes that do not affect the accessibility tree, leading to apparent mismatches.
\n- The discrepancy is most noticeable with custom components, elements inside shadow roots, or when axe‑core is tuned to check attributes that are not exposed in the accessibility tree.
\n
\n
Likely explanation
\n
The mismatch arises because the two tools operate at different layers: snapshot = accessibility‑tree layer; axe‑core = DOM‑attribute layer. Extending the snapshot to include omitted attributes would require Playwright to duplicate axe‑core’s attribute inspection, which is outside its scope and would increase maintenance burden without providing a normalized cross‑browser tree.
\n
Steps to diagnose and resolve the mismatch for this case
\n
\n- Create a test page that contains an element with an ARIA attribute that is not reflected in the accessibility tree, e.g.,
<img src='x' aria-describedby='desc'> where the described element is hidden or not part of the tree. \n- Run Playwright snapshot:\n
const snapshot = await page.accessibility.snapshot();
\nCapture the JSON output.\n \n- Run axe‑core on the same page (using
axe-cli or import { axe } from '@axe-core/playwright'):\nconst results = await axe.run(page);
\n \n- Compare the snapshot’s
attributes (if any) with the violations reported by axe. You will see that the snapshot lacks the aria-describedby entry while axe may flag a missing or misused attribute. \n- If you need to assert on the attribute value, use axe‑core’s rule results directly; otherwise, rely on the snapshot for tree‑level checks (name, role, state).
\n
\n
Missing diagnostic detail
\n
If you are testing inside a shadow DOM or an iframe, please confirm whether you are scoping the accessibility snapshot to that boundary (e.g., passing root option) because the recommendation may change if the snapshot omits elements that axe‑core can see.