agentsclimarketplace

Test layer selection

Skill kamiazya/whiteboard/.claude/skills/test-layer-selection

How to pick the nearest test layer in the whiteboard repo (mcp-node / canvas-viewer-node / canvas-viewer-jsdom / canvas-viewer-browser / web-jsdom / web-browser / E2E), when to reach for a property or model-based test instead of an example, and the commands to run each. Use when writing the red test for a change, or deciding where a regression belongs.From its SKILL.md

Install
npx -y skills add kamiazya/whiteboard --skill test-layer-selection

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 5 stars5 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

4.9 KB, as published. Nobody here has run it

Test Layer Selection

Start with the smallest failing test at the nearest layer. Do not jump to broad E2E if a smaller failing test can isolate the bug.

LayerUse forCommand
mcp-nodepure functions, stores, routes, server behavior, persistence logic in packages/mcp-serverpnpm test --project mcp-node
canvas-viewer-nodepure parsing/serialization logic in packages/canvas-viewer with no DOM dependencypnpm test --project canvas-viewer-node
canvas-viewer-jsdompackages/canvas-viewer components/hooks when browser layout & pointer behavior are NOT the core riskpnpm test --project canvas-viewer-jsdom
canvas-viewer-browserpackages/canvas-viewer popovers, dialogs, scroll, focus, keyboard, pointer, restore flows (real browser)pnpm test --project canvas-viewer-browser
web-jsdomReact components/hooks in apps/web when browser layout & pointer behavior are NOT the core riskpnpm test:web-jsdom (jsdom project only) or pnpm --filter @kamiazya/whiteboard-web test (what CI runs: jsdom + web-node)
web-browserapps/web tests needing real browser APIs jsdom lacks: IndexedDB, OPFS, window.showOpenFilePicker. File suffix .browser.test.tsxpart of pnpm test:browser
E2Ereal routes, server composition, websocket timing, persistence order, multi-step page flowspromote only when needed

Notes:

  • Browser suites together: pnpm run test:browser (canvas-viewer-browser + web-browser); pnpm run test:browser:trace for trace artifacts on failure (under <package>/tmp/vitest-traces).
  • After the targeted test passes, run the broader suite covering the touched area, then pnpm test.
  • Runtime is the source of truth: if behavior disagrees with a test, fix the test or implementation to match real behavior.
  • Passing tests alone are not sufficient — manually verify the real behavior (Playwright/Chrome MCP) before locking the scenario into regression coverage.

Property-Based / Model-Based Testing (PBT)

fast-check is already wired in via shared wrappers — packages/mcp-server/src/shared/test-utils/fast-check.ts, apps/web/src/test-utils/fast-check.ts, and packages/canvas-viewer/src/test-utils/fast-check.ts. Reach for a property (or model-based) test instead of, or in addition to, an example test when the change is one of:

  • Parser / serializer: assert a round-trip (parse(serialize(x)) equals x, or an explicitly computed normalization of x when the serializer is not injective) plus a totality property (parse either throws or returns a schema-valid value — no silent coercion).
  • State machine with time/TTL/revocation (auth/session/challenge stores, sliding-window caches): model the entity as fc.commands-style random sequences of operations (mint/enroll/verify/revoke/ advance-clock) driven by an injected now(), and assert invariants hold after every step — this catches ordering bugs an example test's fixed script cannot.
  • Concurrent store: N concurrent writers converge to one agreed result (e.g. two tabs racing to create the same keypair land on the same key).
  • CRDT / mergeable structure: idempotence (merge twice = merge once), commutativity/convergence (independent edits merged either order reach the same state).
  • Rounding / normalization: the transform's algebraic invariant (e.g. normalize(normalize(x)) === normalize(x)).

Prefer example/browser tests for UI wiring and one-off integrations with no clean invariant to state.

Runtime budget by layer: node-layer properties (mcp-node, canvas-viewer-node) can afford the library's default numRuns; jsdom-layer properties should stay modest; web-browser/canvas-viewer-browser properties are the most expensive per run (real browser + IndexedDB/etc.) — keep numRuns small (single digits to ~20) and prefer the shared wrapper's withDefaults()-style override over inlining { numRuns } ad hoc.

Discipline (matches the fast-check wrappers already in the repo):

  • Never pin a fast-check seed to force a flaky property green — a flake under load is a resource signal (lower numRuns), not an RNG problem to hide.
  • When a property finds a real bug: pin the shrunk counterexample as an example test before fixing production code, fix the implementation, then mutation-check (revert the fix, confirm the pinned example — and ideally the property — goes red, then restore).
  • Shared arbitraries belong in the owning package's test-utils, not copy-pasted per test file.

Keep looking

Skills are one crate of 627,801. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.