fix: the page menu must not claim a modified key (ChatGPT Codex, PR #123)

The menu's early return sat ABOVE `app.js`'s `metaKey` guard, so with the menu
open `Cmd-R` reached `menuKey`, was answered `ignore`, and was then defaulted
away by `if (!e.ctrlKey && !e.altKey) e.preventDefault()` — true for Meta.
Reload was blocked. `Ctrl-j`/`Alt-Home` had the mirror fault and MOVED the menu,
two lines below a comment saying Ctrl and Alt stay the browser's.

Ordering plus one bail: the `metaKey` guard goes back above the menu branch,
`pageMenuKeydown` returns on `ctrlKey || altKey`, and what remains claims
unconditionally — every unmodified key, `ignore` included, which is the rule the
menu exists to keep.

The harness assertion installs its `defaultPrevented` probe AFTER load so it
runs second and sees what the page decided, and ends on an unmodified `j`
asserting `["j", true]` — without which "nothing was prevented" is satisfied by
a page that claims nothing. Proved by restoring the reviewed code: it fails on
`Control+j` moving the active row.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FC2jVn8Au7E9JPkw6bwXXH
This commit is contained in:
Edward Langley
2026-09-21 23:36:43 -07:00
parent 0a920f1d54
commit 9156b48f12
3 changed files with 78 additions and 7 deletions
+38
View File
@@ -83,6 +83,44 @@ test.describe("a page axis can be picked from a menu", () => {
await expect(chip(page)).toHaveText(/Quarter = Q2 \(2\/4\)/);
});
// Found by ChatGPT Codex on PR #123: the menu branch sat ABOVE the page's
// `metaKey` guard, so Cmd-R was answered `ignore` and then defaulted away.
test("a modified key is the browser's, and the menu neither acts on it nor claims it", async ({
page,
}) => {
await theDemo(page);
// Registered AFTER `app.js`'s own window listener, so it runs second and
// reads what the page did — a listener added first would see `false` always.
await page.evaluate(() => {
window.__claimed = [];
window.addEventListener("keydown", (e) =>
window.__claimed.push([e.key, e.defaultPrevented]),
);
});
await chip(page).click();
await expect(menu(page)).toBeVisible();
await expect(menu(page).locator(".page-item.active")).toHaveText("✓ Q1");
// `Ctrl-j` is not `j`: it must not move the menu the way the bare key does.
await page.keyboard.press("Control+j");
await expect(menu(page).locator(".page-item.active")).toHaveText("✓ Q1");
await page.keyboard.press("Meta+r");
await expect(menu(page)).toBeVisible();
const claimed = await page.evaluate(() => window.__claimed);
expect(claimed, `nothing reached the handler: ${JSON.stringify(claimed)}`).not.toEqual([]);
for (const [key, prevented] of claimed) {
expect(prevented, `${key} was defaulted away; it is the browser's`).toBe(false);
}
// The precondition the rows above lean on: an UNMODIFIED key still is
// claimed, so "nothing was prevented" is a fact about the modifier.
await page.keyboard.press("j");
await expect(menu(page).locator(".page-item.active")).toHaveText(" Q2");
const after = await page.evaluate(() => window.__claimed.at(-1));
expect(after).toEqual(["j", true]);
});
test("Escape closes the menu and changes nothing", async ({ page }) => {
await theDemo(page);
await chip(page).click();