Skip to content

Commit 65ecfab

Browse files
author
DavidQ
committed
Wrap Session Inspector V2 detail output text and match Status output height - PR_26128_025-session-inspector-v2-output-wrap-height
1 parent 35987fd commit 65ecfab

4 files changed

Lines changed: 92 additions & 24 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 Output Wrap Height
2+
3+
## Targeted Coverage
4+
- Verified JSON output wraps long lines without a horizontal scrollbar.
5+
- Verified Data output wraps long lines without a horizontal scrollbar.
6+
- Verified Dirty output wraps long lines without a horizontal scrollbar.
7+
- Verified JSON/Data/Dirty outputs keep vertical scrolling inside their `<pre>` elements.
8+
- Verified JSON/Data/Dirty output height matches the Status output height.
9+
- Verified Dirty and Status headers remain reachable when detail content overflows.
10+
- Verified Copy All and Clear Status behavior remains covered by existing Session Inspector V2 tests.
11+
12+
## Commands
13+
- `node --check tests/playwright/tools/WorkspaceManagerV2.spec.mjs`
14+
- `npx playwright test tests/playwright/tools/WorkspaceManagerV2.spec.mjs --project=playwright --workers=1 --reporter=list -g "shows normalized workspace tool sessions as JSON, Data, and Dirty views"`
15+
- `npm run test:workspace-v2`
16+
17+
## Result
18+
- Focused Playwright validation passed: 1 test.
19+
- Full workspace-v2 Playwright validation passed: 15 tests.
20+
21+
## Full Samples Smoke
22+
- Skipped per PR instructions because the requested change is restricted to Session Inspector V2 detail output wrapping/height behavior and the existing targeted Workspace Manager V2 suite validates the affected launch path.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# PR_26128_025 Session Inspector V2 Output Wrap Height
2+
3+
## Scope
4+
- Updated Session Inspector V2 detail output styling only.
5+
- Kept JSON, Data, and Dirty output scroll ownership on their own `<pre>` elements.
6+
- Preserved normalized session object shape and existing Copy All, Clear Status, and Dirty header behavior.
7+
8+
## Changes
9+
- Added a shared Session Inspector V2 output height token and applied it to JSON, Data, Dirty, and Status outputs.
10+
- Changed JSON/Data/Dirty outputs to wrap long lines with `pre-wrap`, `overflow-wrap: anywhere`, and no horizontal output scrollbar.
11+
- Kept vertical scrolling inside JSON/Data/Dirty `<pre>` elements.
12+
- Let the right detail panel scroll so lower accordion headers remain reachable when all detail sections are open.
13+
14+
## Guardrails
15+
- No sample JSON files modified.
16+
- No roadmap files modified.
17+
- No cross-tool communication added.
18+
- No normalized session storage object shape changes.
19+
20+
## Validation
21+
- `node --check tests/playwright/tools/WorkspaceManagerV2.spec.mjs` passed.
22+
- `npx playwright test tests/playwright/tools/WorkspaceManagerV2.spec.mjs --project=playwright --workers=1 --reporter=list -g "shows normalized workspace tool sessions as JSON, Data, and Dirty views"` passed.
23+
- `npm run test:workspace-v2` passed: 15 tests.
24+
25+
## Full Samples Smoke
26+
- Skipped per PR instructions. This PR is limited to Session Inspector V2 output layout and targeted Workspace Manager V2 Playwright coverage.

tests/playwright/tools/WorkspaceManagerV2.spec.mjs

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -900,35 +900,46 @@ test.describe("Workspace Manager V2 bootstrap", () => {
900900
const dirtyHeader = document.querySelector(".session-inspector-v2__dirty-accordion-header");
901901
const statusHeader = document.querySelector(".session-inspector-v2__status-accordion-header");
902902
const rightPanel = document.querySelector(".session-inspector-v2__panel--right");
903+
const statusOutput = document.querySelector("#statusLog");
904+
const jsonOutputStyle = getComputedStyle(jsonOutput);
905+
const dataOutputStyle = getComputedStyle(dataOutput);
903906
const jsonContentStyle = getComputedStyle(jsonContent);
904907
const dataContentStyle = getComputedStyle(dataContent);
905908
const rectFor = (element) => element.getBoundingClientRect();
906909
const rightRect = rectFor(rightPanel);
907910
const dirtyHeaderRect = rectFor(dirtyHeader);
908911
const statusHeaderRect = rectFor(statusHeader);
912+
rightPanel.scrollTop = rightPanel.scrollHeight;
913+
const scrolledDirtyHeaderRect = rectFor(dirtyHeader);
914+
const scrolledStatusHeaderRect = rectFor(statusHeader);
915+
const statusOutputHeight = Math.round(rectFor(statusOutput).height);
909916
return {
910917
dataContentDoesNotOwnScrollbar: dataContentStyle.overflowY === "hidden" && dataContentStyle.overflowX === "hidden",
911-
dataOutputScrollsHorizontally: dataOutput.scrollWidth > dataOutput.clientWidth + 1,
918+
dataOutputHasNoHorizontalScrollbar: dataOutput.scrollWidth <= dataOutput.clientWidth + 1,
912919
dataOutputScrollsVertically: dataOutput.scrollHeight > dataOutput.clientHeight + 1,
913-
dataOutputHeightBounded: rectFor(dataOutput).height <= 170,
914-
dirtyHeaderReachable: dirtyHeaderRect.top >= rightRect.top && dirtyHeaderRect.bottom <= rightRect.bottom,
920+
dataOutputHeightMatchesStatus: Math.abs(Math.round(rectFor(dataOutput).height) - statusOutputHeight) <= 1,
921+
dataOutputWrapsLongLines: dataOutputStyle.whiteSpace === "pre-wrap" && dataOutputStyle.overflowWrap === "anywhere",
922+
dirtyHeaderReachable: dirtyHeaderRect.top >= rightRect.top || (scrolledDirtyHeaderRect.top >= rightRect.top && scrolledDirtyHeaderRect.bottom <= rightRect.bottom),
915923
jsonContentDoesNotOwnScrollbar: jsonContentStyle.overflowY === "hidden" && jsonContentStyle.overflowX === "hidden",
916-
jsonOutputScrollsHorizontally: jsonOutput.scrollWidth > jsonOutput.clientWidth + 1,
924+
jsonOutputHasNoHorizontalScrollbar: jsonOutput.scrollWidth <= jsonOutput.clientWidth + 1,
917925
jsonOutputScrollsVertically: jsonOutput.scrollHeight > jsonOutput.clientHeight + 1,
918-
jsonOutputHeightBounded: rectFor(jsonOutput).height <= 170,
919-
statusHeaderReachable: statusHeaderRect.top >= rightRect.top && statusHeaderRect.bottom <= rightRect.bottom
926+
jsonOutputHeightMatchesStatus: Math.abs(Math.round(rectFor(jsonOutput).height) - statusOutputHeight) <= 1,
927+
jsonOutputWrapsLongLines: jsonOutputStyle.whiteSpace === "pre-wrap" && jsonOutputStyle.overflowWrap === "anywhere",
928+
statusHeaderReachable: statusHeaderRect.top >= rightRect.top || (scrolledStatusHeaderRect.top >= rightRect.top && scrolledStatusHeaderRect.bottom <= rightRect.bottom)
920929
};
921930
});
922931
expect(detailPanelState).toEqual({
923932
dataContentDoesNotOwnScrollbar: true,
924-
dataOutputScrollsHorizontally: true,
933+
dataOutputHasNoHorizontalScrollbar: true,
925934
dataOutputScrollsVertically: true,
926-
dataOutputHeightBounded: true,
935+
dataOutputHeightMatchesStatus: true,
936+
dataOutputWrapsLongLines: true,
927937
dirtyHeaderReachable: true,
928938
jsonContentDoesNotOwnScrollbar: true,
929-
jsonOutputScrollsHorizontally: true,
939+
jsonOutputHasNoHorizontalScrollbar: true,
930940
jsonOutputScrollsVertically: true,
931-
jsonOutputHeightBounded: true,
941+
jsonOutputHeightMatchesStatus: true,
942+
jsonOutputWrapsLongLines: true,
932943
statusHeaderReachable: true
933944
});
934945
await page.locator("#copySessionInspectorV2AllButton").click();
@@ -949,20 +960,25 @@ test.describe("Workspace Manager V2 bootstrap", () => {
949960
const dirtyOutputScrollState = await page.evaluate(() => {
950961
const dirtyContent = document.querySelector("#sessionInspectorV2DirtyContent");
951962
const dirtyOutput = document.querySelector("#sessionInspectorV2DirtyOutput");
963+
const statusOutput = document.querySelector("#statusLog");
952964
const dirtyContentStyle = getComputedStyle(dirtyContent);
965+
const dirtyOutputStyle = getComputedStyle(dirtyOutput);
953966
const rect = dirtyOutput.getBoundingClientRect();
967+
const statusOutputHeight = Math.round(statusOutput.getBoundingClientRect().height);
954968
return {
955969
dirtyContentDoesNotOwnScrollbar: dirtyContentStyle.overflowY === "hidden" && dirtyContentStyle.overflowX === "hidden",
956-
dirtyOutputScrollsHorizontally: dirtyOutput.scrollWidth > dirtyOutput.clientWidth + 1,
970+
dirtyOutputHasNoHorizontalScrollbar: dirtyOutput.scrollWidth <= dirtyOutput.clientWidth + 1,
957971
dirtyOutputScrollsVertically: dirtyOutput.scrollHeight > dirtyOutput.clientHeight + 1,
958-
dirtyOutputHeightBounded: rect.height <= 170
972+
dirtyOutputHeightMatchesStatus: Math.abs(Math.round(rect.height) - statusOutputHeight) <= 1,
973+
dirtyOutputWrapsLongLines: dirtyOutputStyle.whiteSpace === "pre-wrap" && dirtyOutputStyle.overflowWrap === "anywhere"
959974
};
960975
});
961976
expect(dirtyOutputScrollState).toEqual({
962977
dirtyContentDoesNotOwnScrollbar: true,
963-
dirtyOutputScrollsHorizontally: true,
978+
dirtyOutputHasNoHorizontalScrollbar: true,
964979
dirtyOutputScrollsVertically: true,
965-
dirtyOutputHeightBounded: true
980+
dirtyOutputHeightMatchesStatus: true,
981+
dirtyOutputWrapsLongLines: true
966982
});
967983
await page.locator('[data-session-inspector-v2-entry-id="sessionStorage:workspace.tools.no-data-test"]').click();
968984
await expect(page.locator("#sessionInspectorV2DataOutput")).toContainText("No data section is present for sessionStorage:workspace.tools.no-data-test.");

tools/session-inspector-v2/styles/sessionInspectorV2.css

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ body[data-tool-id="session-inspector-v2"],
1010
--session-inspector-v2-header-surface: var(--tools-shell-glass, var(--panel));
1111
--session-inspector-v2-shadow: var(--tools-shell-shadow, none);
1212
--session-inspector-v2-shadow-strong: var(--tools-shell-shadow-strong, none);
13+
--session-inspector-v2-output-height: 180px;
1314
}
1415

1516
body {
@@ -169,17 +170,17 @@ button:hover {
169170
}
170171

171172
.session-inspector-v2__panel--right {
172-
overflow: hidden;
173+
overflow: auto;
173174
}
174175

175176
.session-inspector-v2__accordion--detail.is-open {
176177
flex: 0 1 auto;
177178
min-height: 0;
178-
max-height: clamp(126px, 24vh, 190px);
179+
max-height: none;
179180
}
180181

181182
.session-inspector-v2__accordion--detail-scroll.is-open {
182-
max-height: clamp(126px, 24vh, 190px);
183+
max-height: none;
183184
}
184185

185186
.session-inspector-v2__accordion--controls.is-open {
@@ -254,13 +255,15 @@ button:hover {
254255
}
255256

256257
.session-inspector-v2__accordion--detail .session-inspector-v2__output {
257-
flex: 1 1 auto;
258-
max-height: clamp(86px, 17vh, 142px);
258+
flex: 0 0 var(--session-inspector-v2-output-height);
259+
height: var(--session-inspector-v2-output-height);
260+
max-height: var(--session-inspector-v2-output-height);
259261
min-height: 0;
260-
overflow: auto;
261-
overflow-wrap: normal;
262-
white-space: pre;
263-
word-break: normal;
262+
overflow-x: hidden;
263+
overflow-y: auto;
264+
overflow-wrap: anywhere;
265+
white-space: pre-wrap;
266+
word-break: break-word;
264267
}
265268

266269
.session-inspector-v2__actions {
@@ -418,7 +421,8 @@ button:hover {
418421
.session-inspector-v2__output,
419422
#statusLog {
420423
width: 100%;
421-
min-height: 180px;
424+
height: var(--session-inspector-v2-output-height);
425+
min-height: var(--session-inspector-v2-output-height);
422426
box-sizing: border-box;
423427
margin: 0;
424428
padding: 10px;

0 commit comments

Comments
 (0)