Skip to content

Commit 1abd81b

Browse files
author
DavidQ
committed
done
1 parent 44132af commit 1abd81b

6 files changed

Lines changed: 387 additions & 12 deletions

File tree

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# PR_26128_011 Playwright Preview Generator Session Repo Load
2+
3+
## Command
4+
`npm run test:workspace-v2`
5+
6+
## Result
7+
PASS: 13/13 tests passed.
8+
9+
## Targeted Coverage
10+
- Workspace Manager V2 repo selection writes `workspace.repo.reference`.
11+
- Preview Generator V2 workspace launch reads `workspace.repo.reference`.
12+
- Preview Generator V2 workspace launch reads `workspace.tools.preview-generator-v2.state`.
13+
- Preview Generator V2 hides independent repo selection during workspace launch.
14+
- Generate Image is enabled after valid workspace manifest, repo reference, tool state, and preview source hydration.
15+
- Generate Image remains disabled when `workspace.repo.reference` is missing.
16+
- Generate Image remains disabled when repo session data is invalid.
17+
- Asteroids workspace launch generates a real SVG preview and records it through the session-backed repo handle.
18+
- Gravity Well and Pong workspace launches also resolve repo context from session storage and enable Generate Image.
19+
20+
## Skipped
21+
Full samples smoke test was skipped as requested because this PR changes Workspace Manager V2 to Preview Generator V2 session hydration. The targeted workspace suite covers the affected cross-tool launch path without exercising unrelated samples.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# PR_26128_011 Preview Generator Session Repo Load
2+
3+
## Summary
4+
Preview Generator V2 now resolves Workspace Manager V2 repo/game context from session storage during workspace launch instead of requiring a second repo picker action.
5+
6+
## Changes
7+
- Preview Generator V2 reads `workspace.repo.reference` from `sessionStorage`.
8+
- Preview Generator V2 reads its per-tool launch state from `workspace.tools.preview-generator-v2.state`.
9+
- Generate Image remains disabled until:
10+
- the workspace manifest from `hostContextId` is valid,
11+
- `workspace.repo.reference` is present and valid,
12+
- `workspace.tools.preview-generator-v2.state` matches the active game context,
13+
- the manifest preview source validates.
14+
- Workspace launches set the base URL to the current origin so generation can run without manual Preview Generator repo setup.
15+
- A session-backed repo handle is created from the validated session reference for Preview Generator V2 writes.
16+
- Missing or invalid repo session data logs visible actionable failures and keeps Generate Image disabled.
17+
18+
## Integration Boundary
19+
- No direct cross-tool communication was added.
20+
- No hidden fallback repo picker behavior was added.
21+
- Session storage remains the integration boundary.
22+
- The repo reference is validated before Preview Generator V2 enables generation.
23+
24+
## Validation
25+
- `npm run test:workspace-v2`: PASS, 13 tests passed.
26+
- Verified `workspace.repo.reference` is present after Workspace Manager V2 repo selection.
27+
- Verified Preview Generator V2 reads repo context from session storage.
28+
- Verified Preview Generator V2 does not require independent repo selection on workspace launch.
29+
- Verified Generate Image remains disabled for missing/invalid repo session state.
30+
- Verified Generate Image enables after valid repo/game session hydration.
31+
- Verified an Asteroids preview image is generated from workspace launch and written through the session-backed repo handle.
32+
33+
## Skipped
34+
Full samples smoke test was skipped as requested. This PR is scoped to Workspace Manager V2 to Preview Generator V2 session repo hydration; the targeted Workspace Manager V2 suite exercises the affected launch, hydration, failure, and generation paths.

tests/playwright/tools/WorkspaceManagerV2.spec.mjs

Lines changed: 71 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -865,7 +865,7 @@ test.describe("Workspace Manager V2 bootstrap", () => {
865865
await expect(page.locator('[data-launch-mode-nav="workspace"]')).toBeVisible();
866866
await expect(page.locator('[data-launch-mode-nav="workspace"] button')).toHaveText(["Generate Image", "Return to Workspace"]);
867867
await expect(page.locator("#executeBtn")).toBeVisible();
868-
await expect(page.locator("#executeBtn")).toBeDisabled();
868+
await expect(page.locator("#executeBtn")).toBeEnabled();
869869
await expect(page.locator("#repoSelectedValue")).toHaveText("HTML-JavaScript-Gaming");
870870
await expect(page.locator("#pickRepoBtn")).toBeHidden();
871871
await expect(page.locator("#workspaceContextValue")).toHaveCount(0);
@@ -875,6 +875,7 @@ test.describe("Workspace Manager V2 bootstrap", () => {
875875
await expect(page.locator('label[for="targetTypeSamples"]')).toBeHidden();
876876
await expect(page.locator('label[for="targetTypeTools"]')).toBeHidden();
877877
await expect(page.locator("#assetFolder")).toHaveValue("assets/images");
878+
await expect(page.locator("#baseUrl")).toHaveValue(server.baseUrl);
878879
await expect(page.locator("#sampleList")).toHaveValue("Asteroids");
879880
await expect(page.locator("#previewTargetValue")).toHaveText("games/Asteroids/assets/images/preview.svg");
880881
await expect(page.locator("#lastGeneratedImagePreview")).toBeVisible();
@@ -883,7 +884,9 @@ test.describe("Workspace Manager V2 bootstrap", () => {
883884
await expect(page.locator("#log")).toContainText("Raw workspace launch path field manifest.repoRoot: HTML-JavaScript-Gaming");
884885
await expect(page.locator("#log")).toContainText("OK Workspace launch context hydrated for Asteroids.");
885886
await expect(page.locator("#log")).toContainText("Workspace repoRoot display label available: HTML-JavaScript-Gaming.");
886-
await expect(page.locator("#log")).toContainText("Workspace launch is display-only; preview writes require normal Preview Generator repo selection.");
887+
await expect(page.locator("#log")).toContainText("OK Workspace repo session reference loaded from workspace.repo.reference for HTML-JavaScript-Gaming.");
888+
await expect(page.locator("#log")).toContainText("OK Workspace tool session state loaded from workspace.tools.preview-generator-v2.state.");
889+
await expect(page.locator("#log")).toContainText("Workspace launch repo context resolved from session storage; independent repo selection is not required.");
887890
await expect(page.locator("#log")).not.toContainText("Direct preview write");
888891
await expect(page.locator("#log")).not.toContainText("Resolved repoPath");
889892
await expect(page.locator("#log")).not.toContainText("absolute preview output path");
@@ -901,8 +904,18 @@ test.describe("Workspace Manager V2 bootstrap", () => {
901904
await expect(page.locator("#log")).toContainText("OK Workspace manifest preview source is valid at games/Asteroids/assets/images/preview.png.");
902905
const previewStatusHeaderOrder = await page.locator(".preview-generator-v2__status-accordion-header").evaluate((header) => Array.from(header.querySelectorAll(":scope > span, :scope > div > span, :scope > div > button"), (element) => element.textContent.trim()));
903906
expect(previewStatusHeaderOrder).toEqual(["Status", "+", "Clear"]);
904-
await page.locator("#baseUrl").fill(server.baseUrl);
905-
await expect(page.locator("#executeBtn")).toBeDisabled();
907+
await page.locator("#executeBtn").click();
908+
await expect(page.locator("#log")).toContainText("Starting execution...", { timeout: 20000 });
909+
await expect(page.locator("#log")).toContainText("RUN Asteroids", { timeout: 20000 });
910+
await expect(page.locator("#log")).toContainText("OUT games\\Asteroids\\assets\\images\\preview.svg", { timeout: 20000 });
911+
await expect(page.locator("#log")).toContainText("OK Asteroids", { timeout: 20000 });
912+
await expect(page.locator("#log")).toContainText("Done.", { timeout: 20000 });
913+
await expect(page.locator("#lastGeneratedImageMeta")).toHaveText("Last generated: Asteroids");
914+
const previewWrites = await page.evaluate(() => JSON.parse(sessionStorage.getItem("workspace.repo.writes") || "[]"));
915+
expect(previewWrites).toHaveLength(1);
916+
expect(previewWrites[0].path).toBe("HTML-JavaScript-Gaming/games/Asteroids/assets/images/preview.svg");
917+
expect(previewWrites[0].contents).toContain("<svg");
918+
expect(previewWrites[0].contents).not.toContain("Capture timeout");
906919
await page.locator("#returnToWorkspaceButton").click();
907920
await expect(page).toHaveURL(/workspace-manager-v2\/index\.html\?hostContextId=workspace-manager-v2-/);
908921
expect(pageErrors).toEqual([]);
@@ -952,7 +965,7 @@ test.describe("Workspace Manager V2 bootstrap", () => {
952965
}
953966
});
954967

955-
test("opens Preview Generator V2 workspace launch with display-only repoRoot and actionable status", async ({ page }) => {
968+
test("opens Preview Generator V2 workspace launch with actionable missing repo session status", async ({ page }) => {
956969
const server = await startRepoServer();
957970
const pageErrors = [];
958971
const hostContextId = "workspace-manager-v2-display-root-context";
@@ -980,7 +993,8 @@ test.describe("Workspace Manager V2 bootstrap", () => {
980993
await expect(page.locator("#log")).toContainText("Raw workspace launch path field manifest.repoRoot: HTML-JavaScript-Gaming");
981994
await expect(page.locator("#log")).toContainText("OK Workspace launch context hydrated for Asteroids.");
982995
await expect(page.locator("#log")).toContainText("Workspace repoRoot display label available: HTML-JavaScript-Gaming.");
983-
await expect(page.locator("#log")).toContainText("Workspace launch is display-only; preview writes require normal Preview Generator repo selection.");
996+
await expect(page.locator("#log")).toContainText("FAIL Workspace repo session hydration: workspace.repo.reference was not found in sessionStorage.");
997+
await expect(page.locator("#log")).toContainText("Preview Generator V2 requires Workspace Manager V2 repo session storage before image generation.");
984998
await expect(page.locator("#log")).not.toContainText("repoPath");
985999
await expect(page.locator("#log")).not.toContainText("Direct preview write");
9861000
await expect(page.locator("#log")).not.toContainText("/__workspace-manager-v2/repo-root");
@@ -993,6 +1007,51 @@ test.describe("Workspace Manager V2 bootstrap", () => {
9931007
}
9941008
});
9951009

1010+
test("keeps Preview Generator V2 disabled for invalid workspace repo session state", async ({ page }) => {
1011+
const server = await startRepoServer();
1012+
const pageErrors = [];
1013+
const hostContextId = "workspace-manager-v2-invalid-repo-reference-context";
1014+
const gameManifest = JSON.parse(await readFile("games/Asteroids/game.manifest.json", "utf8"));
1015+
const manifest = gameManifest.game.workspace;
1016+
manifest.repoRoot = "HTML-JavaScript-Gaming";
1017+
1018+
page.on("pageerror", (error) => {
1019+
pageErrors.push(error.message);
1020+
});
1021+
1022+
await page.addInitScript(({ contextId, workspaceManifest }) => {
1023+
window.sessionStorage.setItem(contextId, JSON.stringify(workspaceManifest));
1024+
window.sessionStorage.setItem("workspace.repo.reference", JSON.stringify({
1025+
source: "workspace-manager-v2",
1026+
kind: "file-system-directory-handle-reference",
1027+
displayName: "WrongRepo",
1028+
handleName: "WrongRepo"
1029+
}));
1030+
window.sessionStorage.setItem("workspace.tools.preview-generator-v2.state", JSON.stringify({
1031+
source: "workspace-manager-v2",
1032+
toolId: "preview-generator-v2",
1033+
gameId: workspaceManifest.gameId,
1034+
gameRoot: workspaceManifest.gameRoot,
1035+
assetsPath: workspaceManifest.assetsPath,
1036+
repoReferenceKey: "workspace.repo.reference"
1037+
}));
1038+
}, { contextId: hostContextId, workspaceManifest: manifest });
1039+
await coverageReporter.start(page);
1040+
await page.goto(`${server.baseUrl}/tools/preview-generator-v2/index.html?launch=workspace&fromTool=workspace-manager-v2&hostContextId=${hostContextId}`, { waitUntil: "networkidle" });
1041+
1042+
try {
1043+
await expect(page.locator("#pickRepoBtn")).toBeHidden();
1044+
await expect(page.locator("#executeBtn")).toBeDisabled();
1045+
await expect(page.locator("#repoSelectedValue")).toHaveText("HTML-JavaScript-Gaming");
1046+
await expect(page.locator("#log")).toContainText("FAIL Workspace repo session hydration: workspace.repo.reference.displayName WrongRepo does not match manifest repoRoot HTML-JavaScript-Gaming.");
1047+
await expect(page.locator("#log")).toContainText("Preview Generator V2 requires Workspace Manager V2 repo session storage before image generation.");
1048+
expect(pageErrors).toEqual([]);
1049+
} finally {
1050+
await coverageReporter.stop(page);
1051+
await server.close();
1052+
}
1053+
});
1054+
9961055
test("loads Gravity Well and Pong manifests as current Workspace Manager V2 manifests", async ({ page }) => {
9971056
const server = await openWorkspaceManagerV2(page);
9981057
const pageErrors = [];
@@ -1057,8 +1116,9 @@ test.describe("Workspace Manager V2 bootstrap", () => {
10571116
await expect(page.locator("#pickRepoBtn")).toBeHidden();
10581117
await expect(page.locator("#sampleList")).toHaveValue("GravityWell");
10591118
await expect(page.locator("#previewTargetValue")).toHaveText("games/GravityWell/assets/images/preview.svg");
1060-
await expect(page.locator("#executeBtn")).toBeDisabled();
1061-
await expect(page.locator("#log")).toContainText("Workspace launch is display-only; preview writes require normal Preview Generator repo selection.");
1119+
await expect(page.locator("#executeBtn")).toBeEnabled();
1120+
await expect(page.locator("#log")).toContainText("OK Workspace repo session reference loaded from workspace.repo.reference for HTML-JavaScript-Gaming.");
1121+
await expect(page.locator("#log")).toContainText("Workspace launch repo context resolved from session storage; independent repo selection is not required.");
10621122
await expect(page.locator("#log")).toContainText("Generated preview target: games/GravityWell/assets/images/preview.svg");
10631123
await page.locator("#returnToWorkspaceButton").click();
10641124
await expect(page).toHaveURL(/workspace-manager-v2\/index\.html\?hostContextId=workspace-manager-v2-/);
@@ -1092,8 +1152,9 @@ test.describe("Workspace Manager V2 bootstrap", () => {
10921152
await expect(page.locator("#pickRepoBtn")).toBeHidden();
10931153
await expect(page.locator("#sampleList")).toHaveValue("Pong");
10941154
await expect(page.locator("#previewTargetValue")).toHaveText("games/Pong/assets/images/preview.svg");
1095-
await expect(page.locator("#executeBtn")).toBeDisabled();
1096-
await expect(page.locator("#log")).toContainText("Workspace launch is display-only; preview writes require normal Preview Generator repo selection.");
1155+
await expect(page.locator("#executeBtn")).toBeEnabled();
1156+
await expect(page.locator("#log")).toContainText("OK Workspace repo session reference loaded from workspace.repo.reference for HTML-JavaScript-Gaming.");
1157+
await expect(page.locator("#log")).toContainText("Workspace launch repo context resolved from session storage; independent repo selection is not required.");
10971158
await expect(page.locator("#log")).toContainText("Generated preview target: games/Pong/assets/images/preview.svg");
10981159
await page.locator("#returnToWorkspaceButton").click();
10991160
await expect(page).toHaveURL(/workspace-manager-v2\/index\.html\?hostContextId=workspace-manager-v2-/);

0 commit comments

Comments
 (0)