Repository navigation
Commit 35fc9b9
test(showcase,ui-live): re-point the two nightly live specs to what record page v3 draws (#28009)
Part of #27114 — the two record-page-v3 reds of nightly run 41009107101
(reading 6516358130). The card stays open until a scheduled `Nightly
tiers` run is green.
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:只改两个夜间 live 测试
spec(`ui/e2e/live/record-history-display.spec.ts`、`examples/app-showcase/e2e/detail-shapes.spec.ts`),让它们按记录页
v3 实际画出的界面去找元素;产品代码零改动。
- 为什么改:夜间 `Nightly tiers` 在 main 上红了两例。一例是 1440
宽下"时间线"开关默认关、事件流折在关闭的「动态」卡片里;另一例是 #27473 把两栏下限改成 760 px 视图后,1200
宽已不再是标签页布局,而且 v3 把主相关列表画成详情页里的表格、不再是独立标签。
- 风险与回滚:只动测试,不影响任何发布包;回滚即 revert 本 PR。风险在于 780 px 这个窗口宽度依赖侧栏图标栏(48 px)和
760 px 下限,日后两者变动时需要重新测量(注释里写了推导)。
- 先看:① `examples/app-showcase/e2e/detail-shapes.spec.ts` 的 Contoso
用例(视口推导注释与新的 v3 断言);② `ui/e2e/live/record-history-display.spec.ts` 第 2
步(先断言开关关闭、卡片折叠,再点开「动态」卡片)。
- 两分钟验证:在构建好的工作区里运行 `cd examples/app-showcase && OS_TEST_TIERS=nightly
pnpm exec vitest run`,预期 `Test Files 2 passed (2)`。
- 需要你做的:无,席位落地。
## What changes
Two test files only, each re-pointed at what record page v3 draws,
measured under the nightly harness itself. No product change, no retry,
no timeout raised, no test renamed, skipped or deleted.
**1. `ui/e2e/live/record-history-display.spec.ts` (driven by
`test/console-live-specs.live.test.ts`).** H1 holds. At 1440x900 the
nightly harness (a built Console on a fresh database) draws the
three-column tier. `showcase_account` is not a worked object: it
declares no `stageField`, no lifecycle option `kind` and no
`enable.files`. So the reader's Timeline switch defaults to off, and the
stream is folded into the closed Activity card at the related column's
foot. That card does not mount its blocks until it is opened, so the
Changes chip never appeared. The failure snapshot reads `group "Panels"`
with `button "Timeline"` (not pressed) and `region "Activity"` with a
collapsed `button "Activity"`. The spec now opens that card the way a
reader does, and asserts each step:
- the Timeline segment of the Panels control reads
`aria-pressed="false"`;
- the card heading's toggle reads `aria-expanded="false"`, is clicked,
then reads `"true"`;
- the stream region is scoped inside that card, and every later
assertion is unchanged.
I picked opening the card over pressing the Timeline segment. The card
is where the stream sits by default, and opening it changes no stored
preference. The toggle is named by its heading, because the open stream
has an "Activity" filter chip of its own. The first attempt matched both
(a strict-mode violation) and was corrected in the second commit. The
first assertion carries the 15 s page-open budget the spec already gave
its first element.
**2. `examples/app-showcase/e2e/detail-shapes.spec.ts`, Contoso case
(driven by `test/showcase-smoke.live.test.ts`).** H2 holds, and there is
a second staleness under it.
- *Width.* Measured on this harness with a fresh context and no sidebar
cookie: from 768 px (`MOBILE_BREAKPOINT`) to 1000 px the sidebar comes
up as its 48 px icon rail. The tier flips between 808 px (two columns)
and 800 px (tabs), which is window minus 48 against the 760 px view
floor. 1024 px and up have the sidebar expanded, and at 1200 the tier is
`two-column` with no tablist. Below 768 px the mobile shell gives the
view the whole window, and 760 px drew two columns. So the desktop
tabbed tier is a window of 768 to 807 px. The case is pinned at 780x800:
732 px of view, 28 px under the floor and 12 px above the mobile
breakpoint. An expanded sidebar only narrows the view further.
- *Prominence.* Even inside the tabbed tier, v3 (objectstack#27055
Target 8) draws `relatedList: 'primary'` lists, Invoices and Projects,
as body tables in the Details tab. They are no longer tabs of their own.
The strip at 780 px is `Details 5 / Related 3 / Timeline`. The case now
asserts:
- Details is selected and a Related tab exists;
- there is no Invoices or Projects tab;
- the Details panel holds the Invoices table (`INV-1002`) and the
Projects table (`Data Platform`), their rows read at open;
- clicking Related selects it and self-fetches Contacts (`Carl Fox`).
This replaces the old `waitForTimeout(1500)` plus "panel text is
non-empty", which an empty state would also pass.
The flat-details, money-strip and footer assertions are unchanged.
- *Tier choice.* The case's own header names its invariant:
"related-heavy → related lists surface as tabs (prominence rule)". So
the case stays in the tabbed tier with a derived viewport, and only its
prominence assertions move to v3's rendering. Re-pointing it to the
column tier would drop the only live-smoke pin on the tab strip. Every
other page in this smoke runs at the Desktop Chrome viewport, which is a
column tier. The tab strip is also what the drawer and the split pane
draw at every width. The header bullet is updated to say this.
## Tests
<details><summary>Repro at base d5951c8 (the nightly invocation):
both reds</summary>
`OS_TEST_TIERS=nightly pnpm exec vitest run --maxWorkers=2` in
`examples/app-showcase`, under `os-verify-lock`:
- `e2e/detail-shapes.spec.ts:173`: `expect(locator).toBeVisible() failed
· Locator: getByRole('tab', { name: /Details/i }) · element(s) not
found`. It failed on both attempts, the retry included. `1 failed · 52
passed (3.1m)`.
- `e2e/live/record-history-display.spec.ts:92`: `TimeoutError:
locator.waitFor: Timeout 15000ms exceeded` on `getByRole('region', {
name: /^(Timeline|时间线)$/ }).locator('[data-stream-filter="changes"]')`.
`1 failed · 19 passed (1.8m)`.
- `Test Files 2 failed (2)` · `VERDICT command-exit 1`.
</details>
<details><summary>Green at head 6becc88 (same invocation)</summary>
- showcase smoke: `53 passed (2.7m)`
- Console live specs: `20 passed (1.6m)`
- `Test Files 2 passed (2)` · `Tests 2 passed (2)` · `VERDICT
command-exit 0`
</details>
<details><summary>Teeth: revert both fixes on top of the head, watch
both cases fail, restore</summary>
The script carries a `trap` restore. Both files were restored to base
with `git restore --source=d5951c8e37` (tree only). Mutated blobs
`024da82966` / `486a7df9e4` equal the base blobs. Fix-marker counts
dropped to 0 / 0.
- The same invocation then red-lined exactly the two cases:
`detail-shapes.spec.ts:156` (`getByRole('tab', { name: /Details/i })`
not found; `1 failed · 52 passed`) and
`record-history-display.spec.ts:62` (`locator.waitFor: Timeout 15000ms`;
`1 failed · 19 passed`). `Test Files 2 failed (2)` · `VERDICT
command-exit 1`.
- Restore by `git checkout HEAD --`. The restored blobs `d355411757` /
`2961a09237` equal the HEAD blobs, `git diff HEAD` is 0 bytes and `git
status --porcelain` is empty.
</details>
<details><summary>Typecheck</summary>
`pnpm --filter @objectstack/example-showcase typecheck` and `ui`'s
`type-check:e2e` both pass: `VERDICT command-exit 0`. `--listFiles`
counts each edited spec once in its program: `e2e/detail-shapes` is in
the showcase tsconfig, and `record-history-display` is in
`ui/tsconfig.e2e.json`.
</details>
## Acceptance notes
- The 780 px pin is a derived reading of two current values: the 48 px
icon rail and the 760 px floor. If the sidebar's auto-collapse range or
`RECORD_PAGE_TWO_COLUMN_MIN_WIDTH` moves, this case is where it
surfaces, as a missing tablist. The comment carries the derivation so
the next re-pin is a re-measure, not a guess.
- `record-history-display` now relies on the reader default (timeline
off for a non-worked object). It asserts that default explicitly, so a
run against a long-lived local stack whose browser stored the switch as
on fails on a named assertion, not on a timeout.
- The beforeAll comment in `detail-shapes.spec.ts` still says Contoso
has "2 invoices". The seed has three (INV-1002, INV-1003, INV-1005). It
is a comment outside this card's surface, left as is.
## Verification
<details><summary>Local gates: dispatch-gates --commands derived 37 over
the 2 paths; all exit 0</summary>
Each gate ran with its exit code captured to disk before any pipe. 35
exited 0 first time. Two were reruns, not reds:
- `pnpm check:dual-build-cjs-loads` first exited 3 (`PREREQUISITE NOT
MET`: 7 packages outside the touched closure had no `dist/`). After
building them it exited 0: `113 published require entry point(s) across
70 package(s) load`.
- `pnpm check:query-options-erasure` hit my own 280 s per-gate cap
(124). Rerun uncapped, it exited 0: `ratchet holds: 50 unswept non-test
site(s) in 15 file(s), none new`.
The reconciliation `dispatch-gates --ran` answered `37 derived
famil(ies) accounted for — 37 run, 0 NOT-MEASURED (a DERIVED zero — all
37 recorded an exit code and none of them is 3)`, exit 0.
`check:nul-bytes` exit 0, and the control-byte self-scan of both files
found nothing. The families CI runs are read off this PR's check-runs.
`dogfood_battery`: n/a, because there is no `!` in the title and no
`(narrowing)` arm. `skip-changeset`: both files are test specs in
packages that publish nothing (`ui/e2e/**`, and the private
`@objectstack/example-showcase`).
</details>
---
_Generated by [Claude
Code](https://claude.ai/code/session_01QSeKYmTYfaPbLQD4BJfomW)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent d3d70d3 commit 35fc9b9
2 files changed
Lines changed: 78 additions & 28 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
15 | | - | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
16 | 20 | | |
17 | 21 | | |
18 | 22 | | |
| |||
156 | 160 | | |
157 | 161 | | |
158 | 162 | | |
159 | | - | |
160 | | - | |
161 | | - | |
162 | | - | |
163 | | - | |
164 | | - | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
165 | 182 | | |
166 | 183 | | |
167 | 184 | | |
168 | 185 | | |
169 | 186 | | |
170 | 187 | | |
171 | | - | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
172 | 193 | | |
| 194 | + | |
173 | 195 | | |
174 | | - | |
175 | | - | |
176 | | - | |
177 | | - | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
178 | 208 | | |
179 | 209 | | |
180 | 210 | | |
| |||
190 | 220 | | |
191 | 221 | | |
192 | 222 | | |
193 | | - | |
194 | | - | |
195 | | - | |
196 | | - | |
197 | | - | |
198 | | - | |
199 | | - | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
200 | 230 | | |
201 | 231 | | |
202 | 232 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
43 | 43 | | |
44 | 44 | | |
45 | 45 | | |
46 | | - | |
47 | | - | |
48 | | - | |
49 | | - | |
50 | | - | |
| 46 | + | |
51 | 47 | | |
52 | 48 | | |
53 | 49 | | |
| |||
56 | 52 | | |
57 | 53 | | |
58 | 54 | | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
59 | 68 | | |
60 | 69 | | |
61 | 70 | | |
| |||
83 | 92 | | |
84 | 93 | | |
85 | 94 | | |
86 | | - | |
87 | | - | |
88 | | - | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
89 | 99 | | |
90 | | - | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
91 | 111 | | |
92 | 112 | | |
93 | 113 | | |
| |||
0 commit comments