From 57f2041d1b615cfbb84f25e5af5044c32f5fe2d9 Mon Sep 17 00:00:00 2001 From: DavidQ Date: Mon, 22 Jun 2026 21:29:16 -0400 Subject: [PATCH] PR_26174_ALFA_018-game-selection-button-state --- assets/theme-v2/css/tables.css | 7 +- ...74_ALFA_018-game-selection-button-state.md | 26 +++++++ ...lection-button-state_branch-validation.txt | 14 ++++ ...n-button-state_manual-validation-notes.txt | 10 +++ ...ion-button-state_requirement-checklist.txt | 13 ++++ ...selection-button-state_validation-lane.txt | 11 +++ .../dev/reports/codex_changed_files.txt | 12 ++-- docs_build/dev/reports/codex_review.diff | Bin 34398 -> 19930 bytes .../tools/GameHubMockRepository.spec.mjs | 68 +++++++++++++----- toolbox/game-hub/game-hub.js | 10 --- 10 files changed, 135 insertions(+), 36 deletions(-) create mode 100644 docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state.md create mode 100644 docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state_branch-validation.txt create mode 100644 docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state_manual-validation-notes.txt create mode 100644 docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state_requirement-checklist.txt create mode 100644 docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state_validation-lane.txt diff --git a/assets/theme-v2/css/tables.css b/assets/theme-v2/css/tables.css index 8289fd805..ae4dc414e 100644 --- a/assets/theme-v2/css/tables.css +++ b/assets/theme-v2/css/tables.css @@ -115,9 +115,10 @@ td { cursor: pointer } -.data-table [data-game-active-cell="true"] { - box-shadow: inset var(--space-3) 0 0 var(--gold); - border-bottom-color: var(--gold-border-muted) +.data-table [data-game-toggle][aria-current="true"] { + border-color: var(--gold); + background: color-mix(in srgb, var(--gold) 18%, var(--panel-soft)); + box-shadow: inset 0 0 0 1px var(--gold-border-muted) } .idea-board-idea-label { diff --git a/docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state.md b/docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state.md new file mode 100644 index 000000000..cb4c0d692 --- /dev/null +++ b/docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state.md @@ -0,0 +1,26 @@ +# PR_26174_ALFA_018-game-selection-button-state + +## Summary + +Moved Game Hub selected-game indication to the game button only. + +## Implementation + +- Removed active-game markers from parent rows. +- Removed active-game markers from parent table cells. +- Replaced the left-border cell highlight with selected styling on the game button. +- Removed the `Selected {game}.` status log update when selecting a game row. +- Preserved child row behavior so Source Idea and Readiness Output follow the selected game. +- Added targeted Playwright assertions for one selected button, unchanged sibling columns, child row movement, and no selected status copy. + +## Scope Control + +- Preserved the existing API/service contract. +- Preserved the Game row parent structure. +- Preserved Source Idea and Readiness Output child rows/tables. +- Did not add browser-owned product data. +- Did not introduce silent fallbacks. + +## ZIP + +- `tmp/PR_26174_ALFA_018-game-selection-button-state_delta.zip` diff --git a/docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state_branch-validation.txt b/docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state_branch-validation.txt new file mode 100644 index 000000000..b3d79a161 --- /dev/null +++ b/docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state_branch-validation.txt @@ -0,0 +1,14 @@ +Branch validation: PASS + +Branch: +pr/26174-ALFA-018-game-selection-button-state + +Base stack branch: +pr/26174-ALFA-017-game-hub-guest-save-and-crew-cleanup + +Checks: +- Current branch is the ALFA_018 branch: PASS +- Worktree was clean before ALFA_018 edits: PASS +- Scope limited to Game Hub selection state, targeted Playwright coverage, and required reports: PASS +- No protected Project Instructions changes: PASS +- No merge to main performed: PASS diff --git a/docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state_manual-validation-notes.txt b/docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state_manual-validation-notes.txt new file mode 100644 index 000000000..85f5d6781 --- /dev/null +++ b/docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state_manual-validation-notes.txt @@ -0,0 +1,10 @@ +Manual validation notes: PASS + +- Reviewed `docs_build/dev/ProjectInstructions/addendums/table_first_ui.md`. +- Confirmed selected state remains on the game button through `aria-current`. +- Confirmed parent rows no longer receive active attributes. +- Confirmed cells no longer receive active markers. +- Confirmed the old left-border cell selector was removed. +- Confirmed selecting another game leaves only one selected game button. +- Confirmed Source Idea and Readiness Output child rows move with the selected game. +- Confirmed the bottom status area no longer receives `Selected {game}.` when a game row is selected. diff --git a/docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state_requirement-checklist.txt b/docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state_requirement-checklist.txt new file mode 100644 index 000000000..43fd997cb --- /dev/null +++ b/docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state_requirement-checklist.txt @@ -0,0 +1,13 @@ +Requirement checklist: PASS + +- Selected game is indicated only by the Game button: PASS +- Row-level selection indicators removed: PASS +- Left border highlight removed: PASS +- Row background highlight removed: PASS +- Cell background highlights removed: PASS +- Purpose, Status, and Actions columns remain visually identical for all rows: PASS +- Only one game may be selected at a time: PASS +- Selecting a different game moves selected styling to that game button: PASS +- Child rows continue to follow the selected game: PASS +- Follow table_first_ui.md: PASS +- Removed selected-game status copy from bottom status area: PASS diff --git a/docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state_validation-lane.txt b/docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state_validation-lane.txt new file mode 100644 index 000000000..edd65a9f8 --- /dev/null +++ b/docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state_validation-lane.txt @@ -0,0 +1,11 @@ +Validation lane: PASS + +Commands: +- `git diff --check -- toolbox/game-hub/game-hub.js assets/theme-v2/css/tables.css tests/playwright/tools/GameHubMockRepository.spec.mjs` + - PASS +- `node --check toolbox/game-hub/game-hub.js` + - PASS +- `npx playwright test tests/playwright/tools/GameHubMockRepository.spec.mjs -g "Game Hub"` + - PASS, 11 passed + +Generated coverage reports were restored after Playwright validation to keep this PR scoped. diff --git a/docs_build/dev/reports/codex_changed_files.txt b/docs_build/dev/reports/codex_changed_files.txt index f7be6c46d..6ae3f1e60 100644 --- a/docs_build/dev/reports/codex_changed_files.txt +++ b/docs_build/dev/reports/codex_changed_files.txt @@ -1,10 +1,10 @@ -docs_build/dev/reports/PR_26174_ALFA_017-game-hub-guest-save-and-crew-cleanup.md -docs_build/dev/reports/PR_26174_ALFA_017-game-hub-guest-save-and-crew-cleanup_branch-validation.txt -docs_build/dev/reports/PR_26174_ALFA_017-game-hub-guest-save-and-crew-cleanup_manual-validation-notes.txt -docs_build/dev/reports/PR_26174_ALFA_017-game-hub-guest-save-and-crew-cleanup_requirement-checklist.txt -docs_build/dev/reports/PR_26174_ALFA_017-game-hub-guest-save-and-crew-cleanup_validation-lane.txt +assets/theme-v2/css/tables.css +docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state.md +docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state_branch-validation.txt +docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state_manual-validation-notes.txt +docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state_requirement-checklist.txt +docs_build/dev/reports/PR_26174_ALFA_018-game-selection-button-state_validation-lane.txt docs_build/dev/reports/codex_changed_files.txt docs_build/dev/reports/codex_review.diff tests/playwright/tools/GameHubMockRepository.spec.mjs toolbox/game-hub/game-hub.js -toolbox/game-hub/index.html diff --git a/docs_build/dev/reports/codex_review.diff b/docs_build/dev/reports/codex_review.diff index 882ec504bd38b66fedc5a565d72cc27566817418..55044b9665e01bb102bba56ca24fe01822a9e1b6 100644 GIT binary patch literal 19930 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 b^z}9}FECmSpUBoLmhT}s59MbzJ*)o$HCC@T literal 34398 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 X-RKxFmS { const demoGameRow = page.locator("[data-game-row='demo-game']"); await expect(demoGameRow.locator("td")).toHaveText(["Game", "Under Construction", "Edit"]); await expect(demoGameRow).not.toContainText("User 1"); - await expect(demoGameRow).toHaveAttribute("data-game-active", "true"); - await expect(demoGameRow).toHaveAttribute("aria-current", "true"); - await expect(demoGameRow.locator("th[data-game-active-cell='true']")).toContainText("Demo Game"); - const activeCellStyle = await demoGameRow.locator("th[data-game-active-cell='true']").evaluate((cell) => { - const styles = getComputedStyle(cell); - return { - backgroundColor: styles.backgroundColor, - boxShadow: styles.boxShadow, - }; - }); - const inactiveCellBackground = await page.locator("[data-game-row='gravity-demo'] th").evaluate((cell) => getComputedStyle(cell).backgroundColor); - expect(activeCellStyle.backgroundColor).toBe(inactiveCellBackground); - expect(activeCellStyle.boxShadow).not.toBe("none"); + await expect(demoGameRow).not.toHaveAttribute("data-game-active", "true"); + await expect(demoGameRow).not.toHaveAttribute("aria-current", "true"); + await expect(demoGameRow.locator("th[data-game-active-cell='true']")).toHaveCount(0); + await expect(page.locator("[data-game-row][data-game-active='true']")).toHaveCount(0); + await expect(page.locator("[data-game-row][aria-current='true']")).toHaveCount(0); + await expect(page.locator("[data-game-active-cell='true']")).toHaveCount(0); + const rowVisuals = await page.locator("[data-game-row]").evaluateAll((rows) => rows.map((row) => { + const cells = Array.from(row.children).slice(1); + return cells.map((cell) => { + const styles = getComputedStyle(cell); + return { + backgroundColor: styles.backgroundColor, + boxShadow: styles.boxShadow, + }; + }); + })); + expect(rowVisuals[0]).toEqual(rowVisuals[1]); await expect(demoGameRow.locator("> .status")).toHaveCount(0); await expect(demoGameRow.locator("[data-game-toggle='demo-game']")).toHaveAttribute("aria-expanded", "false"); await expect(demoGameRow.locator("[data-game-toggle='demo-game']")).not.toHaveClass(/primary/); await expect(demoGameRow.locator("[data-game-toggle='demo-game']")).toHaveClass(/\bbtn--compact\b/); + await expect(demoGameRow.locator("[data-game-toggle='demo-game']")).toHaveAttribute("data-game-active", "true"); await expect(demoGameRow.locator("[data-game-toggle='demo-game']")).toHaveAttribute("aria-current", "true"); + await expect(page.locator("[data-game-toggle][aria-current='true']")).toHaveCount(1); + await expect(page.locator("[data-game-toggle][data-game-active='true']")).toHaveCount(1); + const activeButtonStyle = await demoGameRow.locator("[data-game-toggle='demo-game']").evaluate((button) => { + const styles = getComputedStyle(button); + return { + backgroundColor: styles.backgroundColor, + borderColor: styles.borderColor, + boxShadow: styles.boxShadow, + }; + }); + const inactiveButtonStyle = await page.locator("[data-game-row='gravity-demo'] [data-game-toggle='gravity-demo']").evaluate((button) => { + const styles = getComputedStyle(button); + return { + backgroundColor: styles.backgroundColor, + borderColor: styles.borderColor, + boxShadow: styles.boxShadow, + }; + }); + expect(activeButtonStyle).not.toEqual(inactiveButtonStyle); await expect(demoGameRow.getByRole("button", { name: "Edit Demo Game" })).toHaveText("Edit"); await expect(demoGameRow.getByRole("button", { name: "Edit Demo Game" })).not.toHaveClass(/primary/); await expect(demoGameRow.getByRole("button", { name: "Edit Demo Game" })).toHaveClass(/\bbtn--compact\b/); @@ -348,7 +372,10 @@ test("Game Hub creates, opens, and deletes mock games", async ({ page }) => { await addGameRow.getByLabel("Status").selectOption("Ready for Testing"); await addGameRow.getByRole("button", { name: "Save" }).click(); await expect(page.locator("[data-game-list]")).toContainText("Launch Test Game"); - await expect(page.locator("[data-game-row='launch-test-game-1']")).toHaveAttribute("data-game-active", "true"); + await expect(page.locator("[data-game-row='launch-test-game-1']")).not.toHaveAttribute("data-game-active", "true"); + await expect(page.locator("[data-game-row='launch-test-game-1']")).not.toHaveAttribute("aria-current", "true"); + await expect(page.locator("[data-game-toggle][aria-current='true']")).toHaveCount(1); + await expect(page.locator("[data-game-row='launch-test-game-1'] [data-game-toggle='launch-test-game-1']")).toHaveAttribute("aria-current", "true"); await expect(page.locator("[data-game-row='launch-test-game-1'] [data-game-toggle='launch-test-game-1']")).not.toHaveClass(/primary/); await expect(page.locator("[data-game-row='launch-test-game-1']").getByRole("button", { name: "Edit Launch Test Game" })).not.toHaveClass(/primary/); await expect(page.locator("[data-game-row='launch-test-game-1'] td").nth(0)).toHaveText("Learning Game"); @@ -376,14 +403,21 @@ test("Game Hub creates, opens, and deletes mock games", async ({ page }) => { await page.getByRole("button", { name: "Add Game" }).click(); await page.locator("[data-game-add-row='input']").getByLabel("Game").fill("Archive Game"); await page.locator("[data-game-add-row='input']").getByRole("button", { name: "Save" }).click(); - await expect(page.locator("[data-game-row='archive-game-2']")).toHaveAttribute("data-game-active", "true"); + await expect(page.locator("[data-game-row='archive-game-2']")).not.toHaveAttribute("data-game-active", "true"); + await expect(page.locator("[data-game-row='archive-game-2'] [data-game-toggle='archive-game-2']")).toHaveAttribute("aria-current", "true"); await expect(page.locator("[data-game-row='archive-game-2'] [data-game-toggle='archive-game-2']")).not.toHaveClass(/primary/); await page.locator("[data-game-row='launch-test-game-1'] [data-game-toggle='launch-test-game-1']").click(); - await expect(page.locator("[data-game-row='launch-test-game-1']")).toHaveAttribute("data-game-active", "true"); + await expect(page.locator("[data-game-row='launch-test-game-1']")).not.toHaveAttribute("data-game-active", "true"); + await expect(page.locator("[data-game-row='launch-test-game-1'] [data-game-toggle='launch-test-game-1']")).toHaveAttribute("aria-current", "true"); + await expect(page.locator("[data-game-row='archive-game-2'] [data-game-toggle='archive-game-2']")).not.toHaveAttribute("aria-current", "true"); + await expect(page.locator("[data-game-toggle][aria-current='true']")).toHaveCount(1); + await expect(page.locator("[data-game-toggle][data-game-active='true']")).toHaveCount(1); + await expect(page.locator("[data-game-expanded-row='launch-test-game-1']")).toHaveCount(2); + await expect(page.locator("[data-game-expanded-row='archive-game-2']")).toHaveCount(0); await expect(page.locator("[data-game-row='launch-test-game-1'] [data-game-toggle='launch-test-game-1']")).not.toHaveClass(/primary/); await expect(page.locator("[data-game-row='launch-test-game-1']").getByRole("button", { name: "Edit Launch Test Game" })).not.toHaveClass(/primary/); - await expect(page.locator("[data-game-hub-log]")).toHaveText("Selected Launch Test Game."); + await expect(page.locator("[data-game-hub-log]")).not.toHaveText("Selected Launch Test Game."); await page.getByRole("button", { name: "Delete Open Game" }).click(); await expect(page.locator("[data-game-row='launch-test-game-1']")).toHaveCount(0); diff --git a/toolbox/game-hub/game-hub.js b/toolbox/game-hub/game-hub.js index e4659f47b..a79c9d7d8 100644 --- a/toolbox/game-hub/game-hub.js +++ b/toolbox/game-hub/game-hub.js @@ -482,16 +482,9 @@ function renderGameParentRow(tbody, game, activeGame, progress) { const row = document.createElement("tr"); row.dataset.gameRow = game.id; - if (active) { - row.dataset.gameActive = "true"; - row.setAttribute("aria-current", "true"); - } const nameCell = document.createElement("th"); nameCell.scope = "row"; - if (active) { - nameCell.dataset.gameActiveCell = "true"; - } nameCell.append(createGameToggleButton(game, expanded, active)); row.append( nameCell, @@ -731,9 +724,6 @@ elements.gameList?.addEventListener("click", (event) => { renderWorkspace(); return; } - if (game) { - setStatusLog(`Selected ${game.name}.`); - } state.expandedGameId = state.expandedGameId === toggle.dataset.gameToggle ? "" : toggle.dataset.gameToggle; renderWorkspace(); return;