Skip to content

Commit 4bf48a8

Browse files
test(showcase): add the Reports index to the smoke SURFACES (#28719)
<!-- claude-projects-attribution: {"github_login":"marchtian"} --> _Requested by **田騏** · [project thread](https://claude.ai/code/project/chan_01VmuUhXU9SSUzqJYyXSmYSi?thread=cmsg_01VmuUhXU9SSUzqJYyXSmYSi9paTx1Lu8ENYwwssthfK3h)_ Fixes #28653 Clause-②: no Metadata-protocol: none ## 维护者速读 - 改了什么:showcase P0 冒烟套件的 SURFACES 新增一项「All reports」(报表索引页 nav_report_index,路径 …/reports);清单条目 platform-core.nav-surfaces-render 同步改为「SURFACES 覆盖全部 50 个导航叶子」,并去掉对 /reports 的常设手工巡检(revision 9 → 10);RUNNER.md 里「49 个测试全挂即环境问题」的计数同步为 50。 - 为什么改:showcase 导航有 50 个叶子,冒烟只覆盖 49 个,报表索引页每次 P0 都得靠人手点一遍,忘了点就漏掉回归;现在它和其他页面一样由套件自动检查。 - 风险与回滚:只动测试与文档,不动产品代码、不发布任何包;现有 49 项检查一字未改。回滚即 revert 本 PR。 - 先看:examples/app-showcase/e2e/showcase-smoke.spec.ts(新增那一行 SURFACES)→ docs/qa/platform-checklist/areas/platform-core.json(steps[0]/[2] 与 history 第 10 行)→ docs/qa/platform-checklist/RUNNER.md(一个数字)。 - 两分钟验证:`pnpm console:build` 之后运行 `SMOKE_API_URL=http://localhost:PORT pnpm -C examples/app-showcase test:smoke e2e/showcase-smoke.spec.ts`(PORT 取一个空闲端口),预期「50 passed」,最后一项是「surface renders cleanly: All reports」。 - 需要你做的:无,席位落地。 ## What changes - `examples/app-showcase/e2e/showcase-smoke.spec.ts`: one new `SURFACES` entry, `{ name: 'All reports', path: base('reports') }`, for `nav_report_index` (a `report` nav entry with no `reportName`, which the console opens as the app's report index at `…/reports`). It runs under exactly the same per-surface checks as every other entry (no pageerror, no `no actions configured` placeholder, non-empty main content, past the boot splash). It is not a chart surface, so no `chart: true`. No existing entry or check is changed or removed. The name is the console's own label for that page (`sidebar.allReports`, "All reports"), since the nav entry carries no `label`. - `docs/qa/platform-checklist/areas/platform-core.json`, item `platform-core.nav-surfaces-render`: `steps[0]` now says SURFACES has 50 entries covering all 50 served `showcase_app` nav leaves, the report index included; `steps[2]` drops the standing hand-walk of `/reports` (on a current tree the served-vs-SURFACES diff is empty; a leaf the nav gains without a SURFACES entry is the hand-walk until the suite gains it). `revision` 9 to 10, one history row citing #28653. No clause, negative or oracle changed. - `docs/qa/platform-checklist/RUNNER.md`: the whole-run-red discriminator said one test per `SURFACES` entry, "49 today, so 49 failed means all of them". This PR makes that 50, so it now says 50. This is the one other place that pinned the count, and the change makes it wrong, so it is fixed here (declared below). ## Tests Counts read from source at `e630e6434b` (`origin/main` 0be4c8a merged in): `examples/app-showcase/src/ui/apps/index.ts` serves 50 non-separator leaves (25 pages, 17 objects, 5 reports, 3 dashboards); `SURFACES` held 49 before this PR and holds 50 after it. Live run, prepared the way the nightly prepares it (`turbo run build` of the showcase closure, `pnpm console:build`), with `SMOKE_API_URL` on an OS-assigned free port and `OS_TEST_CHROMIUM_EXECUTABLE_PATH=/opt/pw-browsers/chromium`, both runs at the same build: | Spec | Command | Result | |:--|:--|:--| | base spec (`e170d42438`) | `pnpm -C examples/app-showcase test:smoke e2e/showcase-smoke.spec.ts` | 49 passed (2.1m) | | this PR (`e630e6434b`) | same | 50 passed (2.0m), `All reports` passed in 2.0s | A separate probe of the same page (signed in as the seeded admin, waiting past the boot splash) read the report index rendering its four named reports under the Tasks section, with no pageerror: "Reports · All reports · Recent · Tasks 4 · Hours by Status (Chart) · Hours by Status (Summary) · Status × Priority (Matrix) · Task Overview (Joined)". So the new entry passes on real content, not on an empty or not-found state. `pnpm --filter @objectstack/example-showcase run typecheck` (its tsconfig includes `e2e/**/*`): exit 0. ## Acceptance notes - Declared in-place fix outside the claim's named file surface: `docs/qa/platform-checklist/RUNNER.md` line 257, the count `49` to `50`. It is the same defect class (a stale SURFACES count), a mechanical one-number edit, held by no other claim, and inside the same checklist gate family. Left alone, it would make "49 failed" read as a whole-run environment red when one surface still passed. - Historical counts were left as they are: the `22 of 49 surfaces` in the spec's boot-splash comment, the `49 leaf items` in the #21060 comment, and the history rows of revisions 5 and 9. Each records what was measured at that time. - `acceptance[1]` of the item (coverage is current: every served destination is in SURFACES or hand-walked this run) is still the run's job. The suite never reads `meta/app`, so no automation computes that diff. This PR changes the expected result of that diff to empty. It does not automate the diff. ## Verification <details><summary>Local gates: 42 derived, 42 run, every exit code 0</summary> `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` at `e630e6434b` derived 42 commands for the 3 changed paths. Every one exited 0, each exit captured before any pipe, including `pnpm check:platform-checklist`, `pnpm check:doc-authoring`, `pnpm check:nul-bytes`, `pnpm check:examples-live-imports` and `pnpm check:published-files`. `--ran` reconciliation: "42 derived famil(ies) accounted for — 42 run, 0 NOT-MEASURED (a DERIVED zero — all 42 recorded an exit code and none of them is 3)". </details> <details><summary>Changeset</summary> No changeset: the diff touches `examples/app-showcase` (`"private": true`) and `docs/qa/` only, so no released package publishes anything new. Labelled `skip-changeset`. </details> Session: https://claude.ai/code/session_017ihL2gLghEqeDKTbDTC7Zd 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude <noreply@anthropic.com>
1 parent 63acf35 commit 4bf48a8

3 files changed

Lines changed: 15 additions & 4 deletions

File tree

‎docs/qa/platform-checklist/RUNNER.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ contradicts it, and correct it here when it does.
254254
out of this section is the `absence-inference` trap one level up.
255255
**The discriminator is uniformity:** a launch/environment failure
256256
takes down the whole run at once (`showcase-smoke.spec.ts` generates one test per
257-
`SURFACES` entry — 49 today, so "49 failed" means all of them), while a product defect
257+
`SURFACES` entry — 50 today, so "50 failed" means all of them), while a product defect
258258
fails selectively. ⛔ Do not file a whole-run red as a product defect before checking
259259
the browser resolved.
260260

‎docs/qa/platform-checklist/areas/platform-core.json‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@
310310
"title": "Every showcase nav surface renders without page errors, and failures surface the error boundary — never a blank page",
311311
"since": "v15",
312312
"status": "active",
313-
"revision": 9,
313+
"revision": 10,
314314
"priority": "P0",
315315
"surface": "browser",
316316
"personas": ["seeded admin (admin@objectos.ai / admin123)"],
@@ -321,9 +321,9 @@
321321
]
322322
},
323323
"steps": [
324-
"run the pinned suite: pnpm -C examples/app-showcase test:smoke e2e/showcase-smoke.spec.ts (the SURFACES array in e2e/showcase-smoke.spec.ts — 49 entries, which cover 49 of the 50 served showcase_app nav leaves; the one outside it is nav_report_index, steps[2]: pages, object lists, the three filter slices, the tabular view, dashboards, reports, the view-gallery pages). On a shared box pass SMOKE_API_URL=http://localhost:<free port>: the config signs in, drives every page and boots `serve --dev -p <that port>` from that one URL, and reuses whatever already answers it — on the default port 3000 that can be somebody else's server. Where the browser cache holds a different chromium build than @playwright/test resolves (RUNNER.md Environment facts), pass OS_TEST_CHROMIUM_EXECUTABLE_PATH=/opt/pw-browsers/chromium. Name the spec: the config's testDir is ./e2e (examples/app-showcase/playwright.config.ts), so a bare `test:smoke` also collects bulk-capability-gate.spec.ts and detail-shapes.spec.ts beside the pin (QA run #25812), and their results are not this item's",
324+
"run the pinned suite: pnpm -C examples/app-showcase test:smoke e2e/showcase-smoke.spec.ts (the SURFACES array in e2e/showcase-smoke.spec.ts — 50 entries, which cover all 50 served showcase_app nav leaves: pages, object lists, the three filter slices, the tabular view, dashboards, reports, the report index (nav_report_index, …/reports), the view-gallery pages). On a shared box pass SMOKE_API_URL=http://localhost:<free port>: the config signs in, drives every page and boots `serve --dev -p <that port>` from that one URL, and reuses whatever already answers it — on the default port 3000 that can be somebody else's server. Where the browser cache holds a different chromium build than @playwright/test resolves (RUNNER.md Environment facts), pass OS_TEST_CHROMIUM_EXECUTABLE_PATH=/opt/pw-browsers/chromium. Name the spec: the config's testDir is ./e2e (examples/app-showcase/playwright.config.ts), so a bare `test:smoke` also collects bulk-capability-gate.spec.ts and detail-shapes.spec.ts beside the pin (QA run #25812), and their results are not this item's",
325325
"GET /api/v1/meta/app?id=showcase_app and extract every nav destination from the response (?id= matches the app NAME; the package-id spelling returns an empty items array and would yield zero destinations)",
326-
"diff the served nav destinations against the SURFACES array; hand-walk any destination the suite does not cover (screenshot first, then DOM). The console draws no nav destination of its own: the report index (…/reports) renders only where an app's navigation declares a `report` entry with no `reportName` (showcase: nav_report_index in the Reports group), so it is served in meta/app and falls inside that diff like any other entry. #27525 retired the sidebar's injected 'All reports' row (objectui#13020) that QA run #25812 walked as the 50th surface. nav_report_index is the STANDING hand-walk: the served nav has 50 leaves (examples/app-showcase/src/ui/apps/index.ts: 25 pages, 17 objects, 5 reports, 3 dashboards) and SURFACES holds 49, so /reports is outside the suite on every run until SURFACES gains an entry for it — walk it each run and record it as hand-walked. A diff of the served entry ids reads 51: the 50 leaves plus the nav_sep_reports separator, which draws no surface (QA run #28545)",
326+
"diff the served nav destinations against the SURFACES array; hand-walk any destination the suite does not cover (screenshot first, then DOM). The console draws no nav destination of its own: the report index (…/reports) renders only where an app's navigation declares a `report` entry with no `reportName` (showcase: nav_report_index in the Reports group), so it is served in meta/app and falls inside that diff like any other entry. #27525 retired the sidebar's injected 'All reports' row (objectui#13020) that QA run #25812 walked as the 50th surface. The served nav has 50 leaves (examples/app-showcase/src/ui/apps/index.ts: 25 pages, 17 objects, 5 reports, 3 dashboards) and SURFACES holds all 50, nav_report_index included (#28653), so on a current tree the diff is empty and no surface is hand-walked; a leaf the nav gains without a SURFACES entry is the hand-walk until the suite gains it. A diff of the served entry ids reads 51: the 50 leaves plus the nav_sep_reports separator, which draws no surface (QA run #28545)",
327327
"on each hand-walked surface: wait for render, screenshot, then check for pageerror / empty <main> / placeholder leaks ('no actions configured')",
328328
"chart surfaces (the chart:true entries in SURFACES — Delivery Operations, Chart Gallery, Command Center, Revenue Pulse, Hours by Status (Chart)): the suite now POLLS boundingBox against a bounded deadline (SURFACE_BUDGET_MS in the spec) instead of reading it once after a fixed wait, so a chart red here is a real finding and not the measurement window — #7569 measured the difference: 3 fresh loads each drew 5 real charts, and polling every 400 ms returned null ONLY at t = 1.5 s, the old fixed measurement instant and exactly the recharts ResponsiveContainer initial-layout window, then non-null on all 19 later samples. Read WHICH assertion failed: 'no chart SVG laid out' means the box stayed null for the whole budget; a width/height failure means the chart laid out but collapsed (#2616 D). If you hand-walk a chart surface outside the suite, poll the same way — never sleep-then-read-once",
329329
"probe the failure path: navigate to a nonexistent route under the app (/_console/apps/com.example.showcase/object_that_does_not_exist); screenshot what renders",
@@ -404,6 +404,12 @@
404404
"date": "2026-11-01",
405405
"change": "QA run #28545 (W3-C1R) finding, stale since #27525: steps[0] called SURFACES 'all 49 showcase_app nav destinations', but the served nav has 50 leaves, nav_report_index among them, and SURFACES holds 49, so /reports was a hand-walk every run with no step naming it. steps[0] now says which leaf SURFACES lacks, and steps[2] names it as the standing hand-walk and notes that the id diff reads 51 with the separator. Counts read from source (apps/index.ts leaves; SURFACES in showcase-smoke.spec.ts). Adding the entry to SURFACES is outside this checklist file. No clause changed. Read from source at base 6b9c1ca991. Wave anchor #27377, wave-3 accuracy slice S9 (#28641); finding parked in anchor comment 6554042054",
406406
"ref": "#28545"
407+
},
408+
{
409+
"revision": 10,
410+
"date": "2026-11-01",
411+
"change": "the pin caught up with the standing hand-walk revision 9 named: SURFACES in showcase-smoke.spec.ts gained an entry for nav_report_index (…/reports, the app's report index, opened by a `report` entry with no `reportName`), under the same render checks as every other entry, and no entry was removed. steps[0] now says SURFACES covers all 50 served showcase_app nav leaves, and steps[2] drops the standing hand-walk of /reports: on a current tree the served-vs-SURFACES diff is empty. No clause changed. Counts read from source at base e170d42438 (apps/index.ts: 50 leaves; SURFACES: 50)",
412+
"ref": "#28653"
407413
}
408414
]
409415
},

‎examples/app-showcase/e2e/showcase-smoke.spec.ts‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ const SURFACES: { name: string; path: string; chart?: boolean }[] = [
8181
{ name: 'CRM Workbench', path: base('page/showcase_crm_workbench') },
8282
{ name: 'Task Desk', path: base('page/showcase_task_desk') },
8383
{ name: 'Renewals Pipeline', path: base('page/showcase_renewals_pipeline') },
84+
// [#28653] The 50th leaf: `nav_report_index`, a `report` entry with no
85+
// `reportName`, which the console opens as the app's report index at
86+
// `…/reports` (#27525). It carries no label, so the name is the console's
87+
// own for that page. With it, every served `showcase_app` nav leaf is here.
88+
{ name: 'All reports', path: base('reports') },
8489
];
8590

8691
/**

0 commit comments

Comments
 (0)