Skip to content

test: reorganize e2e suites, fix failing tests, and prune to library-only coverage - #56

Open
tfukaza wants to merge 8 commits into
refactor/core-geometryfrom
test/e2e-reorg
Open

tfukaza wants to merge 8 commits into
refactor/core-geometryfrom
test/e2e-reorg

Conversation

@tfukaza

@tfukaza tfukaza commented Sep 11, 2026 •

Copy link
Copy Markdown
Owner

Stacked on #55. Review that PR first; this one's diff is against refactor/core-geometry.

What changed

1. E2E layout (9d9ab49)

  • One Playwright config per project, laid out as tests/e2e/<project>/<use-case>/. The projects are core, asset-base, snapline and snapsort (plus snapsort/layout.playwright.config.ts, a cross-browser layout matrix). The snapdesign and website configs created here are removed again in section 4. Files moved with git mv wherever they weren't split.
  • Shared server setup: tests/e2e/shared/servers.ts holds the one port table (every port unique, each overridable by env var), the demo and website dev servers, and coreImportPath for in-page /@fs imports.
  • Framework-only specs are named *.react.spec.ts / *.svelte.spec.ts, and projects route on those names. There are no more in-test test.skip framework guards.
  • The 6.7k-line snapsort-drag-snapshot.spec.ts is split by use case. Its 33 pure tests move to tests/ut/snapsort-{drag-config,drop-priority,placement}.spec.ts, and snapsort-callback-ledger moves to tests/ut/ as well. Shared helpers live in tests/helpers/snapsort-fixtures.ts and tests/e2e/snapsort/_support/.
  • Newly scripted: 11 website/SnapDesign specs that no script ran before are now wired in. They were later deleted (section 4).
  • Root config: playwright.config.ts now covers only tests/ut, so npm test is the unit sweep. npm run test:e2e runs every project config.
  • Scripts: the old per-suite script names still work, as filters over the new configs.
  • Deleted:
    • the orphaned snapsort_drag.spec.ts
    • the unrouted nested_items demo
    • the obsolete tests/ut/input.spec.ts
    • the old configs

2. Fixes for failing e2e tests (f06b1c9, a6af841, 469a8e0)

  • Insertion demos: columns now use prioritizePointerContainer. Strict main-axis insertion ranking is kept and documented in assets/snapsort/AGENTS.md. The wrapped-row unit test is rewritten to pin that rule.
  • KeyboardDragController: an arrow key pressed while a direct-drag lift is still activating no longer scrolls the page. A regression test covers it and failed on the old controller.
  • React SnapSort fixture: now exposes the programmatic-removal hooks the Svelte demo already had.
  • Nested demo styles: its unscoped :global styles no longer leak into other Svelte demo pages.
  • Website dev server: svhighlight is pre-bundled. On a cold Vite cache, the first visit to /about triggered a dependency re-optimize and a page reload, which dropped the navigation.
  • Stale tests updated:
    • a renamed test id
    • the leaked-ghost test.fail, now an assertion of the fixed behavior
    • the gallery exhibit list
    • camera-card zoom direction
    • the insertion-marker threshold pre-move
  • Dead tests removed: four website preview tests that could no longer fail.

3. Remaining issues from the refactor (f743bd2)

  • check:website is clean: a new sessionPointerId() helper fixes the 8 session.pointerId errors, so it reports 0 errors.
  • Tests are type-checked: tsconfig.tests.json plus npm run check:tests (48 errors fixed), wired into npm run ci and GitHub CI.
  • SnapLine collider size: colliders on scaled nodes now keep their unscaled local size (readDom({ unapplyTransform: true })). A unit test covers it and failed before the fix.
  • freezePoint moved to core geometry. The two SnapSort copies are removed.
  • CI also runs test:core-ut and test:snapline-ut, matching npm run ci. CI still doesn't run the e2e suites.
  • Docs and AGENTS.md now point at the new test paths.

4. Stop testing the website; prune excessive tests (4a9d82d, e06dcab, 37216f3)

Tests now cover only the engine, the asset packages, and the demo/ apps.

  • Website tests deleted: tests/e2e/website (27), tests/e2e/snapdesign (39), and the unit test that imported website source. Their scripts and dev-server entries are gone too, and AGENTS.md says the website is not tested. Some SnapSort behaviors had browser coverage only through website pages (swap drag, dropEffect: "none", dragVisual: "none", concurrent drags). They are not ported; unit tests still cover parts of them. tests/promo stays, since it records video rather than testing anything.
  • Unit tests: 271 → 262.
    • Dropped: the assertion-free snapline-perf benchmark, plus duplicates in core-layout, snapsort-placement, snapsort-drop-priority and snapsort-algorithm.
    • Merged: the CoreObject/BaseObject transform twins, and the write-cascade recursion test. The merged cascade test now also checks that a none-mode child's subtree is pruned.
    • core-input-error-isolation moved into the shared input harness.
    • @ts-expect-error markers for long-removed APIs dropped from the SnapSort type contract.
  • E2E:
    • layout/** renders its own markup, so it now runs only in the layout config. It used to run on both demo projects as well.
    • The 3-browser matrix is limited to specs whose result depends on browser layout.
    • 5 SnapLine and 5 SnapSort tests that other tests already cover are removed, and 4 are merged into neighbors.
    • The AnimationObject channel test moved to tests/e2e/core/animation, since it needs real Web Animations.
  • Harness: removed helpers that parsed ghost logs the engine no longer emits, so their assertions could never fail. Also removed unasserted screenshots and frame-rect capture.
  • Kept on review: several suggested cuts turned out to guard real contracts. Examples: the frozen containerPlan (public API), the "no direct layout reads" source guard (SNAPSORT_SIMPLIFICATION.md), session cleanup on ended handles (apps keep the handle), and the real-reconciler bulk load.

Verification

  • npm run ci passes.

  • npm test (unit sweep): 262 passed.

  • Unit suites: test:core-ut 97, test:snapsort-ut 122, test:snapline-ut 43.

  • E2E (Chromium unless noted), before and after section 4:

    Suite Before After
    core (chromium, firefox, webkit) 12 15
    asset-base 7 7
    snapline 64 (1.2m) 58 (1.2m)
    snapsort (svelte + react) 143 (5.9m) 111 (5.1m)
    layout (chromium, firefox, webkit) 187 (8.3m) 129 (5.7m)
    snapdesign 39 (2.2m) removed
    website 27 (1.4m) removed
  • The only expected failures left are the three design-limitation test.fails (RTL flex, grid spans, stretch intrinsic heights). Playwright counts them as passed.

  • Test counts were checked against the pre-reorg baseline. Every source test maps to a destination, apart from the deletions listed above.

Package version bumps are still a release step (see #55).

🤖 Generated with Claude Code

https://claude.ai/code/session_01DsiHfSvTGUzy6iNEkoWiG3

tfukaza and others added 5 commits September 11, 2026 12:34
tests/e2e was flat: 34 specs and 15 configs side by side, several ports
shared between configs, and 11 website/SnapDesign specs reachable only
from a config no script ran.

- One Playwright config per project: tests/e2e/{core,asset-base,
  snapline,snapsort,snapdesign,website}/playwright.config.ts, plus
  snapsort/layout.playwright.config.ts for the cross-browser layout
  matrix. Specs sit in per-feature folders (snapline/resize/,
  snapsort/insertion/, snapdesign/gallery/, ...).
- tests/e2e/shared/servers.ts replaces playwright-matrix.ts and the
  per-config boilerplate: one unique port table, demo and website dev
  servers, browser devices, and `coreImportPath` for in-page core imports
  (replacing 13 `/@fs${process.cwd()}` copies).
- Framework-only specs are named *.react.spec.ts / *.svelte.spec.ts and
  routed by project globs (replaces a test.skip and an ad-hoc project).
- snapsort-drag-snapshot.spec.ts (6.7k lines) is split into 15 use-case
  specs across layout/, drag/, animation/, nested/, components/,
  insertion/, and ghosts/, with shared helpers in snapsort/_support/ and
  DOM-free fixtures in tests/helpers/snapsort-fixtures.ts.
- Tests that never open a page move to tests/ut: snapsort-callback-ledger,
  the 33 pure drop-resolution tests (snapsort-drag-config, -drop-priority,
  -placement), and the two material-surface serializer tests. They run once
  instead of up to five times behind demo servers.
- website-navigation's Gallery and Layers-panel tests move to snapdesign/.
- The root config now covers tests/ut only, so `npm test` is the unit
  sweep instead of every spec with no base URL.
- Remove the orphaned, stale snapsort_drag.spec.ts (it hard-coded :3001
  and a page that no longer exists), the unrouted nested_items demo, the
  obsolete tests/ut/input.spec.ts (it targeted a pre-pointer-events
  InputControl API), and the retired configs. input-* unit specs become
  core-input-* so test:core-ut runs them.
- New scripts test:{core,asset-base,snapline,snapsort,snapdesign,website}
  and test:e2e; the old suite scripts remain as filtered aliases.

Every test maps to a destination: the per-config test counts reconcile
with the previous suites, minus only the moved pure tests and the six
always-skipped React runs of the Svelte-only ghost spec.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DsiHfSvTGUzy6iNEkoWiG3
Every failure here predates the reorganization; each fix targets its root
cause.

- Insertion demos (Svelte and React): insertion ranks gaps by main-axis
  distance alone (a documented rule since 0031eb3), so an empty sibling
  column whose center lined up with the pointer's Y took the marker. The
  columns now opt into `prioritizePointerContainer`, and AGENTS.md says
  side-by-side destinations need it. Fixes three insertion-copy tests and
  the adapter-ghosts insertion-owner test.
- "moves one stable marker": the move that crosses the drag threshold only
  starts the session and is never resolved; activate the drag first.
- The wrapped-row unit test predated the main-axis rule; it now pins the
  documented result (a first-line gap wins on X) with the reasoning inline.
- React components demo: expose `__snapsortRemoveComponentItem` and
  `__snapsortDeleteComponentItem` like the Svelte demo, so the programmatic
  removal test exercises React instead of reading `undefined`.
- asset-base React spec: the demo's test id is `camera-engine` (renamed in
  885701b).
- The locked-container `test.fail` could no longer reproduce its leak (fixed
  in input) and failed on its own precondition; it is now a positive
  regression test that no drag state is left behind.
- DropSnapNestedDemo's unscoped `:global(.snapsort-container/.snapsort-item)`
  rules leaked into every Svelte demo page; scope them to the demo.
- website engine-lifecycle: remove three tests of the SnapSort home-page
  preview that 4cf8a6a replaced with a static mock, and one that passed
  vacuously on a warning that no longer exists.
- Keyboard drag: an arrow pressed while a lift was still activating fell
  through to the browser and scrolled the page (the flaky "animates the
  active item" failure). The controller now consumes movement keys until
  the lift has a target; the animation test waits for the lift, and a new
  test pins the consumed key (it fails without the fix).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DsiHfSvTGUzy6iNEkoWiG3
- Website: the SnapDesign gallery read `session.pointerId`, which left the
  public `DragSession` when direct/keyboard input landed (8 svelte-check
  errors). A `sessionPointerId()` helper reads the pointer input instead,
  and the gallery e2e probes do the same. `check:website` is clean.
- Test type-checking: tests were never type-checked, and 125 errors had
  accumulated. `tsconfig.tests.json` + `npm run check:tests` (DOM.Iterable,
  `@types/jsdom`) now cover tests/, and the stale fixtures are fixed to the
  current shapes (PointerPosition sub-points, `DragSession.input`, strategy
  `mode`, typed mock engines) without changing test behavior.
- SnapLine: a node's collision box is its child, so it already inherits the
  node's scale; measuring the rendered (scaled) size applied the scale
  twice. Nodes are now read with their own transform unapplied. A unit test
  pins it and fails without the fix.
- `freezePoint` was duplicated in two SnapSort drag modules; it now lives in
  core geometry next to `freezeRect`.
- CI runs the core and SnapLine unit suites and `check:tests`, matching
  `npm run ci`.
- Docs: AGENTS.md describes the test layout and scripts; stale test paths
  in SNAPSORT_SIMPLIFICATION.md, the SnapLine architecture doc, and test
  comments are updated; the NodeGraph design doc's connector geometry drops
  the removed `scaleX`/`scaleY`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DsiHfSvTGUzy6iNEkoWiG3
These specs lived in a config no script ran, so they drifted unnoticed.
Now that test:website and test:snapdesign run them:

- Gallery route: the Gallery has eight exhibits (Toucan lesson and Kanban
  board joined in 0031eb3, the same commit that wrote the test's count of
  six); assert the exhibit list itself instead of a count.
- Engine lifecycle, About navigation: client-side navigation loads the
  /about route before updating the URL, and on a cold dev server that route
  compiles on first visit, which can exceed the default 5s expect timeout.
- Engine lifecycle, camera card: the card's camera starts at its maximum
  zoom of 1, so the test's ctrl+wheel zoom-in could never change the
  transform (it failed on main as well); zoom out instead, which still
  proves a modified wheel zooms rather than scrolls.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DsiHfSvTGUzy6iNEkoWiG3
…ations

Vite's startup scan misses CodeBlock's svhighlight import. On a cold dep
cache, the first visit to /about discovered it, re-optimized, and reloaded
the page at "/", dropping the client-side navigation. That is what failed
the engine-lifecycle About test on the first run of a fresh server, not a
slow route compile, so the test's extended timeout is reverted.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DsiHfSvTGUzy6iNEkoWiG3
@vercel

vercel Bot commented Sep 11, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
snap-engine-js Ready Ready Preview Sep 11, 2026 9:18pm UTC

tfukaza and others added 3 commits September 11, 2026 13:54
Tests cover the engine, the asset packages, and the demo apps; the website
(landing, about, docs, navigation, the SnapDesign guideline and gallery) is
no longer tested. Removes tests/e2e/website, tests/e2e/snapdesign, the
material-surface unit test that imported website source, their scripts and
dev-server entries, and the doc steps that ran them. tests/promo stays: it
records promo video, it does not test.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DsiHfSvTGUzy6iNEkoWiG3
- snapline-perf: no assertions, only timing logs, yet ran in CI.
- core-layout "wraps a genuinely oversized ghost insertion": weaker than
  "still wraps genuine overflow just past the tolerance".
- snapsort-placement: the empty-row marker test duplicates
  snapsort-algorithm's empty-row gap test; the fractional-overflow wrap
  test repeats the trailing-margin fixture, and tolerance is pinned in
  core-layout.
- snapsort-drop-priority: "priority -1 rejects a container" is covered by
  the filter and run-once tests; the all-rejected case folds into the
  rejection/override test. snapsort-algorithm's frozen-event test folds its
  frozen-rect checks into the drop policy event test.
- transform: the CoreObject and BaseObject sync twins become one test over
  both classes; nested direct-mode recursion folds into the cascade test,
  which now also checks that a none-mode child's subtree is pruned.
- core-input-error-isolation moves into core-input-headless-owner on the
  shared harness.
- snapsort-api-contract: drop @ts-expect-error markers for APIs removed
  long ago. Markers for live boundaries and the geometry hard break stay.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DsiHfSvTGUzy6iNEkoWiG3
Config:
- layout/** renders its own markup, so it no longer runs on both demo
  projects of the SnapSort config, only in the layout config; test:e2e
  runs that config on Chromium.
- The layout config's three-browser matrix keeps only specs whose result
  depends on browser layout; lifecycle, framework-state, ghost, FLIP, and
  marker specs run once on Chromium.

Removed (each covered elsewhere):
- snapline: ctrl+wheel zoom (covered by the direction test), React
  connect (covered by edges.react), TL-anchor grow (the nw case of the
  8-handle loop), and the resize cursor test (demo CSS; its attribute
  check could no longer fail).
- snapsort: the nested self-insert probe (unit-tested in snapsort-state),
  the nested-column flicker drag (nested-commit runs the same drag under
  slow FLIP), the flat-list spacer drag (a longer drag of the same item
  follows), the website-core z-index check (demo CSS), and the duolingo
  grading test (demo logic).

Merged:
- edges.react gesture-connect into the replace test.
- group carried-members into the header-drag test.
- lifecycle threshold-release cleanup into the regrab test.
- multi-item-ghosts into adapter-ghosts (final order check).

The pooled animation-variable test moves to tests/e2e/core/animation: it
tests AnimationObject alone and needs real Web Animations.

Harness: removes ghost-log helpers whose logs no longer exist (their
assertions could not fail), probes and sample fields only removed tests
used, unasserted frame-rect capture and screenshots, the no-op trace
hook on setContent layout specs, and adapter-ghosts' stale test.skip.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DsiHfSvTGUzy6iNEkoWiG3
@tfukaza tfukaza changed the title test: reorganize e2e suites by project and fix every failing e2e test test: reorganize e2e suites, fix failing tests, and prune to library-only coverage Sep 11, 2026
@tfukaza
tfukaza added this pull request to stack #57 September 12, 2026 18:27

This branch was successfully deployed

1 active deployment
Preview — 37216f3a Deployed Sep 11, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant