refactor(daemon): relocate the interaction touch tests by what they assert

Merged
TH
1d ago
+2381-2251

Summary

Batch interaction-touch of the daemon test redesign (no test exports of any kind). The 16 root tests (plus the interaction-touch-runner.ts helper and the root-level interaction-touch-android-readiness-spawns sibling) that drove handleInteractionCommands with the real command surface are placed by what they assert. Daemon halves (a) now run against package fakes; assertions about what the real src/commands/interaction/** code does (c) moved to tests beside that code. snapshot-interactor-capture mocks are gone: captures go through installInteractorSnapshotResolution() (the InteractorResolution seam). Stacked on #3670.

New package fixtures, all unexported: interactor-resolution-fixture.ts, touch-command-surface-fake.ts, touch-interaction-runner.ts.

a / c split and test-count parity

Before = exact count at the old path (vitest JSON reporter); after = run count per destination (all under packages/daemon/src/execution/ unless noted).

Source (before)Daemon half (a)Command half (c), src/commands/interaction/runtime/
interaction-touch (12)interaction/internal/interaction-touch-routing.test.ts (12)none
interaction-touch-press-admission (13).../interaction-touch-press-admission.test.ts (12)interactions-preresolved-target.test.ts (the #1654 provenance-mismatch case)
interaction-touch-press (9).../interaction-touch-press.test.ts (5)interactions-target-promotion.test.ts (4), interactions-preresolved-target.test.ts (5, shared)
interaction-touch-fill (6).../interaction-touch-fill.test.ts (4; +1 dispatch-and-record)interactions-ref-frame-evidence.test.ts (off-screen and invalid bounds), interactions-target-promotion.test.ts (editable node)
interaction-touch-runtime (7).../interaction-touch-runtime.test.ts (3)interactions-ref-frame-evidence.test.ts (5, shared); the missing-rect refusal is already pinned by ref-target-resolution.test.ts
interaction-touch-response (6).../interaction-touch-response-evidence.test.ts (6)digest/changed-from-before stays in interactions.test.ts
interaction-touch-payload (7).../interaction-touch-payload.test.ts (7)none
interaction-touch-prepare (5).../interaction-touch-prepare.test.ts (5)none
interaction-touch-android-freshness (4).../interaction-touch-android-freshness.test.ts (4)none
interaction-touch-android-readiness (7).../interaction-touch-android-readiness.test.ts (7)none
root interaction-touch-android-readiness-spawns (1).../interaction-touch-android-readiness-spawns.test.ts (1; real createAndroidObservationAdapter over a counting runAdb host port: six dumpsys calls for three taps)none
interaction-touch-direct-ios-eligibility (4).../interaction-touch-direct-ios-eligibility.test.ts (4)none
interaction-touch-direct-ios (6).../interaction-touch-direct-ios.test.ts (6, incl. the maestro-direct disclosure row loop)none
interaction-ios-tap-outcome (22).../interaction-ios-tap-outcome.test.ts (22)none
interaction-gesture-drag (2).../interaction-gesture-drag.test.ts (2)drag endpoint disclosure already pinned by gestures.test.ts
interaction-get (16)execution/selector-runtime-get-reads.test.ts (9), execution/selector-runtime-is-reads.test.ts (5)selector-is-visibility.test.ts (2), selector-read-disambiguation.test.ts (1)

127 tests before; 131 after (the added ones are the fill dispatch-and-record case, the disambiguation case, and splits). The interaction-touch.test.ts original was deleted with its package copy (12 = 12); nothing was dropped without a named owner.

Selection

All destinations match packages/*/src/**/*.test.ts or src/**/*.test.ts, so unit-core selects them (pnpm test:unit, test:coverage); the sources were already in unit-core. check:affected --run runs the vitest related leg over them.

vi.mock (each reads what its mock provided or recorded)

  • interaction-touch-android-readiness.test.ts, platform-android/mechanics: the mocked getAndroidAppState result is read by "tap likely escaped the app", "foregrounded com.android.settings" and the permission-dialog warning.
  • same file, ../../android-system-dialog.ts: its spy drives "a ref action aborts with the shared ref_frame_expired rejection after Android dialog recovery mutates" (details.reason === 'ref_frame_expired', mockTapPoint not called).
  • interaction-touch-payload.test.ts, platform-android/mechanics: getAndroidScreenSize is read by toHaveBeenCalledTimes(1), not.toHaveBeenCalled() and the 1344Ɨ2992 reference-size assertions.
  • interaction-touch-android-freshness.test.ts, platform-android/mechanics: a benign default that keeps the readiness check from spawning adb; the response.ok assertions depend on it. No assertion reads its recordings.
  • selector-runtime-is-reads.test.ts, platform-android/mechanics: mockGetAndroidAppState is read by the permission-dialog blocker test (foregroundPackage in details).
  • selector-runtime-get-reads.test.ts, platform-apple/runner/operations: a negative guard. expect(mockRunAppleRunnerCommand).not.toHaveBeenCalled() and the querySelector not.toHaveBeenCalledWith fail if the daemon starts reaching the runner for a get again, instead of silently running it. It passes today because the daemon no longer queries the runner.

Subpath exports

PackageBefore (#3670)After
daemon8581

Deleted: __tests__/ios-comparison-key-fixture, __tests__/replay-runtime/replay-command-fixture, interaction/internal/interaction-ios-tap-outcome, interaction/internal/interaction-touch-android-readiness. No other package changed; no new subpath, barrel or export *.

Notes

  • The touch fake's target resolution is a deliberate minimum (points resolve to themselves; a @ref is the centre of its node in refFrameSnapshot/snapshot; a selector is the first matching node of one fresh capture; preresolvedTarget is honored). It has no promotion, occlusion, off-screen, bounds, label-recovery or verify-evidence logic. Those are asserted as (c) tests against the real runtime, so its default answers do not stand in for command behavior.
  • Real-surface composition legs removed from the daemon tests are covered by test/integration/interaction-contract/* and provider-scenarios/press-selector-resolution.test.ts; I have not confirmed those assert the same cases one for one.
  • One-line path repoints for registries that named moved tests: packages/contracts/src/dispatch-disclosure.fixtures.ts (maestro-direct. owner) and packages/test-kit/src/boundary-fault-matrix.ts.
  • (c) tests are additive files in src/commands/interaction/runtime/, outside packages/daemon; say if any belongs to another worker.

Validation

check:quick, check:layering, check:fallow and check:gate-manifest pass on this head; check:affected --run passes (including test-file-size-ratchet and the eager-closure suite).

šŸ¤– Generated with Claude Code