Is there a recommended Vitest serialiser? #3785
-
| Due to how Ark/Zag handles ID attributes, snapshots tend to differ between the local run and the CIs. I looked in the docs and could not find a list of ID patterns, or a recommended Vitest serialiser, so I came up with this empirically: // Snapshot serializer to normalize all dynamic IDs from Ark UI components expect.addSnapshotSerializer({ test: (value) => { if (typeof value !== "string") return false; // Test for any Ark UI ID pattern: // - field-xxx (field IDs) // - component::xxx:: or component:xxx: (component instance IDs) // - :xxx: (bare IDs like :r4d:/log-out) return ( /field-[a-z0-9]{9,}/.test(value) || /\b\w+[:]{1,2}\w*-?[a-z0-9]{3,}[:]{1,2}/i.test(value) || /:[a-z0-9]{3,}:/i.test(value) ); }, serialize: (value: string) => { // Replace all dynamic Ark UI IDs with normalized placeholders let normalized = value; // Step 1: Normalize field IDs normalized = normalized .replace(/field::field-[a-z0-9]{9,}/g, "field::field-NORMALIZED_ID") .replace(/\bfield-[a-z0-9]{9,}/g, "field-NORMALIZED_ID"); // Step 2: Normalize bare IDs that start with colon (like :r4d:/log-out) normalized = normalized.replace( /:([a-z0-9]{3,}):/gi, ":NORMALIZED_ID:" ); // Step 3: Normalize all component instance IDs with component name prefix // Matches patterns like: // - tooltip:tooltip-8saoqm1hs:content // - select::r6g::positioner // - combobox:combobox-abc123:trigger normalized = normalized.replace( /\b(\w+)([:]{1,2})(\w+-)?([a-z0-9]{3,})([:]{1,2})/gi, "$1$2$3NORMALIZED_ID$5" ); return `"${normalized}"`; },It seems to cover all the patterns present in my app so far. I am missing some other ones? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
| Thanks for sharing this — the serializer is a solid approach for normalizing dynamic IDs in snapshots. A few notes: If you keep using snapshots: Your patterns look right for the main Ark/Zag ID formats. One thing to add: React 19.1+ uses guillemets ( Simpler alternative: Zag doesn’t generate IDs — it uses whatever <Dialog.Root id="test-dialog"> <Dialog.Trigger>Open</Dialog.Trigger> <Dialog.Content>...</Dialog.Content> </Dialog.Root>This yields IDs like Broader recommendation: Snapshot tests for UI components are often brittle and low-signal. For Ark components, we generally recommend:
If you do use snapshots, keep them small and focused, and prefer deterministic IDs where possible. We could also document this pattern or provide an official serializer package for those who need it. |
Beta Was this translation helpful? Give feedback.
Thanks for sharing this — the serializer is a solid approach for normalizing dynamic IDs in snapshots.
A few notes:
If you keep using snapshots: Your patterns look right for the main Ark/Zag ID formats. One thing to add: React 19.1+ uses guillemets (
«r1») instead of colons, so you may want to extend the serializer to handle that.Simpler alternative: Zag doesn’t generate IDs — it uses whatever
idyou pass. Thatidis passed into the machine via the Root component (e.g.Dialog.Root,Select.Root). Zag builds part IDs ascomponentName:${id}:partName, so passing a fixedidmakes all derived IDs stable. For example: