From 72348a8ca4e291122addebd787c60e546136b58e Mon Sep 17 00:00:00 2001 From: DavidQ Date: Sat, 20 Jun 2026 21:30:48 -0400 Subject: [PATCH] PR_26171_ALPHA_048 wire idea journey handoff --- .../dev/reports/codex_changed_files.txt | 155 ++++++------------ docs_build/dev/reports/codex_review.diff | Bin 121645 -> 52104 bytes .../APPLY_PR.md | 55 +++++++ .../BUILD_PR.md | 51 ++++++ .../PLAN_PR.md | 25 +++ .../playwright/tools/GameJourneyTool.spec.mjs | 2 +- .../tools/IdeaBoardTableNotes.spec.mjs | 18 +- toolbox/game-hub/index.html | 2 +- 8 files changed, 197 insertions(+), 111 deletions(-) create mode 100644 docs_build/pr/PR_26171_ALPHA_048-idea-project-journey-execution-flow/APPLY_PR.md create mode 100644 docs_build/pr/PR_26171_ALPHA_048-idea-project-journey-execution-flow/BUILD_PR.md create mode 100644 docs_build/pr/PR_26171_ALPHA_048-idea-project-journey-execution-flow/PLAN_PR.md diff --git a/docs_build/dev/reports/codex_changed_files.txt b/docs_build/dev/reports/codex_changed_files.txt index 60d4cdf24..af8e89c91 100644 --- a/docs_build/dev/reports/codex_changed_files.txt +++ b/docs_build/dev/reports/codex_changed_files.txt @@ -1,125 +1,64 @@ -PR_26171_ALPHA_047-game-hub-canonical-path-journey-handoff - -Git workflow: -- Current branch: pr/26171-ALPHA-047-game-hub-canonical-path-journey-handoff -- Created branch: pr/26171-ALPHA-047-game-hub-canonical-path-journey-handoff -- Push result: PASS; pushed to origin/pr/26171-ALPHA-047-game-hub-canonical-path-journey-handoff -- PR URL: https://github.com/ToolboxAid/HTML-JavaScript-Gaming/pull/32 -- Merge approval status: pending explicit Team Alpha owner approval -- Merge result: not performed; merge is blocked until explicit Team Alpha owner approval -- Rebase/conflict resolution: PASS; rebased onto origin/main at e8845dae6 after GitHub reported the branch was behind current main. Conflicts were limited to generated Codex report artifacts and reports were regenerated. -- Latest rebase/conflict resolution: PASS; rebased onto origin/main at 195c90a64 after PR_26171_BETA_075 landed. Conflicts were resolved in generated Codex report artifacts and tests/playwright/tools/RootToolsFutureState.spec.mjs; the test expectations now preserve current-main Text To Speech coverage and ALPHA_047 canonical game-hub route/filter behavior. -- Final approved rebase: PASS; Team Alpha approval granted for ALPHA_047, rebased onto origin/main at 1451a1173, with conflicts limited to generated Codex report artifacts. +PR_26171_ALPHA_048-idea-project-journey-execution-flow Instruction compliance: -- PASS: docs_build/dev/PROJECT_INSTRUCTIONS.md was read before file changes. -- PASS: docs_build/dev/PROJECT_MULTI_PC.txt was read before file changes. +- PASS: docs_build/dev/PROJECT_INSTRUCTIONS.md was read before implementation. +- PASS: docs_build/dev/PROJECT_MULTI_PC.txt was read before implementation. - PASS: BUILD_PR.md was created and read before implementation. -- PASS: Team Alpha owner scope applies to Game Hub, Game Journey handoff, and Idea Board continuity. +- PASS: Branch was created from clean main after ALPHA_047 was merged and main was pulled to a0da3ad30. +- PASS: PR TEAM owner applies to Idea Board, Game Hub, and Game Journey. - PASS: Full samples smoke was not run. +Git workflow: +- Current branch: pr/26171-ALPHA-048-idea-project-journey-execution-flow +- Created branch: pr/26171-ALPHA-048-idea-project-journey-execution-flow +- Clean status: PASS after final amendment +- Push result: PASS; pushed pr/26171-ALPHA-048-idea-project-journey-execution-flow to origin +- PR URL: https://github.com/ToolboxAid/HTML-JavaScript-Gaming/pull/41 +- Merge approval status: pending explicit Team Alpha owner approval; PR is open and mergeable +- Merge result: not performed; do not merge without explicit Team Alpha owner approval + Validation: -- PASS: node --check toolbox/game-hub/game-hub.js -- PASS: node --check toolbox/game-hub/game-hub-api-client.js -- PASS: node --check toolbox/idea-board/index.js -- PASS: node --check toolbox/game-journey/game-journey.js -- PASS: node --check src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js -- PASS: node --check src/dev-runtime/server/local-api-router.mjs -- PASS: node --check tests/playwright/tools/GameHubMockRepository.spec.mjs - PASS: node --check tests/playwright/tools/IdeaBoardTableNotes.spec.mjs - PASS: node --check tests/playwright/tools/GameJourneyTool.spec.mjs -- PASS: npx playwright test tests/playwright/tools/GameHubMockRepository.spec.mjs --project=playwright --workers=1 --reporter=line (11 passed) +- PASS: node --check toolbox/idea-board/index.js +- PASS: node --check toolbox/game-hub/game-hub.js +- PASS: node --check toolbox/game-journey/game-journey.js - PASS: npx playwright test tests/playwright/tools/IdeaBoardTableNotes.spec.mjs --project=playwright --workers=1 --reporter=line (2 passed) -- PASS: npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs --project=playwright --workers=1 --reporter=line --grep "Game Hub hands the active game route to Game Journey|Game Journey requires an active game" (2 passed) +- PASS: npx playwright test tests/playwright/tools/GameHubMockRepository.spec.mjs --project=playwright --workers=1 --reporter=line (11 passed) +- PASS: npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs --project=playwright --workers=1 --reporter=line --grep "Game Hub hands the active game route to Game Journey" (1 passed) - PASS: npm run test:workspace-v2 (5 passed) -- PASS: git diff --check (line-ending warnings only) -- PASS: Completion revalidation for PR_26171_ALPHA_048 start-gate blocker; ALPHA_047 scoped validation was rerun while still on branch pr/26171-ALPHA-047-game-hub-canonical-path-journey-handoff, and ALPHA_048 implementation was not started. -- PASS: Latest post-rebase validation after origin/main 195c90a64: syntax checks, targeted Game Hub Playwright, targeted Idea Board Playwright, targeted Game Journey handoff Playwright, and npm run test:workspace-v2. -- PASS: Final approved validation after origin/main 1451a1173: syntax checks, targeted Game Hub Playwright, targeted Idea Board Playwright, targeted Game Journey handoff Playwright, and npm run test:workspace-v2. Requirement-by-requirement evidence: -- PASS: Rename active path toolbox/game-workspace/ to toolbox/game-hub/. -- PASS: Rename active game-workspace.js to game-hub.js. -- PASS: Rename active game-workspace-api-client.js to game-hub-api-client.js. -- PASS: Deep-audit and update imports, variables, data attributes, tests, toolbox navigation/registry, tool display mode slug, page titles, and creator-facing labels to Game Hub. -- PASS: Do not leave active navigation pointing to toolbox/game-workspace; active route audit found no active legacy route. -- PASS: Do not create duplicate active Game Hub paths; registry reads filter stale game-workspace rows and active metadata points to game-hub. -- PASS: Idea Board Create Project creates/links a Game Hub project when a Ready idea becomes Project. -- PASS: Project ideas lock original Idea, Pitch, and Notes. -- PASS: Game Hub shows Source Idea/Pitch/Notes as read-only creator-facing content. -- PASS: Game Journey receives executable Journey items from Idea notes when the linked project opens. +- PASS: Ready Idea -> Create Project -> Game Hub -> Game Journey flow remains wired through the existing shared Game Hub project contract. +- PASS: Create Project appears only for Ready ideas; the targeted Idea Board test verifies the Ready row action sequence. +- PASS: Clicking Create Project creates or links a Game Hub project and sets the Idea status to Project. +- PASS: Project ideas lock original Idea, Pitch, and Notes as read-only; targeted Idea Board coverage verifies no Edit/Delete/Add Note/note actions after Project status. +- PASS: Project actions become Open in Game Hub and Archive. +- PASS: Game Hub displays read-only Source Idea, Pitch, and Notes for the linked project. +- PASS: Game Hub exposes the creator-facing action as Open Journey. +- PASS: Open Journey navigates to the related Game Journey project route. +- PASS: Game Journey receives an editable Journey item generated from the Idea note. +- PASS: Targeted Idea Board coverage edits the generated Journey item and confirms the Source Idea note remains unchanged. - PASS: Original Idea notes are not mutated or moved. -- PASS: Project/source-linked actions avoid Delete and use Open in Game Hub plus Archive. -- PASS: No real database migration was added; existing shared mock/server contracts are reused. -- PASS: Merge is not performed without explicit Team Alpha owner approval. +- PASS: No real database persistence or schema work was added. + +ZIP: +- Path: tmp/PR_26171_ALPHA_048-idea-project-journey-execution-flow_delta.zip +- Size: 191263 bytes +- Contents: + - docs_build/dev/reports/codex_changed_files.txt + - docs_build/dev/reports/codex_review.diff + - docs_build/pr/PR_26171_ALPHA_048-idea-project-journey-execution-flow/APPLY_PR.md + - docs_build/pr/PR_26171_ALPHA_048-idea-project-journey-execution-flow/BUILD_PR.md + - docs_build/pr/PR_26171_ALPHA_048-idea-project-journey-execution-flow/PLAN_PR.md + - tests/playwright/tools/GameJourneyTool.spec.mjs + - tests/playwright/tools/IdeaBoardTableNotes.spec.mjs + - toolbox/game-hub/index.html Changed files: -- deleted: assets/theme-v2/images/badges/game-workspace-1024.png -- deleted: assets/theme-v2/images/badges/game-workspace.png -- added: assets/theme-v2/images/badges/game-hub-1024.png -- added: assets/theme-v2/images/badges/game-hub.png -- deleted: assets/theme-v2/images/tools/game-workspace-1024.png -- deleted: assets/theme-v2/images/tools/game-workspace.png -- added: assets/theme-v2/images/tools/game-hub-1024.png -- added: assets/theme-v2/images/tools/game-hub.png -- updated: assets/theme-v2/js/account-achievements.js -- updated: assets/theme-v2/js/gamefoundry-partials.js -- updated: assets/theme-v2/partials/header-nav.html -- updated: docs_build/database/ddl/game-workspace.sql -- updated: docs_build/database/dml/DML_INDEX.md -- updated: docs_build/database/dml/game-workspace.sql -- updated: docs_build/database/seed/game-workspace.json -- updated: docs_build/database/seed/guest/game-workspace.json -- updated: docs_build/dev/admin-notes/deployment-uat-prod/index.txt -- added: docs_build/dev/reports/codex_changed_files.txt -- added: docs_build/dev/reports/codex_review.diff -- added: docs_build/pr/PR_26171_ALPHA_047-game-hub-canonical-path-journey-handoff/APPLY_PR.md -- added: docs_build/pr/PR_26171_ALPHA_047-game-hub-canonical-path-journey-handoff/BUILD_PR.md -- added: docs_build/pr/PR_26171_ALPHA_047-game-hub-canonical-path-journey-handoff/PLAN_PR.md -- deleted: learn/game-workspace/index.html -- added: learn/game-hub/index.html -- updated: learn/getting-started/index.html -- updated: learn/index.html -- updated: package.json -- updated: scripts/run-targeted-test-lanes.mjs -- updated: scripts/validate-browser-env-agnostic.mjs -- updated: scripts/validate-local-postgres-runtime.mjs -- updated: src/dev-runtime/admin/header-nav.local.html -- updated: src/dev-runtime/persistence/mock-db-store.js -- updated: src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js -- updated: src/dev-runtime/seed/server-seed-loader.mjs -- updated: src/dev-runtime/server/local-api-router.mjs -- updated: src/shared/toolbox/tool-metadata-inventory.js -- updated: tests/dev-runtime/DevRuntimeBoundary.test.mjs -- updated: tests/dev-runtime/ProductDataProviderContractHardening.test.mjs -- updated: tests/dev-runtime/SupabaseProductDataCutover.test.mjs -- updated: tests/playwright/account/AchievementsPage.spec.mjs -- updated: tests/playwright/tools/AdminDbViewer.spec.mjs -- added: tests/playwright/tools/GameHubMockRepository.spec.mjs +- added: docs_build/pr/PR_26171_ALPHA_048-idea-project-journey-execution-flow/APPLY_PR.md +- added: docs_build/pr/PR_26171_ALPHA_048-idea-project-journey-execution-flow/BUILD_PR.md +- added: docs_build/pr/PR_26171_ALPHA_048-idea-project-journey-execution-flow/PLAN_PR.md - updated: tests/playwright/tools/GameJourneyTool.spec.mjs -- deleted: tests/playwright/tools/GameWorkspaceMockRepository.spec.mjs - updated: tests/playwright/tools/IdeaBoardTableNotes.spec.mjs -- updated: tests/playwright/tools/RootToolsFutureState.spec.mjs -- updated: tests/playwright/tools/ToolDisplayModeNavigation.spec.mjs -- updated: tests/playwright/tools/ToolImageRegistry.spec.mjs -- updated: tests/playwright/tools/ToolNavigationPrevNext.spec.mjs -- updated: tests/playwright/tools/ToolboxRoutePages.spec.mjs -- updated: toolbox/colors/index.html -- updated: toolbox/controls/controls.js -- updated: toolbox/controls/index.html -- updated: toolbox/game-design/index.html -- added: toolbox/game-hub/game-hub-api-client.js -- added: toolbox/game-hub/game-hub.js -- added: toolbox/game-hub/index.html -- updated: toolbox/game-journey/game-journey.js -- deleted: toolbox/game-workspace/game-workspace-api-client.js -- deleted: toolbox/game-workspace/game-workspace.js -- deleted: toolbox/game-workspace/index.html -- updated: toolbox/idea-board/index.js -- updated: toolbox/project-workspace/index.html -- updated: toolbox/tools-page-accordions.js - -ZIP: -- Path: tmp/PR_26171_ALPHA_047-game-hub-canonical-path-journey-handoff_delta.zip -- Size: generated after branch push; final byte size is reported in the delivery response because the ZIP is not committed. -- Contents: repo-structured scoped delta files. Deleted legacy paths are documented in the changed-files list and are not represented as physical files in the archive. +- updated: toolbox/game-hub/index.html diff --git a/docs_build/dev/reports/codex_review.diff b/docs_build/dev/reports/codex_review.diff index 9b7b02d87c38e0041b5f02a836ea823b0b4e1d09..fe31ed50f8806294d46c9380ee897d028e20d17d 100644 GIT binary patch literal 52104 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 E|3(O4$p8QV diff --git a/docs_build/pr/PR_26171_ALPHA_048-idea-project-journey-execution-flow/APPLY_PR.md b/docs_build/pr/PR_26171_ALPHA_048-idea-project-journey-execution-flow/APPLY_PR.md new file mode 100644 index 000000000..8132731e8 --- /dev/null +++ b/docs_build/pr/PR_26171_ALPHA_048-idea-project-journey-execution-flow/APPLY_PR.md @@ -0,0 +1,55 @@ +# PR_26171_ALPHA_048-idea-project-journey-execution-flow APPLY + +## Git Workflow +- Current branch: `pr/26171-ALPHA-048-idea-project-journey-execution-flow` +- Created branch: `pr/26171-ALPHA-048-idea-project-journey-execution-flow` +- Push result: PASS; pushed `pr/26171-ALPHA-048-idea-project-journey-execution-flow` to origin. +- PR URL: https://github.com/ToolboxAid/HTML-JavaScript-Gaming/pull/41 +- Merge approval status: pending explicit Team Alpha owner approval; PR is open and mergeable. +- Merge result: not performed; do not merge without explicit Team Alpha owner approval. + +## Validation +- PASS: `node --check tests/playwright/tools/IdeaBoardTableNotes.spec.mjs` +- PASS: `node --check tests/playwright/tools/GameJourneyTool.spec.mjs` +- PASS: `node --check toolbox/idea-board/index.js` +- PASS: `node --check toolbox/game-hub/game-hub.js` +- PASS: `node --check toolbox/game-journey/game-journey.js` +- PASS: `npx playwright test tests/playwright/tools/IdeaBoardTableNotes.spec.mjs --project=playwright --workers=1 --reporter=line` (2 passed) +- PASS: `npx playwright test tests/playwright/tools/GameHubMockRepository.spec.mjs --project=playwright --workers=1 --reporter=line` (11 passed) +- PASS: `npx playwright test tests/playwright/tools/GameJourneyTool.spec.mjs --project=playwright --workers=1 --reporter=line --grep "Game Hub hands the active game route to Game Journey"` (1 passed) +- PASS: `npm run test:workspace-v2` (5 passed) + +## ZIP +- Path: `tmp/PR_26171_ALPHA_048-idea-project-journey-execution-flow_delta.zip` +- Size: 191263 bytes +- Contents: + - `docs_build/dev/reports/codex_changed_files.txt` + - `docs_build/dev/reports/codex_review.diff` + - `docs_build/pr/PR_26171_ALPHA_048-idea-project-journey-execution-flow/APPLY_PR.md` + - `docs_build/pr/PR_26171_ALPHA_048-idea-project-journey-execution-flow/BUILD_PR.md` + - `docs_build/pr/PR_26171_ALPHA_048-idea-project-journey-execution-flow/PLAN_PR.md` + - `tests/playwright/tools/GameJourneyTool.spec.mjs` + - `tests/playwright/tools/IdeaBoardTableNotes.spec.mjs` + - `toolbox/game-hub/index.html` + +## Requirement Evidence +- Instruction compliance: PASS; PROJECT_INSTRUCTIONS.md and PROJECT_MULTI_PC.txt were read before implementation. +- Team Alpha owner: PASS; scope is Idea, Game Hub, and Game Journey. +- Branch gate: PASS; branch was created from clean `main` after ALPHA_047 merged. +- PASS: Ready Idea -> Create Project -> Game Hub -> Game Journey flow remains wired through the existing shared Game Hub project contract. +- PASS: Create Project remains available only for Ready ideas; targeted Idea Board Playwright verifies Ready action state before creation. +- PASS: Clicking Create Project creates or links a Game Hub project, sets the idea to Project, locks the Idea/Pitch/Notes, and shows Open in Game Hub plus Archive. +- PASS: Game Hub displays read-only Source Idea, Pitch, and Notes for the linked project. +- PASS: Game Hub now exposes the creator action as `Open Journey`. +- PASS: Game Journey receives an editable item generated from the Idea note; targeted Idea Board Playwright edits the generated Journey item after handoff. +- PASS: Original Idea notes are not mutated or moved; targeted Idea Board Playwright confirms the Game Hub Source Idea note remains unchanged after editing the Journey item. +- PASS: No real database persistence or schema work was added. +- PASS: Full samples smoke was not run. + +## Changed Files +- added: `docs_build/pr/PR_26171_ALPHA_048-idea-project-journey-execution-flow/APPLY_PR.md` +- added: `docs_build/pr/PR_26171_ALPHA_048-idea-project-journey-execution-flow/BUILD_PR.md` +- added: `docs_build/pr/PR_26171_ALPHA_048-idea-project-journey-execution-flow/PLAN_PR.md` +- updated: `tests/playwright/tools/GameJourneyTool.spec.mjs` +- updated: `tests/playwright/tools/IdeaBoardTableNotes.spec.mjs` +- updated: `toolbox/game-hub/index.html` diff --git a/docs_build/pr/PR_26171_ALPHA_048-idea-project-journey-execution-flow/BUILD_PR.md b/docs_build/pr/PR_26171_ALPHA_048-idea-project-journey-execution-flow/BUILD_PR.md new file mode 100644 index 000000000..7938ec804 --- /dev/null +++ b/docs_build/pr/PR_26171_ALPHA_048-idea-project-journey-execution-flow/BUILD_PR.md @@ -0,0 +1,51 @@ +# PR_26171_ALPHA_048-idea-project-journey-execution-flow BUILD + +## Start Gate +- Read `docs_build/dev/PROJECT_INSTRUCTIONS.md`. +- Read `docs_build/dev/PROJECT_MULTI_PC.txt`. +- Confirm current branch is clean latest `main` before branch creation. +- Confirm Team Alpha owns Idea, Game Hub, and Game Journey work. +- Confirm `toolbox/game-hub/` exists on `main`. +- Confirm merge requires explicit Team Alpha owner approval. + +## Exact Targets +- `toolbox/idea-board/index.js` +- `toolbox/game-hub/game-hub.js` +- `toolbox/game-journey/game-journey.js` +- `src/dev-runtime/persistence/tool-repositories/game-journey-mock-repository.js` +- Targeted Playwright tests for Idea Board, Game Hub, and Game Journey flow +- `docs_build/dev/reports/codex_review.diff` +- `docs_build/dev/reports/codex_changed_files.txt` + +## Required Implementation +- Create Project appears only for Ready ideas. +- Clicking Create Project: + - creates or links a Game Hub project, + - sets Idea status to Project, + - locks original Idea, Pitch, and Notes as read-only, + - changes actions to Open in Game Hub and Archive, + - creates editable Game Journey Items from Idea Notes. +- Do not mutate or move original Idea Notes. +- Game Hub displays read-only Source Idea: + - Idea + - Pitch + - Notes +- Add Open Journey action from Game Hub where appropriate. +- Keep creator-facing production copy only. + +## Required Validation +- `node --check` for changed JS files. +- Targeted Idea Board Playwright. +- Targeted Game Hub Playwright. +- Targeted Game Journey Playwright. +- `npm run test:workspace-v2`. +- Do not run full samples smoke. + +## Required Delivery +- Update required reports. +- Produce repo-structured ZIP under `tmp/PR_26171_ALPHA_048-idea-project-journey-execution-flow_delta.zip`. +- Stage only scoped files. +- Commit. +- Push branch. +- Create PR. +- Stop before merge until explicit Team Alpha owner approval is present. diff --git a/docs_build/pr/PR_26171_ALPHA_048-idea-project-journey-execution-flow/PLAN_PR.md b/docs_build/pr/PR_26171_ALPHA_048-idea-project-journey-execution-flow/PLAN_PR.md new file mode 100644 index 000000000..cde8258b4 --- /dev/null +++ b/docs_build/pr/PR_26171_ALPHA_048-idea-project-journey-execution-flow/PLAN_PR.md @@ -0,0 +1,25 @@ +# PR_26171_ALPHA_048-idea-project-journey-execution-flow PLAN + +## Purpose +Wire the creator execution flow from a Ready Idea through Game Hub into editable Game Journey items. + +## Source of Truth +- `docs_build/dev/PROJECT_INSTRUCTIONS.md` +- `docs_build/dev/PROJECT_MULTI_PC.txt` + +## Team Ownership +- Team Alpha owns Idea, Game Hub, and Game Journey work. + +## Scope +- Ready Idea -> Create Project -> Game Hub -> Game Journey. +- Project and Archived Idea locking remains read-only for Idea, Pitch, and Notes. +- Game Hub displays Source Idea/Pitch/Notes read-only. +- Game Journey receives editable Journey Items generated from Idea Notes. +- Original Idea Notes are not mutated or moved. +- Add Open Journey action from Game Hub where appropriate. + +## Out of Scope +- Game Journey image wiring. +- Game Hub table polish unrelated to execution flow. +- Real database persistence or schema changes. +- Full samples smoke. diff --git a/tests/playwright/tools/GameJourneyTool.spec.mjs b/tests/playwright/tools/GameJourneyTool.spec.mjs index 429f6f381..7a0f87f53 100644 --- a/tests/playwright/tools/GameJourneyTool.spec.mjs +++ b/tests/playwright/tools/GameJourneyTool.spec.mjs @@ -1457,7 +1457,7 @@ test("Game Hub hands the active game route to Game Journey", async ({ page }) => const failures = await openRepoPage(page, "/toolbox/game-hub/index.html"); try { - const journeyLink = page.getByRole("link", { name: "Open Game Journey" }); + const journeyLink = page.getByRole("link", { name: "Open Journey" }); await expect(journeyLink).toHaveAttribute("href", /toolbox\/game-journey\/index\.html\?game=demo-game$/); await journeyLink.click(); await page.waitForURL(/toolbox\/game-journey\/index\.html\?game=demo-game$/); diff --git a/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs b/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs index 934faf46f..4eb6de548 100644 --- a/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs +++ b/tests/playwright/tools/IdeaBoardTableNotes.spec.mjs @@ -354,12 +354,28 @@ test("Idea Board uses accordion table ideas and notes", async ({ page }) => { await expect(page.locator("[data-source-idea-notes]")).toContainText("Use dusk tide changes as the first Game Hub planning note."); await expect(page.getByRole("button", { name: "Delete Open Game" })).toHaveCount(0); await expect(page.locator("main")).not.toContainText(/\bproject records\b|\bAPI\b|\bDB\b|\bmock\b|\bseed\b|\bdebug\b|\binternal\b/i); - await page.getByRole("link", { name: "Open Game Journey" }).click(); + const createdProjectUrl = page.url(); + await page.getByRole("link", { name: "Open Journey" }).click(); await page.waitForURL(/\/toolbox\/game-journey\/index\.html\?game=lantern-reef-\d+$/); await expect(page.locator("[data-journey-active-game]")).toHaveText("Active game: Lantern Reef."); await expect(page.locator("[data-journey-summary-body]")).toContainText("Source Idea: Lantern Reef"); await expect(page.locator("[data-journey-summary-body]")).toContainText("10000011"); await expect(page.locator("[data-journey-recent-activity]")).toContainText("Created 1 Game Journey item from Source Idea."); + await page.locator("[data-journey-note-button]", { hasText: "Source Idea: Lantern Reef" }).click(); + const generatedJourneyItem = page.locator("[data-journey-item-button]", { hasText: "Use dusk tide changes as the first Game Hub planning note." }).first(); + await expect(generatedJourneyItem).toBeVisible(); + await generatedJourneyItem.click(); + await expect(page.locator("[data-journey-editor-status]")).toContainText("User-created item"); + await expect(page.locator("[data-journey-title-input]")).toBeEnabled(); + await page.locator("[data-journey-title-input]").fill("Refine dusk tide puzzle loop"); + await page.locator("[data-journey-item-details-input]").fill("Keep this as an editable journey planning item."); + await page.getByLabel("Status").selectOption("in-progress"); + await page.getByRole("button", { name: "Update Item" }).click(); + await expect(page.locator("[data-journey-item-tree]")).toContainText("Refine dusk tide puzzle loop"); + await expect(page.locator("[data-journey-item-tree]")).toContainText("Keep this as an editable journey planning item."); + await page.goto(createdProjectUrl, { waitUntil: "networkidle" }); + await expect(page.locator("[data-source-idea-notes]")).toContainText("Use dusk tide changes as the first Game Hub planning note."); + await expect(page.locator("[data-source-idea-notes]")).not.toContainText("Refine dusk tide puzzle loop"); expect(mutatingApiRequests.some((request) => request.includes("/api/toolbox/game-hub/repositories"))).toBe(true); expect(mutatingApiRequests.some((request) => request.includes("/methods/createGame"))).toBe(true); diff --git a/toolbox/game-hub/index.html b/toolbox/game-hub/index.html index ef7b50004..347861b11 100644 --- a/toolbox/game-hub/index.html +++ b/toolbox/game-hub/index.html @@ -97,7 +97,7 @@

Game Hub