feat(experimental): support aria snapshot#9668
feat(experimental): support aria snapshot#9668sheremet-va merged 244 commits intovitest-dev:mainfrom
Conversation
✅ Deploy Preview for vitest-dev ready!Built without sensitive environment variables
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
I finished the follow up of providing domain snapshot API via custom matcher. Internally aria snapshot also goes through the same path. #10041 I like this shape better so I will merge this to here after #10042 merged to main. EDIT: two are merged via hi-ogawa#5 |
* refactor: use custom matcher for domain snapshot
* test: test toMatchKvSnapshot and toMatchKvInlineSnapshot
* test: update exports
* refactor: aria snapshot via expect.extend
* chore: comment what to do
* feat: support `expect.extend(..., { __vitest_poll_takeover__: true })`
* test: update
* refactor: remove unused
* test: update exports
* refactor: remove more
* test: update
* chore: remove types
* docs: remove addSnapshotDomain
* chore: clean snapshot matcher transition leftovers
Co-authored-by: Codex <noreply@openai.com>
* chore: unused
* docs: update custom snapshot matcher guidance
Co-authored-by: Codex <noreply@openai.com>
* docs: re-order
* docs: jsdoc
* refactor: use __vitest_poll_takeover__ per matcher function
* refactor: revert expect.extend options
* chore: comment
* chore: comment
---------
Co-authored-by: Codex <noreply@openai.com>
|
@sheremet-va This is ready yet again. |
sheremet-va
left a comment
There was a problem hiding this comment.
I don't think I've seen a multi-line ARIA snapshot - how are they supported?
Otherwise looks good 👍
docs/api/expect.md
Outdated
|
|
||
| - **Type:** `() => void` | ||
|
|
||
| Captures the accessibility tree of a DOM element and compares it against a stored snapshot. Inspired by [Playwright's ARIA snapshots](https://playwright.dev/docs/aria-snapshots). |
There was a problem hiding this comment.
I simplified the paragraph here and removed the mention.
| On first run, Vitest generates a snapshot file entry: | ||
|
|
||
| ```yaml | ||
| - form "Log In": |
There was a problem hiding this comment.
Does it create a separate file or does it have exports[] file? I thought it just follow regular snapshots, but this example makes me doubt it
There was a problem hiding this comment.
Good catch. Updated with the explicit file with __snapshots__/basic.test.ts.snap.
| } | ||
| } | ||
|
|
||
| // TODO: should `all` mode ignore parse error? |
There was a problem hiding this comment.
Not certain. Silently hiding parse error isn't good either and users can fix or purge the broken snapshot manually and that decision affects how the snapshot get updated since aria snapshot adjusts based on the template side.
I'll leave this as is and see what will happen. I've updated the comment to mention the decision.
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Do you mean multiline text like paragraph? ARIA snapshot normalize white space and new lines, so the generated text is always a single line. For example, <p>
....anything...
...<br />
...
</p>should always end up - paragraph: ...anything but normalized... |
Co-authored-by: Codex <noreply@openai.com>
sheremet-va
left a comment
There was a problem hiding this comment.
LGTM, let's see how it goes
Description
updateSnapshotviaSnapshotState#9481Adds
toMatchAriaSnapshot()andtoMatchAriaInlineSnapshot()matchers for asserting DOM accessibility trees, inspired by Playwright's aria snapshot feature. Core logic of aria tree generation, parsing, matching are entirely implemented onivyavitest-dev/ivya#8 as Aria related runtime utility lives there.Under the hood, this PR also introduces domain snapshot API in Vitest core to allow extending comparison mechanism beyond exact string equality. The simple example is added as a test case and also documented to illustrate the idea. However, I'd treat this API being "experimental" since I haven't too deeply thought through the API shape beyond what I minimally needed for implementing aria snapshot.
API
Example
Given HTML like
Initially generated snapshot looks like:
Snapshot can be manually edited to include regex pattern or remove some part and snapshot assertion continues to pass:
Now when actual HTML changes to:
Snapshot would now fail, but the error diff normalizes partially matching part:
When forcing the snapshot update via
--update, newly generated snapshot would reflect the same error diff, which means manually edited part is preserved:TODO
adapter.parseExpected)/childrendirective in aria tree template ivya#10Questions
--updatewait for stable snapshot?TODO: new heuristics and new option? employ similar strategy astoMatchScreenshot?Yes, it should. We can simplify pool more and wait until stable on
"new"(initial snaphsot) and"all"(--update) casesHow to pull in(fixed by feat: add minimal YAML parser for aria snapshot templates ivya#13)yaml?@vitest/browser/dist/expect-element.js. The packageyamlis huge around 100kb. This causedexpect-element.jsto go from23kbto140kb. Should we try code split and lazily load on runtime?toMatchAriaSnapshotspecifically asynchronous, which is technically possible. Or we can make explicit opt-in/out flag to lazy load early during runtime.feat: add minimal YAML parser for aria snapshot templates ivya#13
Follow-up considered
/childrenproperty (port https://playwright.dev/docs/aria-snapshots#strict-matching)/childrendirective in aria tree template ivya#10toMatchFileSnapshotconfig to register snapshot domain similar tosnapshotSerializersfeat(experimental): support aria snapshot #9668 (comment)expect.extend.TODO
expect.element + aria snapshotbecomes a special casedefineHelper. should be fixed on next playwright update, which has better async stack.Please don't delete this checklist! Before submitting the PR, please make sure you do the following:
pnpm-lock.yamlunless you introduce a new test example.Tests
pnpm test:ci.Documentation
pnpm run docscommand.Changesets
feat:,fix:,perf:,docs:, orchore:.