test(web): assert the timestamp occlusion the sidebar gutter fixes
The e2e measured the reserved band but never the symptom the change is named for. Headless chromium defaults to an overlay scrollbar, which is the configuration where a bar can cover row content at all, so the scenario already ran in the right mode: against clean master the band is 0 and the bar covers 7px of the relative time. Adds timeCoveredBy, the overlap between the relative time's right edge and the range the bar occupies, taking the bar's width from the sheet where it applies and from the UA's overlay width otherwise. Assuming 0 there would report no occlusion in precisely the state that has it. Keeps the band assertion rather than replacing it: the two catch different regressions. Removing only scrollbar-gutter leaves timeCoveredBy at 0, because the bar is then 8px and the row's right padding is also 8px, so it abuts the timestamp without covering it. Removing the pseudo-element width as well is what produces the overlap. Each was mutation-checked with the other assertions in its test silenced. Records in the note that the gutter and the ::-webkit-scrollbar width are jointly necessary against an overlay bar, measured by deleting each from the live cascade with the other in force: either alone drops the band from 8 to 0.
This commit is contained in:
+5
-1
@@ -26,6 +26,8 @@ The track and the corner stay transparent, so the thumb reads against whatever s
|
||||
|
||||
`.list` declares `scrollbar-gutter: stable`, which keeps the bar beside the rows instead of on top of them. `stable` rather than `auto` because `auto` reserves the gutter only while the list actually overflows: expanding a workspace group would then shift every row horizontally at the moment it starts scrolling. The reservation is unconditional and the rows never move.
|
||||
|
||||
The gutter and the sheet's `::-webkit-scrollbar` width are jointly necessary against an overlay scrollbar, which is the configuration where the symptom exists at all. Measured on the running app by deleting each from the live cascade with the other left in force: either deletion alone takes the list's band from 8 to 0. The gutter states that space be reserved, and the pseudo-element width is what makes chromium treat the bar as occupying layout space rather than floating over the content. Neither half of this change is therefore optional for the reported bug, which is a second reason the two halves ship together.
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
**Per-module `::-webkit-scrollbar` rules in each scrolling component sheet.** Rejected: the client has thirteen scrolling containers across nine packages, every one would carry the same block, and the fourteenth would ship unthemed with nothing failing. A skin driven by design tokens belongs in the package that owns the tokens.
|
||||
@@ -65,6 +67,8 @@ Two chromium measurement limits shape what the e2e can assert. The gate makes ch
|
||||
|
||||
The gate itself has a negative control at the level it operates on: removing the `@supports` wrapper from the sheet, rebuilding `build:web`, and rerunning the e2e turns the `scrollbar-width: auto` assertion red with `thin`, which is the suppression the gate exists to prevent.
|
||||
|
||||
Headless chromium draws overlay scrollbars, so a reserved gutter there does not shrink `clientWidth`. The reservation shows up as a non-zero `offsetWidth - clientWidth` band on the list; client-area geometry alone does not demonstrate it, and an assertion comparing the time element's right edge against the client-area edge holds with and without the reservation, so it would pass or fail on the platform's scrollbar style rather than on the declaration under test.
|
||||
Headless chromium draws overlay scrollbars, and that is the configuration in which the reported symptom exists, so the e2e reproduces the bug rather than approximating it: against clean master the list's band is 0 and the bar covers 7px of the relative time. A reserved gutter there does not shrink `clientWidth`, so an assertion comparing the time element's right edge against the client-area edge holds with and without the reservation and would pass or fail on the platform's scrollbar style rather than on the declaration under test. The two signals that do separate the states are the `offsetWidth - clientWidth` band and `timeCoveredBy`, the overlap measured against the bar's own width.
|
||||
|
||||
Both are asserted because each catches a different regression, established by mutating one declaration at a time with the other assertions in that test silenced. Removing only the gutter leaves `timeCoveredBy` at 0 — the bar is then 8px and the row's right padding is also 8px, so it abuts the timestamp without covering it — and the band assertion is what fails. Removing the pseudo-element width as well, which is the actual master state, produces the overlap, and `timeCoveredBy` fails at 7. A headed run under xvfb cannot show the symptom in either state, because chromium paints a classic space-consuming bar there and `clientWidth` already excludes it.
|
||||
|
||||
Verifying browser-visible plugin CSS needs a rebuild `pnpm run build:web` does not perform. `WorkspaceBrowser.module.css` never reaches `apps/web/dist`: ui-workspace loads as a runtime plugin and its CSS is inlined into `packages/client/ui-workspace/lib/client.js`, built by that package's own `bundle` script. A negative control that reruns only `build:web` therefore exercises a stale bundle and passes with the declaration removed, which reads as a vacuous test rather than as an invalid control. Rebuild with `pnpm --filter @deepseek-ai/dsh-client-ui-workspace run bundle`, confirm the artifact by grepping `lib/client.js` for the declaration, then `build:web`. No script in the web lane does this: `test:web` runs `build:web` alone, so every scroll-region or plugin-CSS change hits the same trap.
|
||||
|
||||
Reference in New Issue
Block a user