From 978f60ed6cd759358c28660e12c5092e3b5ce1ba Mon Sep 17 00:00:00 2001 From: Byntham <135178921+Byntham@users.noreply.github.com> Date: Thu, 5 Nov 2026 02:02:43 -0800 Subject: [PATCH] Show the expected character for a wrong key A wrong key now shows the character the prompt expects, still in red. A wrong key in place of a space shows a dot. Extra keys past the end of the prompt still show what was typed. Co-Authored-By: Claude Opus 5.5 --- src/components/chat/ChatComposer.tsx | 3 ++- tests/play.mjs | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/components/chat/ChatComposer.tsx b/src/components/chat/ChatComposer.tsx index 2356e1d..df40ecf 100644 --- a/src/components/chat/ChatComposer.tsx +++ b/src/components/chat/ChatComposer.tsx @@ -77,13 +77,14 @@ function GhostEditor({ draft, target, locked }: { draft: string; target: string; > {typed.map((ch, index) => { const ok = goal[index] === ch; + const shown = goal[index] ?? ch; return ( - {ch === " " && !ok ? "·" : ch} + {shown === " " && !ok ? "·" : shown} ); })} diff --git a/tests/play.mjs b/tests/play.mjs index 23ccd99..82e17e4 100644 --- a/tests/play.mjs +++ b/tests/play.mjs @@ -264,8 +264,28 @@ async function checkWordsStayPutWhileTyping(browser) { await page.close(); } +async function checkWrongKeysShowExpectedText(browser) { + const { page, errors } = await openPage(browser, "dark", "speed=4&seed=1"); + const text = activeOf(await state(page)).def.prompts[0].text; + const space = text.indexOf(" "); + const wrong = (ch) => (ch === "q" ? "z" : "q"); + const typed = text.slice(0, 2) + wrong(text[2]) + text.slice(3, space) + "x" + text.slice(space + 1, space + 4); + await page.keyboard.type(typed); + await page.screenshot({ path: join(shots, "dark-wrong-keys.png") }); + const spans = await page + .locator('[data-testid="composer-editor"] [data-typed]') + .evaluateAll((els) => els.map((el) => ({ text: el.textContent, typed: el.dataset.typed }))); + const bad = spans.map((s, i) => (s.typed === "bad" ? i : -1)).filter((i) => i >= 0); + check(bad.join(",") === `2,${space}`, `wrong keys are marked at 2 and ${space} (got ${bad.join(",")})`); + check(spans[2]?.text === text[2], `a wrong letter shows the expected "${text[2]}" (got "${spans[2]?.text}")`); + check(spans[space]?.text === "\u00b7", `a key typed in place of a space shows a dot (got "${spans[space]?.text}")`); + check(errors.length === 0, `no console errors in wrong key run${errors.length ? `: ${errors.join(" | ")}` : ""}`); + await page.close(); +} + const browser = await chromium.launch(); try { + await checkWrongKeysShowExpectedText(browser); await checkWordsStayPutWhileTyping(browser); await playFullSessionInDark(browser); await checkAutoSettle(browser);