Skip to content

fix: make keyboard pipeline tests hermetic and assert NFC at scalar level - #14

Merged
jonaskahn merged 1 commit into
mainfrom
fix/ci-test-hermeticity
Oct 16, 2026
Merged

jonaskahn merged 1 commit into
mainfrom
fix/ci-test-hermeticity

Conversation

@jonaskahn

@jonaskahn jonaskahn commented Oct 16, 2026 •

Copy link
Copy Markdown
Owner

Why

CI (run 38877143025) has been red since #12 — the same 6 unit tests fail deterministically on GitHub-hosted runners while passing on a dev Mac. Only test (unit-2) and test (unit-4) fail the run; the ui-known-broken-on-hosted-runner shard is tolerated by design (continue-on-error).

Root causes

1. Non-hermetic KeyboardInputPipelineProcessTests (5 failures) — the tests never injected spotlightVisibilityProvider, so the default probed the real machine (SpotlightWindowDetector.isSpotlightWindowVisible). On hosted runners a Spotlight-owned window is on-screen, so currentCompatibilityRule() returned the Spotlight rule (.spotlightSelection): replacements went out as shift+left selection instead of backspaces, and the Chromium U+200B empty-character break after Space-commit was skipped. Exactly the two observed failure shapes. Fix: inject spotlightVisibilityProvider: { false } in every context-sensitive pipeline construction (Spotlight-behavior tests already inject their own).

2. Unsatisfiable assertion in VietnameseEngineEdgeCaseTests (1 failure) — XCTAssertNotEqual(text, text.precomposed…) compares Swift Strings, whose == is canonical-equivalence: NFD and NFC are always equal, so the "sample must actually be decomposed" precondition could never pass. Fix: compare unicodeScalars (the sample was in fact decomposed). The per-unit-NFC invariant and two wire-text NFC asserts in KeyboardInputPipelineProcessTests were vacuous for the same reason — hardened to scalar-level too.

UI test failures (investigated, no code change)

The 14 Onboarding/Settings failures are click-then-verify cases quarantined in ui-known-broken-on-hosted-runner since 97d1dba: hosted runners cannot make an AppKit window key (AX tree queryable, isHittable true, activation never lands), so clicks/sheets silently no-op. Deterministic, not flaky; not a regression (blocking shards ui-1…ui-5 are green on the same runs). The fix is infrastructure — a self-hosted runner with a real GUI session — per ci.yml:267-278 and docs/operations.md. No in-app change attempted.

Verification

  • The 6 previously-failing tests pass locally.
  • Full unit suite: 2060 tests, 0 failures.
  • This PR's CI: unit-2 and unit-4 green; ui-known-broken may still show its internal failures (expected, non-blocking).

…evel

KeyboardInputPipelineProcessTests drove KeyboardInputPipeline without
injecting spotlightVisibilityProvider, so the real Spotlight window
detector decided the context. On GitHub-hosted runners a Spotlight-owned
window is on-screen, which flipped the pipeline into Spotlight mode
(selection replacement, no Chromium empty-character break) and failed
five tests deterministically. Inject { false } in every context-sensitive
construction; Spotlight-behavior tests already inject their own provider.

VietnameseEngineEdgeCaseTests:640 compared NFD vs NFC with String ==,
which is canonical-equivalence — always equal, so the precondition could
never pass. Compare unicode scalars instead, and likewise harden the
per-unit-NFC invariant and the wire-text NFC asserts in
KeyboardInputPipelineProcessTests, which were vacuous for the same reason.
@jonaskahn
jonaskahn force-pushed the fix/ci-test-hermeticity branch from 39a0eb1 to 5e73ad6 Compare October 16, 2026 11:12
@jonaskahn
jonaskahn merged commit f810e6d into main Oct 16, 2026
12 checks passed
@jonaskahn
jonaskahn deleted the fix/ci-test-hermeticity branch October 16, 2026 11:14
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