Skip to content

test(e2e): a US keyboard in the CDP harness never types «ї» - #45

Merged
prodelt merged 1 commit into
integrate/post-submissionfrom
fix/race-layout-notice-flake
Oct 6, 2026
Merged

prodelt merged 1 commit into
integrate/post-submissionfrom
fix/race-layout-notice-flake

Conversation

@prodelt

@prodelt prodelt commented Oct 6, 2026

Copy link
Copy Markdown
Owner

Fixes the flaky e2e/race-real.spec.ts:107 «a Ukrainian race with the system on US explains itself, and clears when the layout is right» (failed both tries on run 37419553245 attempt 1, commit 2f59e69).

Root cause (test harness, not the product)

The real-key CDP harness (e2e/harness/realType.ts) looks up what the active layout prints on a physical key in the curriculum's QWERTY. That layout lists only the keys an English exercise uses, so it has no BracketLeft, BracketRight, Backslash or Slash. For those keys the harness fell back to the intended character. So «ї» pressed "on US" reached the page as «ї», not «]».

«ї» is a ЙЦУКЕН letter, and nextForeignStreak correctly resets on it: the six keys of «Київ с» arrived as R b ї d ␠ c, a streak of 2, never FOREIGN_STREAK (3), so race-layout-notice never appeared. A real US layout prints «]» there, and the product warns as it should.

It looked flaky because private rooms pick their text with order by random() from four Ukrainian texts, and only «Київ стоїть…» has х/ї/ґ in its first six characters. That makes it 1 try in 4, and both tries 1 run in 16. Both failed tries drew that text.

Evidence from the trace: the line was data-live and focus was on the textarea. error-count went 1→6, one per key, in the same race-run node, so nothing re-mounted. The race-layout-slot stayed empty throughout, and there was no page error. Everything reached the engine, so the watch saw a ЙЦУКЕН letter that no US keyboard can produce.

Fix

  • realType.ts: the key mapping is now a pure keystrokeOf(char, active, intended). It knows what a real US layout prints on the four keys the curriculum leaves out ([ ] \ / and their shifted signs). On any other missing key it throws instead of typing a character the active layout cannot produce.
  • tools/real-keyboard.test.ts (regression, all three red before the fix):
    • no ЙЦУКЕН key pressed on US types a Cyrillic letter;
    • «Київ с» on US types R b ] d ␠ c;
    • those six keys reach FOREIGN_STREAK through the product's own nextForeignStreak.

I also checked all four seeded Ukrainian race texts against the fix: each stays under 3 foreign letters after 2 keys and reaches 3 or more by 6 keys, as the spec assumes. That check was a throwaway and is not committed.

Tests

  • pnpm check: typecheck, lint (one pre-existing !important warning in shell.css), 906 unit tests passed.
  • pnpm build: passes.
  • playwright test --project=cdp e2e/real-input.spec.ts (the other real-key spec, no backend; built with the Supabase env emptied): 2 passed.
  • race-real.spec.ts is @backend. Docker isn't running here, so it was not run locally; CI's "e2e against a local Supabase" job covers it.

🤖 Generated with Claude Code

race-real.spec.ts «a Ukrainian race with the system on US explains
itself» failed whenever the private room drew the «Київ стоїть…» text
(one of the four Ukrainian race texts, picked by `order by random()`):
1 try in 4, both tries 1 run in 16.

Cause: the real-key harness looks up what the active layout prints on a
physical key in the curriculum's QWERTY, which lists only the keys an
English exercise uses. It has no BracketLeft, BracketRight, Backslash or
Slash, and for those the harness fell back to the intended character. So
«ї» pressed "on US" arrived as «ї», not «]». «ї» is a ЙЦУКЕН letter, and
the race's foreign-letter watch rightly reset on it: R b ї d ␠ c is a
streak of 2, never FOREIGN_STREAK (3), so the notice never came. The
trace agrees: the engine counted all six keys (errors 1..6), the race
never re-mounted, focus held, no page error, the notice slot stayed
empty. The product is right: a real US layout prints «]» there.

Fix: the harness knows what a real US layout prints on the four keys the
curriculum leaves out, and throws on any other missing key instead of
typing a character the active layout cannot produce. The key mapping is
a pure `keystrokeOf`, pinned by tools/real-keyboard.test.ts: no ЙЦУКЕН
key pressed on US types a Cyrillic letter, «Київ с» types R b ] d ␠ c,
and those six keys reach FOREIGN_STREAK. All three failed before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 6, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated
typing-race Ready Ready Preview Oct 6, 2026 6:42am UTC

@prodelt
prodelt merged commit dc4ac8b into integrate/post-submission Oct 6, 2026
6 checks passed

This branch was successfully deployed

1 active deployment
Preview — dc4ac8bf Deployed Oct 6, 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