Skip to content

test(showcase,ui-live): re-point the two nightly live specs to what record page v3 draws - #28009

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-27114-showcase-live-v3
Oct 30, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-27114-showcase-live-v3

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

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 宽下"时间线"开关默认关、事件流折在关闭的「动态」卡片里;另一例是 fix(plugin-detail,app-shell,components): record page round 2 — related OFF draws no column or rail, one segmented panel control in the header row, three columns in a 1440 window with the sidebar #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

Repro at base d5951c8 (the nightly invocation): both reds

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.
Green at head 6becc88 (same invocation)
  • 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
Teeth: revert both fixes on top of the head, watch both cases fail, restore

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.
Typecheck

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.

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

Local gates: dispatch-gates --commands derived 37 over the 2 paths; all exit 0

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).


Generated by Claude Code

…ecord page v3 draws

record-history-display: at 1440x900 a non-worked object's Timeline switch
is off, so the stream is folded into the closed Activity card at the
related column's foot. The spec now asserts the switch is off and the
card is closed, opens it, and reads the Changes chip inside it.

detail-shapes (Contoso): re-pin the tabbed tier at 780x800, derived from
the measured icon-rail sidebar and the 760 px view floor, and re-point the
prominence assertions to v3: primary lists are body tables in the Details
tab, the rest self-fetch behind the Related tab.

Claude-Session: https://claude.ai/code/session_01QSeKYmTYfaPbLQD4BJfomW
Co-authored-by: Claude <noreply@anthropic.com>
…pen stream has an Activity chip of its own

Claude-Session: https://claude.ai/code/session_01QSeKYmTYfaPbLQD4BJfomW
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 30, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:devx#2 · os-justin · session_01QSeKYmTYfaPbLQD4BJfomW

席位核对 — ACCEPT · domain:devx#2 · head 6becc88c2b · 2026-10-30T07:46Z

维护者速读

席位意见:合入。dev 用夜间检查同样的方式复现了两个红;修后变绿;再把两个文件退回原样,两个用例都重新变红,说明修复是真的起作用。每一步都有断言,没有用固定等待凑过去。780px 的推导写在注释里:桌面上只有 768–807px 这个窗口宽度会画页签。

Shape: draft → main, Part of #27114. 2 files: examples/app-showcase/e2e/detail-shapes.spec.ts (+49/−19) and ui/e2e/live/record-history-display.spec.ts (+29/−9). Labels tests, size/m, skip-changeset. Non-governed; the seat lands it. Report 6517465110; reading 6516358130; dispatch 6516371709.

Premise measured: reproduced at d5951c8e37 under the nightly invocation:

  • detail-shapes:173: tab Details not found. 1 failed, 52 passed.
  • record-history-display:92: waitFor 15000 ms. 1 failed, 19 passed.

Seat's own read:

  • record-history-display:
    • It asserts that [data-panel-toggle="timeline"] has aria-pressed=false.
    • The Activity card's heading toggle starts at aria-expanded=false, then flips to true after the click. The toggle is named through its heading, because the open stream has an "Activity" filter chip of its own; that collision is fixed in the second commit.
    • It then reads the Changes chip inside the card. The display-contract assertions are unchanged.
    • The 15 s first-element budget moved from the chip wait to the switch assertion. It was not raised.
  • detail-shapes:
    • The viewport is 780×800, with the derivation in the case comment: icon-rail sidebar, tier flip at window 808 → 800.
    • Assertions: Details is selected, a Related tab exists, there is no Invoices or Projects tab, and the INV-1002 and Data Platform rows appear in the Details panel's tables.
    • Related self-fetches and shows Carl Fox. This replaces waitForTimeout(1500) plus a non-empty-text check.

Gates:

  • On head 6becc88c2b, 60 check-runs: 47 success, 13 skipped, 0 failure. Build & E2E UI and Live E2E UI succeed. mergeable_state: clean.
  • check-expected-skips --pr 28009: OK, all 13 skips are in main's roster (exit 0).
  • check-governed-merges --pr 28009: NOT governed, 106 changed lines.
  • Dev's union: 37 derived, 37 run, all exit 0.
  • Nightly invocation green: 53/53 and 20/20.
  • Teeth: both files restored to base turn red again (1/53 and 1/20).

Accepted deviation: detail-shapes needed more than the viewport re-pin. Its Invoices and Projects tab assertions were stale under v3 at every width. The change stays inside the case, and the title is unchanged.

Out of scope: the beforeAll comment says Contoso has "2 invoices", but the seed has 3. Comment only, so it goes to Acceptance notes. Skills-docs: n/a.

Landing: non-governed, 106 changed lines. In this act the seat readies the PR and arms auto-merge. On merge, the seat verifies the merged diff and posts the landing note on #27114. The card stays open until the next scheduled Nightly tiers run (cron 29 5 * * *) is green.


Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 30, 2026 07:47
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 30, 2026
Merged via the queue into main with commit 35fc9b9 Oct 30, 2026
61 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-27114-showcase-live-v3 branch October 30, 2026 08:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant