Skip to content

Commit cb736fc

Browse files
author
DavidQ
committed
Rename Session Inspector V2 State view to Tool Data and clarify JSON meaning - PR_26128_020-session-inspector-v2-tool-data-label
1 parent 08df526 commit cb736fc

9 files changed

Lines changed: 117 additions & 49 deletions

File tree

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Playwright Session Inspector V2 State View
2+
3+
## Command
4+
`npm run test:workspace-v2`
5+
6+
## Result
7+
- Passed: 15/15
8+
- Runtime: about 1.3 minutes
9+
10+
## Targeted Coverage
11+
- Session Inspector V2 has no Schema section/control label.
12+
- State section/control is present.
13+
- JSON shows the selected storage entry's full stored object.
14+
- State shows only the selected normalized tool object's `state` section.
15+
- State shows an actionable empty-state message when no `state` section exists.
16+
- JSON and State accordions open and close predictably.
17+
- Controls, Filters, Entries, and Status accordions continue to open and close.
18+
- Workspace Manager V2 hydration remains normalized to `workspace.tools.<tool-id>`.
19+
- Old split `.schema` and `.state` per-tool keys are not recreated.
20+
21+
## Skipped
22+
- Full samples smoke test was skipped by request. The changed behavior is covered by `tests/playwright/tools/WorkspaceManagerV2.spec.mjs`.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Session Inspector V2 State View
2+
3+
## Scope
4+
- Removed the Session Inspector V2 Schema section/control.
5+
- Removed Session Inspector V2 user-facing Schema labels.
6+
- Added a State section/control.
7+
- Preserved the JSON section as the full selected storage object view.
8+
- Preserved normalized Workspace Manager V2 tool hydration keys:
9+
- `workspace.tools.<tool-id>`
10+
- Did not recreate split `.schema` or `.state` per-tool session keys.
11+
12+
## Implementation Notes
13+
- `StateControl` renders only the selected normalized tool object's top-level `state` section.
14+
- When a selected entry has no top-level `state`, State shows an actionable empty state naming the selected storage entry.
15+
- JSON still renders the full stored value for the selected tile.
16+
- JSON and State accordions use the existing Session Inspector V2 accordion pattern and were validated alongside Controls, Filters, Entries, and Status.
17+
- Per-tile Delete and Delete All behavior were preserved.
18+
19+
## Guardrails
20+
- No cross-tool communication was added.
21+
- Preview Generator V2 image generation behavior was not modified.
22+
- Sample JSON was not modified.
23+
- Roadmap content was not modified.
24+
25+
## Validation
26+
- Passed `npm run test:workspace-v2` with 15/15 tests.
27+
- Verified no Session Inspector V2 Schema control/label remains.
28+
- Verified State control appears.
29+
- Verified State shows only selected item `state`.
30+
- Verified JSON shows the full selected item object.
31+
- Verified JSON and State accordions open and close predictably.
32+
- Verified Controls, Filters, Entries, and Status accordions still work.
33+
- Verified normalized `workspace.tools.<tool-id>` keys remain.
34+
- Verified old split `.schema` and `.state` tool keys are not recreated.
35+
36+
## Skipped
37+
- Full samples smoke test was skipped because this PR is limited to the Session Inspector V2 JSON/State view and normalized Workspace V2 session-key validation. The requested targeted Workspace V2 Playwright suite covers the affected behavior.

tests/playwright/tools/WorkspaceManagerV2.spec.mjs

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,10 @@ test.describe("Workspace Manager V2 bootstrap", () => {
431431
await expect(page.locator(".session-inspector-v2__json-accordion-header")).toContainText("JSON");
432432
await expect(page.locator(".session-inspector-v2__json-accordion-header")).not.toContainText("Details");
433433
await expect(page.locator(".session-inspector-v2__json-accordion-header #copySessionInspectorV2JsonButton")).toHaveText("Copy");
434-
await expect(page.locator(".session-inspector-v2__schema-accordion-header")).toContainText("Schema");
434+
await expect(page.locator(".session-inspector-v2__state-accordion-header")).toContainText("State");
435+
await expect(page.locator(".session-inspector-v2__schema-accordion-header")).toHaveCount(0);
436+
await expect(page.locator("#sessionInspectorV2SchemaOutput")).toHaveCount(0);
437+
await expect(page.locator("body")).not.toContainText("Schema");
435438
expect(await page.locator(".session-inspector-v2__panel--left > .accordion-v2 > .accordion-v2__header > span:first-child").evaluateAll((labels) => labels.map((label) => label.textContent.trim()))).toEqual([
436439
"Controls",
437440
"Filters"
@@ -563,7 +566,7 @@ test.describe("Workspace Manager V2 bootstrap", () => {
563566
"sessionInspectorV2FiltersContent",
564567
"sessionInspectorV2EntriesContent",
565568
"sessionInspectorV2JsonContent",
566-
"sessionInspectorV2SchemaContent",
569+
"sessionInspectorV2StateContent",
567570
"sessionInspectorV2StatusContent"
568571
]) {
569572
await expectSessionInspectorV2AccordionToggles(page, contentId);
@@ -620,7 +623,7 @@ test.describe("Workspace Manager V2 bootstrap", () => {
620623

621624
await page.locator('[data-session-inspector-v2-entry-id="sessionStorage:session-inspector-v2-alpha"]').click();
622625
await expect(page.locator("#sessionInspectorV2JsonOutput")).toHaveText("true");
623-
await expect(page.locator("#sessionInspectorV2SchemaOutput")).toContainText("No schema section is present for sessionStorage:session-inspector-v2-alpha.");
626+
await expect(page.locator("#sessionInspectorV2StateOutput")).toContainText("No state section is present for sessionStorage:session-inspector-v2-alpha.");
624627
const copiedJsonText = await page.locator("#sessionInspectorV2JsonOutput").textContent();
625628
await page.locator("#copySessionInspectorV2JsonButton").click();
626629
await expect(page.locator("#statusLog")).toHaveValue(/OK Copied JSON content to clipboard\./);
@@ -651,7 +654,7 @@ test.describe("Workspace Manager V2 bootstrap", () => {
651654
await expect(page.locator("#sessionInspectorV2EntryList [data-session-inspector-v2-entry-id]")).toHaveCount(0);
652655
await expect(page.locator("#sessionInspectorV2EntryList")).toContainText("No matching storage entries.");
653656
await expect(page.locator("#sessionInspectorV2JsonOutput")).toHaveText("{}");
654-
await expect(page.locator("#sessionInspectorV2SchemaOutput")).toHaveText("Select a storage entry with a top-level schema section.");
657+
await expect(page.locator("#sessionInspectorV2StateOutput")).toHaveText("Select a normalized tool entry with a top-level state section.");
655658
await expect(page.locator("#sessionInspectorV2Summary > span")).toHaveText([
656659
"(0) Entries shown.",
657660
"(0) SessionStorage.",
@@ -678,7 +681,7 @@ test.describe("Workspace Manager V2 bootstrap", () => {
678681
}
679682
});
680683

681-
test("shows normalized workspace tool sessions as JSON and Schema views", async ({ page }) => {
684+
test("shows normalized workspace tool sessions as JSON and State views", async ({ page }) => {
682685
const pageErrors = [];
683686
await page.addInitScript(() => {
684687
window.sessionStorage.setItem("workspace.tools.preview-generator-v2", JSON.stringify({
@@ -711,10 +714,12 @@ test.describe("Workspace Manager V2 bootstrap", () => {
711714
payload: { assets: {} }
712715
}
713716
}));
714-
window.sessionStorage.setItem("workspace.tools.no-schema-test", JSON.stringify({
715-
state: {
717+
window.sessionStorage.setItem("workspace.tools.no-state-test", JSON.stringify({
718+
schema: {
716719
source: "workspace-manager-v2",
717-
toolId: "no-schema-test"
720+
toolId: "no-state-test",
721+
schemaRole: "workspace-launch-context",
722+
schemaRef: "tools/schemas/workspace.manifest.schema.json"
718723
}
719724
}));
720725
});
@@ -727,7 +732,10 @@ test.describe("Workspace Manager V2 bootstrap", () => {
727732
try {
728733
await expect(page.locator("#sessionInspectorV2EntryList [data-session-inspector-v2-entry-id]")).toHaveCount(3);
729734
await expect(page.locator(".session-inspector-v2__json-accordion-header")).toContainText("JSON");
730-
await expect(page.locator(".session-inspector-v2__schema-accordion-header")).toContainText("Schema");
735+
await expect(page.locator(".session-inspector-v2__state-accordion-header")).toContainText("State");
736+
await expect(page.locator(".session-inspector-v2__schema-accordion-header")).toHaveCount(0);
737+
await expect(page.locator("#sessionInspectorV2SchemaOutput")).toHaveCount(0);
738+
await expect(page.locator("body")).not.toContainText("Schema");
731739
await expect(page.locator("#sessionInspectorV2EntryList [data-session-inspector-v2-entry-id='sessionStorage:workspace.tools.preview-generator-v2']")).toHaveCount(1);
732740
await expect(page.locator("#sessionInspectorV2EntryList [data-session-inspector-v2-entry-id='sessionStorage:workspace.tools.preview-generator-v2.schema']")).toHaveCount(0);
733741
await expect(page.locator("#sessionInspectorV2EntryList [data-session-inspector-v2-entry-id='sessionStorage:workspace.tools.preview-generator-v2.state']")).toHaveCount(0);
@@ -736,12 +744,13 @@ test.describe("Workspace Manager V2 bootstrap", () => {
736744
await expect(page.locator("#sessionInspectorV2JsonOutput")).toContainText('"schema"');
737745
await expect(page.locator("#sessionInspectorV2JsonOutput")).toContainText('"state"');
738746
await expect(page.locator("#sessionInspectorV2JsonOutput")).toContainText('"repoReferenceKey": "workspace.repo.reference"');
739-
await expect(page.locator("#sessionInspectorV2SchemaOutput")).toContainText('"schemaRef": "tools/schemas/workspace.manifest.schema.json"');
740-
await expect(page.locator("#sessionInspectorV2SchemaOutput")).not.toContainText('"state"');
741-
await expect(page.locator("#sessionInspectorV2SchemaOutput")).not.toContainText('"repoReferenceKey"');
747+
await expect(page.locator("#sessionInspectorV2StateOutput")).toContainText('"repoReferenceKey": "workspace.repo.reference"');
748+
await expect(page.locator("#sessionInspectorV2StateOutput")).toContainText('"gameRoot": "games/Asteroids/"');
749+
await expect(page.locator("#sessionInspectorV2StateOutput")).not.toContainText('"schema"');
750+
await expect(page.locator("#sessionInspectorV2StateOutput")).not.toContainText('"schemaRef"');
742751

743-
await page.locator('[data-session-inspector-v2-entry-id="sessionStorage:workspace.tools.no-schema-test"]').click();
744-
await expect(page.locator("#sessionInspectorV2SchemaOutput")).toContainText("No schema section is present for sessionStorage:workspace.tools.no-schema-test.");
752+
await page.locator('[data-session-inspector-v2-entry-id="sessionStorage:workspace.tools.no-state-test"]').click();
753+
await expect(page.locator("#sessionInspectorV2StateOutput")).toContainText("No state section is present for sessionStorage:workspace.tools.no-state-test.");
745754

746755
await page.locator('[data-session-inspector-v2-delete-entry-id="sessionStorage:workspace.tools.preview-generator-v2"]').click();
747756
await expect(page.locator("#sessionInspectorV2EntryList [data-session-inspector-v2-entry-id]")).toHaveCount(2);

tools/session-inspector-v2/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ Session Inspector V2 is a first-class tool for inspecting and clearing current-o
1313
- Seed a storage key in the current origin.
1414
- Refresh the tool and verify the key appears in the Entries list.
1515
- Select an entry and confirm the JSON panel shows the full stored value.
16-
- Select a normalized workspace tool entry and confirm the Schema panel shows only its schema section.
16+
- Select a normalized workspace tool entry and confirm the State panel shows only its state section.
1717
- Use per-entry Delete or Delete All and verify the Entries list and status log update immediately.

tools/session-inspector-v2/index.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ <h2 class="tools-platform-frame__eyebrow">Session storage visibility</h2>
9595
</section>
9696
</section>
9797

98-
<aside class="session-inspector-v2__panel session-inspector-v2__panel--right tool-shell-common__fullscreen-panel tool-shell-common__fullscreen-side-panel tool-shell-common__fullscreen-panel-right" aria-label="Session JSON and schema">
98+
<aside class="session-inspector-v2__panel session-inspector-v2__panel--right tool-shell-common__fullscreen-panel tool-shell-common__fullscreen-side-panel tool-shell-common__fullscreen-panel-right" aria-label="Session JSON and state">
9999
<section class="accordion-v2 session-inspector-v2__accordion session-inspector-v2__accordion--fill is-open" data-accordion-v2-open="true">
100100
<div class="accordion-v2__header session-inspector-v2__json-accordion-header" role="button" tabindex="0" aria-expanded="true" aria-controls="sessionInspectorV2JsonContent">
101101
<span>JSON</span>
@@ -110,12 +110,12 @@ <h2 class="tools-platform-frame__eyebrow">Session storage visibility</h2>
110110
</section>
111111

112112
<section class="accordion-v2 session-inspector-v2__accordion session-inspector-v2__accordion--fill is-open" data-accordion-v2-open="true">
113-
<div class="accordion-v2__header session-inspector-v2__schema-accordion-header" role="button" tabindex="0" aria-expanded="true" aria-controls="sessionInspectorV2SchemaContent">
114-
<span>Schema</span>
113+
<div class="accordion-v2__header session-inspector-v2__state-accordion-header" role="button" tabindex="0" aria-expanded="true" aria-controls="sessionInspectorV2StateContent">
114+
<span>State</span>
115115
<span class="accordion-v2__icon" aria-hidden="true">+</span>
116116
</div>
117-
<div id="sessionInspectorV2SchemaContent" class="accordion-v2__content">
118-
<pre id="sessionInspectorV2SchemaOutput" class="session-inspector-v2__output">Select a storage entry with a top-level schema section.</pre>
117+
<div id="sessionInspectorV2StateContent" class="accordion-v2__content">
118+
<pre id="sessionInspectorV2StateOutput" class="session-inspector-v2__output">Select a normalized tool entry with a top-level state section.</pre>
119119
</div>
120120
</section>
121121

tools/session-inspector-v2/js/SessionInspectorV2App.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export class SessionInspectorV2App {
99
refreshButton,
1010
returnToWorkspaceButton,
1111
runtimeContract,
12-
schema,
12+
state,
1313
statusLog,
1414
storageService,
1515
windowRef = window
@@ -24,7 +24,7 @@ export class SessionInspectorV2App {
2424
this.refreshButton = refreshButton;
2525
this.returnToWorkspaceButton = returnToWorkspaceButton;
2626
this.runtimeContract = runtimeContract || { storageAccess: "read-only" };
27-
this.schema = schema;
27+
this.state = state;
2828
this.statusLog = statusLog;
2929
this.storageService = storageService;
3030
this.selectedId = "";
@@ -66,7 +66,7 @@ export class SessionInspectorV2App {
6666
this.entryList.render(this.entries, this.selectedId);
6767
const selectedEntry = this.entries.find((entry) => entry.id === this.selectedId);
6868
this.json.render(selectedEntry);
69-
this.schema.render(selectedEntry);
69+
this.state.render(selectedEntry);
7070
this.filters.setSummary(this.summaryCounts());
7171
if (!silent) {
7272
this.statusLog.ok(`Loaded ${this.entries.length} matching storage entries.`);
@@ -85,7 +85,7 @@ export class SessionInspectorV2App {
8585
this.entryList.render(this.entries, this.selectedId);
8686
const entry = this.entries.find((candidate) => candidate.id === entryId);
8787
this.json.render(entry);
88-
this.schema.render(entry);
88+
this.state.render(entry);
8989
if (entry) {
9090
this.statusLog.info(`Selected ${entry.storageType}:${entry.key}.`);
9191
}

tools/session-inspector-v2/js/bootstrap.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { AccordionSection } from "./controls/AccordionSection.js";
33
import { EntryListControl } from "./controls/EntryListControl.js";
44
import { FilterControl } from "./controls/FilterControl.js";
55
import { JsonControl } from "./controls/JsonControl.js";
6-
import { SchemaControl } from "./controls/SchemaControl.js";
6+
import { StateControl } from "./controls/StateControl.js";
77
import { StatusLogControl } from "./controls/StatusLogControl.js";
88
import { sessionInspectorV2RuntimeContract } from "./services/SessionInspectorV2RuntimeContract.js";
99
import { SessionInspectorV2StorageService } from "./services/SessionInspectorV2StorageService.js";
@@ -35,8 +35,8 @@ window.addEventListener("DOMContentLoaded", () => {
3535
refreshButton: requireElement("#refreshSessionInspectorV2Button"),
3636
returnToWorkspaceButton: requireElement("#returnToWorkspaceButton"),
3737
runtimeContract: sessionInspectorV2RuntimeContract(),
38-
schema: new SchemaControl({
39-
output: requireElement("#sessionInspectorV2SchemaOutput")
38+
state: new StateControl({
39+
output: requireElement("#sessionInspectorV2StateOutput")
4040
}),
4141
statusLog: new StatusLogControl({
4242
clearButton: requireElement("#clearSessionInspectorV2StatusButton"),

tools/session-inspector-v2/js/controls/SchemaControl.js

Lines changed: 0 additions & 22 deletions
This file was deleted.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
export class StateControl {
2+
constructor({ output }) {
3+
this.output = output;
4+
}
5+
6+
clear() {
7+
this.output.textContent = "Select a normalized tool entry with a top-level state section.";
8+
}
9+
10+
render(entry) {
11+
if (!entry) {
12+
this.clear();
13+
return;
14+
}
15+
const value = entry.parseOk ? entry.parsedValue : null;
16+
if (!value || typeof value !== "object" || Array.isArray(value) || !Object.prototype.hasOwnProperty.call(value, "state")) {
17+
this.output.textContent = `No state section is present for ${entry.storageType}:${entry.key}. Select a normalized tool entry with a top-level state section.`;
18+
return;
19+
}
20+
this.output.textContent = JSON.stringify(value.state, null, 2);
21+
}
22+
}

0 commit comments

Comments
 (0)