Closed as not planned. The silent: true half was done (#506, #512, #516). Shrinking the corpus was measured and is not worth what it costs — figures below, so returning to it is cheap.
Background
Surfaced during the June 2026 multi-angle project audit (QA review). Thematically adjacent to #63/#74.
Problem as filed
test/components/__snapshots__ = 23 MB across 198 files (+ 376 KB / 4 in content/). Top offenders: Calendar.spec.ts.snap at 1.9 MB ×2, DropdownMenu 836 KB ×2, CommandPalette ~800 KB ×2.
No human reviews a 60 KB-per-case diff, so snapshot churn is rubber-stamped — which defeats the purpose of snapshot review, especially on upstream-sync PRs where the snapshot diff is the primary review signal (#75).
Compounding it: vitest.config.ts set silent: true, which suppressed Vue warnings and console errors during render, so a component that rendered something while logging errors still produced a green snapshot.
Done: the silent: true half
#506 added test/utils/console-gate.ts, which fails any test that writes to console.warn or console.error while rendering. #507 and #508 corrected what it found. #512 and #516 then removed the causes of the noise rather than exempting them, by mounting into the document and unmounting after each test:
|
register entries |
tests logging |
messages |
| before #512 |
38 |
62 |
623 |
| after #512 |
37 |
56 |
366 |
| after #516 |
25 |
44 |
569 |
Between them those two changes surfaced four real defects that a detached, never-unmounted harness had been hiding: Modal and Slideover silently dropping the actions slot, Countdown keeping a requestAnimationFrame handle in a ref, the vue project's singleton router losing its navigation between cases, and the console gate itself being registered so that it stopped watching before teardown ran.
#514, which proposed re-shaping the register into per-file budgets, is closed as not planned for the same reason as this issue.
Not done, and not planned: the size
Where it stands
Measured with git ls-tree -r --long (content bytes). Attaching did not meaningfully change it: 26.35 MB before #512, 26.38 MB after.
|
size |
entries |
average entry |
| whole corpus |
26.4 MB / 212 files |
4,359 |
6.2 KB |
Calendar ×2 |
2,539 KB each |
44 |
57.7 KB |
DropdownMenu ×2 |
817 / 816 KB |
32 |
25.5 KB |
CommandPalette ×2 |
784 / 782 KB |
42 |
18.7 KB |
InputMenu ×2 |
707 / 705 KB |
57 |
12.4 KB |
Table ×2 |
681 / 680 KB |
36 |
18.9 KB |
That is 38% of the tracked tree (70 MB excluding node_modules and .git).
Upstream has the same corpus, and lives with it
Fetched from nuxt/ui@v4 and measured the same way:
| file |
nuxt/ui |
b24ui |
avg class attribute |
Calendar.spec.ts.snap |
1,666 KB (32.7 KB/entry) |
2,539 KB (57.7 KB/entry) |
214 → 431 chars |
DropdownMenu.spec.ts.snap |
348 KB (14.5 KB/entry) |
817 KB (25.5 KB/entry) |
115 → 243 chars |
CommandPalette.spec.ts.snap |
531 KB (12.6 KB/entry) |
784 KB (18.7 KB/entry) |
101 → 163 chars |
There is no upstream technique being missed — this is a property of snapshot testing a Tailwind component library. Our entries run about 1.8× larger for a measurable and deliberate reason: the Bitrix24 design tokens live inside Tailwind arbitrary values (text-(--ui-color-accent-main-primary), text-(length:--ui-font-size-md)/(--ui-font-line-height-md)) where upstream uses short semantic utilities. That is the point of the fork.
What was evaluated, and why it was rejected
Hoisting repeated class strings into a per-entry legend. 63% of the corpus is class= attributes, and 34% (8.78 MB) is the same string repeated within one entry. A prototype cut the corpus 32% (26.4 → 17.7 MB) and Calendar's average entry from 57.7 KB to 18.8 KB, with no loss of coverage.
Rejected because it does not solve the problem this issue names. On the scenario that matters — an upstream sync flips one utility sitting on 47 elements of one entry:
|
diff lines |
bytes to read |
| as-is |
94 |
29,155 |
| hoisted |
98 |
13,765 |
Half the bytes, the same number of places to look. The elements share a utility, not a whole class string, so each distinct string is its own legend line. It buys weight, not reviewability, at the cost of snapshots no longer being literal HTML.
(Recorded in case anyone builds something similar: legend tokens must be named by content hash, not sequentially. With sequential numbering, inserting one element renumbered the legend and turned a 3-line diff into a 227-line one.)
Snapshotting only the variant-bearing subtree. The only evaluated option that does cut diff lines. Rejected on cost: per-case judgement across the six largest components about what each case may stop asserting, a deliberate reduction in coverage, and snapshots that diverge further from upstream's exactly where we compare against them on sync PRs.
Decision
Stay with upstream's shape and live with the corpus. Neither fix pays for itself: one gives weight without reviewability, the other gives reviewability by giving up coverage and by diverging from the repository we sync against.
No CI size budget either — a soft warning over a corpus that is knowingly and permanently over budget is noise, and the exception list would be most of the largest files.
The trigger to reopen would be the corpus growing materially beyond 26 MB, or a sync PR where an unreviewed snapshot diff actually lets a regression through.
Original Fix section, for the record
Priority: P3.
Closed as not planned. The
silent: truehalf was done (#506, #512, #516). Shrinking the corpus was measured and is not worth what it costs — figures below, so returning to it is cheap.Background
Surfaced during the June 2026 multi-angle project audit (QA review). Thematically adjacent to #63/#74.
Problem as filed
test/components/__snapshots__= 23 MB across 198 files (+ 376 KB / 4 incontent/). Top offenders:Calendar.spec.ts.snapat 1.9 MB ×2,DropdownMenu836 KB ×2,CommandPalette~800 KB ×2.No human reviews a 60 KB-per-case diff, so snapshot churn is rubber-stamped — which defeats the purpose of snapshot review, especially on upstream-sync PRs where the snapshot diff is the primary review signal (#75).
Compounding it:
vitest.config.tssetsilent: true, which suppressed Vue warnings and console errors during render, so a component that rendered something while logging errors still produced a green snapshot.Done: the
silent: truehalf#506 added
test/utils/console-gate.ts, which fails any test that writes toconsole.warnorconsole.errorwhile rendering. #507 and #508 corrected what it found. #512 and #516 then removed the causes of the noise rather than exempting them, by mounting into the document and unmounting after each test:Between them those two changes surfaced four real defects that a detached, never-unmounted harness had been hiding:
ModalandSlideoversilently dropping theactionsslot,Countdownkeeping arequestAnimationFramehandle in aref, thevueproject's singleton router losing its navigation between cases, and the console gate itself being registered so that it stopped watching before teardown ran.#514, which proposed re-shaping the register into per-file budgets, is closed as not planned for the same reason as this issue.
Not done, and not planned: the size
Where it stands
Measured with
git ls-tree -r --long(content bytes). Attaching did not meaningfully change it: 26.35 MB before #512, 26.38 MB after.Calendar×2DropdownMenu×2CommandPalette×2InputMenu×2Table×2That is 38% of the tracked tree (70 MB excluding
node_modulesand.git).Upstream has the same corpus, and lives with it
Fetched from
nuxt/ui@v4and measured the same way:Calendar.spec.ts.snapDropdownMenu.spec.ts.snapCommandPalette.spec.ts.snapThere is no upstream technique being missed — this is a property of snapshot testing a Tailwind component library. Our entries run about 1.8× larger for a measurable and deliberate reason: the Bitrix24 design tokens live inside Tailwind arbitrary values (
text-(--ui-color-accent-main-primary),text-(length:--ui-font-size-md)/(--ui-font-line-height-md)) where upstream uses short semantic utilities. That is the point of the fork.What was evaluated, and why it was rejected
Hoisting repeated class strings into a per-entry legend. 63% of the corpus is
class=attributes, and 34% (8.78 MB) is the same string repeated within one entry. A prototype cut the corpus 32% (26.4 → 17.7 MB) andCalendar's average entry from 57.7 KB to 18.8 KB, with no loss of coverage.Rejected because it does not solve the problem this issue names. On the scenario that matters — an upstream sync flips one utility sitting on 47 elements of one entry:
Half the bytes, the same number of places to look. The elements share a utility, not a whole class string, so each distinct string is its own legend line. It buys weight, not reviewability, at the cost of snapshots no longer being literal HTML.
(Recorded in case anyone builds something similar: legend tokens must be named by content hash, not sequentially. With sequential numbering, inserting one element renumbered the legend and turned a 3-line diff into a 227-line one.)
Snapshotting only the variant-bearing subtree. The only evaluated option that does cut diff lines. Rejected on cost: per-case judgement across the six largest components about what each case may stop asserting, a deliberate reduction in coverage, and snapshots that diverge further from upstream's exactly where we compare against them on sync PRs.
Decision
Stay with upstream's shape and live with the corpus. Neither fix pays for itself: one gives weight without reviewability, the other gives reviewability by giving up coverage and by diverging from the repository we sync against.
No CI size budget either — a soft warning over a corpus that is knowingly and permanently over budget is noise, and the exception list would be most of the largest files.
The trigger to reopen would be the corpus growing materially beyond 26 MB, or a sync PR where an unreviewed snapshot diff actually lets a regression through.
Original Fix section, for the record
silent: true(or fail tests on unexpected console errors/warnings) so broken-but-rendering states surface. — done, test(console): fail a test that renders while warning #506 / fix(Modal,Slideover): render the actions slot when nothing else opens the header #512 / test(harness): mount hand-written wrappers into the document too, and unmount them #516.snapexceeds a sane budget (e.g. 200 KB).Priority: P3.