@marianmeres/stuic 3.113.0 → 3.115.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/popover/popover.svelte.js +8 -0
- package/dist/actions/spotlight/index.css +9 -2
- package/dist/actions/spotlight/spotlight.svelte.js +35 -26
- package/dist/actions/tooltip/tooltip.svelte.js +5 -0
- package/dist/actions/validate.svelte.js +37 -3
- package/dist/components/H/README.md +1 -1
- package/dist/components/H/index.css +4 -1
- package/dist/utils/anchor-position.d.ts +41 -0
- package/dist/utils/anchor-position.js +69 -0
- package/docs/component-testing/00-overview-and-roadmap.md +119 -0
- package/docs/component-testing/01-framework-setup.md +164 -0
- package/docs/component-testing/02-test-conventions.md +148 -0
- package/docs/component-testing/03-component-coverage-roadmap.md +92 -0
- package/docs/component-testing/04-hard-cases-and-e2e.md +97 -0
- package/docs/component-testing/05-ci.md +88 -0
- package/docs/component-testing/PROGRESS.md +63 -0
- package/docs/component-testing/README.md +38 -0
- package/docs/testing.md +27 -8
- package/package.json +8 -3
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
GENERATED ANALYSIS — @marianmeres/stuic real-browser component testing
|
|
3
|
+
Produced 2026-06-08 by multi-agent research → adversarial verify → synthesize.
|
|
4
|
+
Claims verified against the codebase at commit cc9958b and the live Vitest 4 /
|
|
5
|
+
vitest-browser-svelte docs. Planning artifact; no code was changed.
|
|
6
|
+
-->
|
|
7
|
+
|
|
8
|
+
# Component Testing — @marianmeres/stuic
|
|
9
|
+
|
|
10
|
+
This directory holds the plan for introducing **real-browser component tests** to STUIC
|
|
11
|
+
(Vitest 4 Browser Mode + `vitest-browser-svelte` + Playwright/Chromium). It was produced
|
|
12
|
+
2026-06-08 from a research pass over the codebase and the current Svelte/Vitest ecosystem.
|
|
13
|
+
It is a **planning artifact — no code has been changed**; every claim is verified against the
|
|
14
|
+
repo at commit `cc9958b` or against the live docs cited in each section.
|
|
15
|
+
|
|
16
|
+
**Start here:** [`00-overview-and-roadmap.md`](./00-overview-and-roadmap.md). Then track and
|
|
17
|
+
resume execution from [`PROGRESS.md`](./PROGRESS.md).
|
|
18
|
+
|
|
19
|
+
## Documents
|
|
20
|
+
|
|
21
|
+
| # | Doc | Scope | Headline |
|
|
22
|
+
|---|-----|-------|----------|
|
|
23
|
+
| 00 | [overview-and-roadmap](./00-overview-and-roadmap.md) | synthesis + roadmap | The stack is the right default; vitest 3→4 upgrade is the gating prerequisite. |
|
|
24
|
+
| 01 | [framework-setup](./01-framework-setup.md) | infra | Upgrade vitest 4, add a `projects` split (node `server` + browser `client`), route by filename. |
|
|
25
|
+
| 02 | [test-conventions](./02-test-conventions.md) | how-to | `render()` + locators + `expect.element`; events are props (spies); snippets via `createRawSnippet`. |
|
|
26
|
+
| 03 | [component-coverage-roadmap](./03-component-coverage-roadmap.md) | what to cover | 74 components tiered; warm up on Button/Pill/Switch, one commit per component. |
|
|
27
|
+
| 04 | [hard-cases-and-e2e](./04-hard-cases-and-e2e.md) | the hard 30 | Portals/focus-traps/anchor-positioning: one "hard proof" now; standalone Playwright E2E deferred. |
|
|
28
|
+
| 05 | [ci](./05-ci.md) | automation | One ~30-line GitHub Actions workflow; install Chromium, run `pnpm test`. |
|
|
29
|
+
|
|
30
|
+
## How it was produced
|
|
31
|
+
|
|
32
|
+
Five parallel research agents (test-infra audit, full component inventory, multistep-format
|
|
33
|
+
extraction, two independent web-research angles on the stack) → synthesis → live-docs
|
|
34
|
+
verification of the exact Vitest 4 config syntax → this plan.
|
|
35
|
+
|
|
36
|
+
> Nothing here is decided beyond the four clarifying answers recorded in
|
|
37
|
+
> [`PROGRESS.md`](./PROGRESS.md) → Decisions log. Each doc's "Open questions / decisions needed"
|
|
38
|
+
> lists what still needs a call.
|
package/docs/testing.md
CHANGED
|
@@ -11,7 +11,12 @@ This is a component library. Most of its correctness guarantees come from:
|
|
|
11
11
|
3. **The build** — every component compiles, every export resolves.
|
|
12
12
|
4. **Manual/visual review** — styling, animation, keyboard interaction, a11y cues.
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Tests are for what those tools can't see. There are **two layers**, split by filename:
|
|
15
|
+
|
|
16
|
+
- **`*.test.ts` — node, fast.** Pure deterministic logic where a regression silently corrupts data.
|
|
17
|
+
- **`*.svelte.test.ts` — real browser (Chromium).** Component _behavior_ the build can't see: events firing, two-way `bind:`, `aria`/`disabled`/`active` state, focus traps, computed layout/positioning.
|
|
18
|
+
|
|
19
|
+
We still explicitly don't try to test everything. The browser layer targets **behavior contracts**, not "does it render" — see [`component-testing/`](./component-testing/) for the strategy, roadmap, and how-to.
|
|
15
20
|
|
|
16
21
|
## What we test
|
|
17
22
|
|
|
@@ -20,6 +25,7 @@ Unit tests are for what those tools can't see: **pure deterministic logic where
|
|
|
20
25
|
- **Validation helpers** — `validateEmail`, `validateAddress`, `validateCustomerForm`, `validateLoginForm`, `validatePhoneNumber`, `addressesEqual`.
|
|
21
26
|
- **State-machine classes** — `NotificationsStack`, `AlertConfirmPromptStack`, `SwitchState`, `InputHistory`. Tri-state transitions, dedupe, ordering, cleanup semantics.
|
|
22
27
|
- **Pure utilities** — `replace-map`, `tr`, `storage-abstraction`, and anything else with non-trivial input/output logic.
|
|
28
|
+
- **Component behavior** (browser mode, `*.svelte.test.ts`) — prop→DOM/`aria` contracts, events firing, `bind:` updates, focus traps, viewport-clamped positioning. One component at a time, asserting contracts a consumer relies on — not every prop permutation.
|
|
23
29
|
|
|
24
30
|
### ⚠️ Maybe, if motivated by a regression
|
|
25
31
|
|
|
@@ -27,18 +33,23 @@ Unit tests are for what those tools can't see: **pure deterministic logic where
|
|
|
27
33
|
|
|
28
34
|
### ❌ We don't test
|
|
29
35
|
|
|
30
|
-
- **
|
|
31
|
-
- **Visual regression**.
|
|
32
|
-
- **
|
|
36
|
+
- **Exhaustive prop-matrix / "does it render" tests.** 50+ components × every prop combination = slow suite with tiny yield. Rendering is already gated by `svelte-check` + `publint` + the build; the browser layer asserts _behavior contracts_, not coverage of every permutation.
|
|
37
|
+
- **Visual regression**. A separate concern (Vitest's `toMatchScreenshot` / screenshot diffing) — deferred, not part of `pnpm test` today.
|
|
38
|
+
- **Heavy gestures & 3rd-party editors** (drag-drop reorder, file drop, Milkdown/CodeMirror) — deferred to a future standalone Playwright **E2E** layer, not the in-repo browser project. Extract and node-test their pure logic where practical.
|
|
33
39
|
- **Coverage % targets**. They're the wrong goal for a component library.
|
|
34
40
|
|
|
35
41
|
## Running tests
|
|
36
42
|
|
|
37
43
|
```bash
|
|
38
|
-
pnpm
|
|
44
|
+
pnpm test # both projects (node + browser), one-shot
|
|
45
|
+
pnpm test:watch # watch mode
|
|
46
|
+
pnpm test:ui # Vitest UI (handy for the browser project)
|
|
39
47
|
```
|
|
40
48
|
|
|
41
|
-
Vitest
|
|
49
|
+
Vitest runs **two projects**, routed by filename: a node project for `*.test.ts` and a real-browser
|
|
50
|
+
(Chromium, via Playwright) project for `*.svelte.test.ts`. Tests live next to the code they test:
|
|
51
|
+
`foo.ts` → `foo.test.ts`; `Foo.svelte` → `Foo.svelte.test.ts`. The browser binary is installed once
|
|
52
|
+
with `pnpm exec playwright install chromium`.
|
|
42
53
|
|
|
43
54
|
## Writing a test
|
|
44
55
|
|
|
@@ -65,8 +76,16 @@ import type { TranslateFn } from "$lib/types.js";
|
|
|
65
76
|
const t: TranslateFn = (k) => k;
|
|
66
77
|
```
|
|
67
78
|
|
|
79
|
+
For **component** tests (`*.svelte.test.ts`), the patterns differ — `render()` from
|
|
80
|
+
`vitest-browser-svelte`, locators, and the retry-able `expect.element`; events are props (assert with
|
|
81
|
+
spies); snippet children come from `createRawSnippet`. See
|
|
82
|
+
[`component-testing/02-test-conventions.md`](./component-testing/02-test-conventions.md) for the full
|
|
83
|
+
how-to and the "what to assert" checklist.
|
|
84
|
+
|
|
68
85
|
## When in doubt
|
|
69
86
|
|
|
70
|
-
- **Logic in a `.ts` file with clear input/output?** Write a test.
|
|
87
|
+
- **Logic in a `.ts` file with clear input/output?** Write a `*.test.ts`.
|
|
88
|
+
- **A component behavior that's a real contract** (event fires, value binds, focus traps, position
|
|
89
|
+
clamps)? Write a `*.svelte.test.ts`.
|
|
71
90
|
- **A regression just bit you in production?** Write a test for that specific case before fixing.
|
|
72
|
-
- **
|
|
91
|
+
- **"Does it render with these 12 props?"** Probably don't bother — the build already covers that.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@marianmeres/stuic",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.115.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "vite dev",
|
|
6
6
|
"build": "vite build && pnpm run prepack",
|
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
|
14
14
|
"format": "prettier --write .",
|
|
15
15
|
"lint": "eslint . && prettier --check .",
|
|
16
|
-
"test": "vitest
|
|
16
|
+
"test": "vitest run",
|
|
17
|
+
"test:watch": "vitest",
|
|
18
|
+
"test:ui": "vitest --ui",
|
|
17
19
|
"svelte-check": "svelte-check",
|
|
18
20
|
"svelte-package": "svelte-package",
|
|
19
21
|
"rp": "pnpm run build && ./release.sh patch",
|
|
@@ -145,9 +147,11 @@
|
|
|
145
147
|
"@tailwindcss/typography": "^0.5.19",
|
|
146
148
|
"@tailwindcss/vite": "^4.3.0",
|
|
147
149
|
"@types/node": "^25.9.2",
|
|
150
|
+
"@vitest/browser-playwright": "^4.1.8",
|
|
148
151
|
"dotenv": "^16.6.1",
|
|
149
152
|
"eslint": "^9.39.4",
|
|
150
153
|
"globals": "^16.5.0",
|
|
154
|
+
"playwright": "^1.60.0",
|
|
151
155
|
"prettier": "^3.8.3",
|
|
152
156
|
"prettier-plugin-svelte": "^3.5.2",
|
|
153
157
|
"publint": "^0.3.21",
|
|
@@ -158,7 +162,8 @@
|
|
|
158
162
|
"typescript": "^5.9.3",
|
|
159
163
|
"typescript-eslint": "^8.60.1",
|
|
160
164
|
"vite": "^7.3.5",
|
|
161
|
-
"vitest": "^
|
|
165
|
+
"vitest": "^4.1.8",
|
|
166
|
+
"vitest-browser-svelte": "^2.1.1"
|
|
162
167
|
},
|
|
163
168
|
"dependencies": {
|
|
164
169
|
"@marianmeres/clog": "^3.21.0",
|