Skip to content

Commit 09abc05

Browse files
chore(ui): retire the dead import harness and the msw testing guide (#29453)
<!-- claude-projects-attribution: {"github_login":"zhuangjianguo"} --> _Requested by **Steedos** · [project thread](https://claude.ai/code/project/chan_018ETKaNwMZCNRYD7D8Q9Ubb?thread=cmsg_018ETKaNwMZCNRYD7D8Q9Ubb4AMvsQ5Sw4M7HwxMHVNGRL)_ Part of #25921: two of the open items in landing note 6579769954, "the playwright harness configs" and "the msw text in skills" (claim 6580031761, amendment 6581015226). The card stays open. The import-console config and spec stay, and every other item the card lists is untouched. Clause-②: no Metadata-protocol: none ## 维护者速读 - 改了什么:删除导入向导的 harness 版 Playwright 配置、它唯一的用例和 `test:e2e:import-harness` 脚本;QA 清单里提到这个"孪生用例"的地方改成"已在 #25921 退役";objectui 测试技能指南不再教 msw,改为教本仓库实际在用的写法(给真实 adapter 传一个 `vi.fn` 作为 `fetch`)。 - 为什么改:harness 配置要求的 `vite.live.config.ts` 在仓库里根本不存在,用例只能自我跳过,也没有任何 workflow 跑它;msw 已没有任何 package.json 声明,照指南写的测试连 import 都解析不了。 - 风险与回滚:只删死文件和改文档,不改任何运行时行为;真正在跑的 import-console 用例和 QA 配方 `qa-crm-import-console` 不动。回滚即 revert 本 PR。 - 先看:`skills/objectui/guides/testing.md`(新示例,已在真实 adapter 上跑通)、`docs/qa/platform-checklist/areas/records-forms.json`(条目 revision 8→9)、`ui/scripts/__tests__/e2e-type-check.test.ts`(Playwright 配置数下限 4→3)。 - 两分钟验证:`git grep -n -e import-harness -e IMPORT_HARNESS -e "from 'msw" -- ui skills docs/qa/platform-checklist/RUNNER.md`,预期无输出(退出码 1)。 - 需要你做的:本 PR 改了 `skills/**`(Tier H),需要你批准后由席位落地。 ## What changes - **Deleted** `ui/playwright.import-harness.config.ts`, its one spec `ui/e2e/import-harness/import-undo.spec.ts`, and the `test:e2e:import-harness` script in `ui/package.json`. The config told a runner to serve `packages/plugin-grid/demo/vite.live.config.ts` at `/live.html`; that file does not exist (`demo/` holds `index.html` and `bulk-actions.html`), so the spec could only self-skip. No workflow ran it. - **QA checklist** (`docs/qa/platform-checklist/areas/records-forms.json`, `RUNNER.md`): every place that named the harness twin now says it was retired on #25921: the `qa-crm-import-console` recipe's `why` and `knownGaps[0]`; and on `records-forms.import-job-undo-cancel` its `fixtures.requires[1]`, `fixtures.knownGaps[0]`, `steps[0]`, `acceptance[0].verify`, `automated.ref` and `source`. The item moves to revision 9 with a history row. History rows 7 and 8 still quote the old paths: the ledger is append-only. The import-console recipe's own steps are unchanged. - **`skills/objectui/guides/testing.md`**: "MSW for API mocking in integration tests" becomes "A fetch double for API mocking": a `vi.fn` passed as the `fetch` of a real `ObjectStackAdapter`, naming `packages/data-objectstack/src/aggregate-rows-post-unwrap-7028.test.ts` as the worked example. "Vitest mocks for unit tests" below it is unchanged. - **Amendment 6581015226**: `ui/scripts/__tests__/e2e-type-check.test.ts` lowers its root-config floor from 4 to 3, as its own comment asks when a config is retired; `ui/playwright.import-console.config.ts` drops the header line that named the harness config (code unchanged). - **Changeset** `.changeset/25921-objectui-testing-guide-fetch-double.md`: `@objectstack/skills` `patch`, because `skills/**` ships in that package's `dist`. ## Why The card's 2026-10-24 census listed both items as zero-consumer surface. Re-measured at `origin/main` `d93acbbe` (hotcrm `d4ffe99`) before editing: | name | before (files / lines) | after, at `6daa99f1` (outside history rows) | |:--|:--|:--| | `playwright.import-harness.config.ts` | 4 / 5 | 1 (the import-console header, removed by the amendment) | | `e2e/import-harness` | 3 / 10 | 0 | | `test:e2e:import-harness` | 2 / 3 | 0 | | `IMPORT_HARNESS_ORIGIN` | 1 / 2 | 0 | | `IMPORT_HARNESS_OBJECT` | 3 / 3 | 0 | | `vite.live.config.ts` | 2 / 4 | 0 | | `msw` (word, any case) | 70 / 262 | 69 / 259 | | `msw` under `skills/` | 5 lines | 2 (both say msw is gone: `data-integration.md` and its eval) | | imports `from 'msw…'` | 2 | 0 | | control `playwright.import-console.config.ts` | 4 files | 4 files | hotcrm names none of the harness names. Its only `msw` hit is an `onlyBuiltDependencies` entry in its root `package.json` (noted below). The other `msw` hits in this tree are CHANGELOGs, release notes and prose about the retired MSW plugin, which this batch does not touch. `skills/**` readings (the published bundle): | reading | before | after | |:--|--:|--:| | `skills/objectui/guides/testing.md` lines | 370 | 363 | | `skills/objectui/guides/testing.md` tokens (ratchet convention) | 3101 | 3101 (ceiling 3101) | | all `SKILL.md` lines | 4529 | 4529 | | `skills/**` lines | 19779 | 19771 | | bundle tokens (`check-skills-token-ratchet` total) | 224069 | 224069 | The new text was paid for by deleting the old MSW block in the same file. The ceiling did not move. ## Tests - Before, on `d93acbbe`: `pnpm --dir ui exec playwright test --config=playwright.import-harness.config.ts --list` → `Total: 1 test in 1 file`, exit 0. Running it: `1 skipped`, exit 0. - The guide's snippet, copied byte for byte into a throwaway test in `ui/packages/data-objectstack/src/` and run with `adapter.find('contact')` against it → 1 passed (`res.data` equals the faked record). The file was deleted afterwards and is not in the diff. - `pnpm --dir ui exec vitest run --maxWorkers=2 scripts/` on `6daa99f1` → 1 failed / 4920 passed: the `e2e-type-check` floor. The amendment lowers that floor; after it, `pnpm exec vitest run scripts/__tests__/e2e-type-check.test.ts` → 15/15 passed. - No ablation: deletions, docs and a test floor. No tested behaviour changed. ## Acceptance notes - `docs/qa/platform-checklist/FOLLOW-UPS.md` L62 still says "the `IMPORT_CONSOLE_LIVE` import-harness backend". It reads as a loose name for the console spec's backend, not as the retired config, and the file is append-only. Left alone. - On the same item, `acceptance[1].verify`, `acceptance[3].verify` and `knownGaps` still say "the specs" (plural). They do not name the twin, so they were left as written. The next edit of the item can make them singular. - hotcrm's root `package.json` lists `msw` under `pnpm.onlyBuiltDependencies` while declaring no `msw` dependency. That is inert, in another repository, and not filed. ## Verification Gate sweep derived by `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack`. `--ran` reconciliation: **69 derived, 68 run, 1 NOT-MEASURED, 0 UNRUN** (run record: `/mnt/project-files/issue-25921/seat2-harness-msw-gates-ran.txt` in the project). <details><summary>Derived gates: 68 exit 0, 1 NOT MEASURED</summary> - Ran on `6daa99f1` (all files except the amendment's two): 57 families exit 0 in the first loop; `check:skill-examples` exited 3 (prerequisite: `@objectstack/client-react` unbuilt), then exit 0 after building it (281 marked examples type-check). - The changeset-derived families (`check-adr-0087-registration` base and self-test, `check-changeset-no-major`, `check-empty-changeset` base and self-test, `release-rehearsal-clone` and `release-pending-publish` self-tests, `check:changeset-gate-self-tests`, `check:closed-ceremony-text`, `check:pm-changeset-deadline-census`): all exit 0. - `pnpm check:dual-build-cjs-loads`: **NOT MEASURED**. It exits 3 because it needs every package's `dist` ("no packages/connectors/connector-imap/dist … Run `pnpm build` first"), and no full build ran here. CI's `Lint & Repo Gates` covers it. - `node scripts/check-sdui-manifest.mjs` (a ui-card gate, outside this derivation): exit 0. - Re-run on the final head `613632fa` (after the amendment commit and a merge of 17 `origin/main` commits, none touching these files): `check-skills-token-ratchet`, `check:platform-checklist`, `check-sdui-manifest`, `check:nul-bytes`, `check:doc-authoring`, `check:cross-package-test-inputs`, `check:agent-test-spelling`, `check-changeset-no-major`, `check-empty-changeset`, `check-adr-0087-registration`: all exit 0. The derived list on `613632fa` is identical to the one on `6daa99f1`. </details> ## Human Minimum - [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic. (not touched) - [x] 2. Every name I added uses the casing for its kind. - [ ] 3. No formatter ran; `pnpm lint` passes. (no formatter ran; `pnpm lint` not run locally, CI's Lint jobs own it) - [x] 4. One issue, one branch off an up-to-date `main`, one pull request. - [x] 5. A change that publishes carries a changeset, and both declaration lines are filled in here and in the changeset. - [x] 6. `packages/spec` touched: its generated artifacts are regenerated and committed. (not touched) - [x] 7. No hand edits to `content/docs/references/`, `packages/*/CHANGELOG.md` or `content/docs/releases/`. - [x] 8. Title, body and comments are in English. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01QsR2jRhnYmMXKLZruzeoPu --- _Generated by [Claude Code](https://claude.ai/code/session_01QsR2jRhnYmMXKLZruzeoPu)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 1896e31 commit 09abc05

9 files changed

Lines changed: 40 additions & 182 deletions

File tree

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
'@objectstack/skills': patch
3+
---
4+
5+
docs(skills): the objectui testing guide stops teaching msw and shows a fetch double over the real adapter
6+
7+
Clause-②: no
8+
Metadata-protocol: none
9+
10+
- **Before.** `skills/objectui/guides/testing.md` taught "MSW for API mocking in integration tests" with `import … from 'msw'` and `msw/node`. No package in this stack declares `msw` any more, so a test written from the guide cannot resolve its imports.
11+
- **Now.** The subsection shows the pattern this repository's own integration tests use: a `vi.fn` passed as the `fetch` of a real `ObjectStackAdapter`, so the adapter and client run and only the wire is faked. It names one real test as the worked example. The guide stays within its token ceiling (3101 of 3101).

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -579,10 +579,11 @@ contradicts it, and correct it here when it does.
579579

580580
- **An `automated.ref` that names an `objectui` path resolves under `ui/` in this
581581
checkout.** objectui was imported into this repository: its specs and unit suites live at
582-
`ui/<path>` (`ui/e2e/live/*.spec.ts`, `ui/e2e/import-console/*`, `ui/e2e/import-harness/*`,
582+
`ui/<path>` (`ui/e2e/live/*.spec.ts`, `ui/e2e/import-console/*`,
583583
and unit suites under `ui/packages/plugin-grid`, `plugin-gantt`, `plugin-calendar`,
584-
`plugin-form`, `fields`, `core`, `app-shell`), and the console builds from this tree with
585-
`pnpm console:build`. There is no pinned objectui revision any more. Some refs and
584+
`plugin-form`, `fields`, `core`, `app-shell`; the import harness twin was retired on
585+
#25921), and the console builds from this tree with `pnpm console:build`.
586+
There is no pinned objectui revision any more. Some refs and
586587
`fixtures.knownGaps` written before the import still spell the path without `ui/`, or
587588
still say such a pin is not runnable from this checkout; read the first as `ui/<path>`
588589
and the second as stale. A jsdom unit suite runs from `ui/`, the objectui root, with

‎docs/qa/platform-checklist/areas/records-forms.json‎

Lines changed: 15 additions & 9 deletions
Large diffs are not rendered by default.

‎skills/objectui/guides/testing.md‎

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -323,24 +323,16 @@ test('all assets load without 404', async ({ page }) => {
323323

324324
## Mocking strategies
325325

326-
### MSW for API mocking in integration tests
326+
### A fetch double for API mocking
327327

328-
```typescript
329-
import { http, HttpResponse } from 'msw';
330-
import { setupServer } from 'msw/node';
331-
332-
const server = setupServer(
333-
http.get('/api/v1/contacts', () => {
334-
return HttpResponse.json({
335-
records: [{ id: 1, name: 'Alice' }],
336-
total: 1,
337-
});
338-
}),
339-
);
328+
Fake the wire, not the client, as `packages/data-objectstack/src/aggregate-rows-post-unwrap-7028.test.ts` does:
340329

341-
beforeAll(() => server.listen());
342-
afterEach(() => server.resetHandlers());
343-
afterAll(() => server.close());
330+
```typescript
331+
const fetchImpl = vi.fn(async (url: unknown) => Response.json({
332+
success: true,
333+
data: String(url).includes('/discovery') ? { routes: {} } : { records: [{ id: '1' }], total: 1 },
334+
}));
335+
const adapter = new ObjectStackAdapter({ baseUrl: '', fetch: fetchImpl });
344336
```
345337

346338
### Vitest mocks for unit tests

‎ui/e2e/import-harness/import-undo.spec.ts‎

Lines changed: 0 additions & 105 deletions
This file was deleted.

‎ui/package.json‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@
112112
"test:e2e:live": "playwright test --config=playwright.live.config.ts",
113113
"test:e2e:live:ci": "playwright test --config=playwright.live.config.ts screen-flow.spec.ts action-modal.spec.ts master-detail.spec.ts saved-view-filter.spec.ts studio-object-designer.spec.ts studio-editor.spec.ts record-form-direct-url.spec.ts list-row-action-cel.spec.ts",
114114
"test:e2e:live:nightly": "playwright test --config=playwright.live.config.ts cascading-options.spec.ts declared-sharing-rules-reach-13091.spec.ts field-conditional-rules.spec.ts form-view-subforms.spec.ts grid-conditional-rules.spec.ts grid-file-upload.spec.ts grid-parent-rules.spec.ts inline-edit-polish-2572.spec.ts read-only-member-record.spec.ts record-history-display.spec.ts required-when-submit.spec.ts summary-rollup.spec.ts user-filters.spec.ts phone-nav-drawer-back-29131.spec.ts",
115-
"test:e2e:import-harness": "playwright test --config=playwright.import-harness.config.ts",
116115
"test:e2e:import-console": "playwright test --config=playwright.import-console.config.ts"
117116
},
118117
"devDependencies": {

‎ui/playwright.import-console.config.ts‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import { join } from 'node:path';
1111
*
1212
* This differs from:
1313
* - playwright.live.config.ts — general live console specs
14-
* - playwright.import-harness.config.ts — a standalone hand-mounted wizard
1514
*
1615
* Prereqs (long-lived dev processes — NOT started by this config):
1716
* 1. An ObjectStack backend with the async import-job routes

‎ui/playwright.import-harness.config.ts‎

Lines changed: 0 additions & 45 deletions
This file was deleted.

‎ui/scripts/__tests__/e2e-type-check.test.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,14 +333,14 @@ describe('tsconfig.e2e.json — coverage of the root playwright configs (objectu
333333
const onDisk = rootPlaywrightConfigsOnDisk();
334334

335335
// Non-vacuity first, for the same reason as the sweep above: the set
336-
// difference below is satisfied by a discovery that finds nothing. Four
336+
// difference below is satisfied by a discovery that finds nothing. Three
337337
// configs exist today. If one is genuinely retired, lower this floor — but
338338
// never satisfy it by narrowing the pattern in `rootPlaywrightConfigsOnDisk`,
339339
// which would be this gate reporting green about files it stopped looking at.
340340
expect(
341341
onDisk.length,
342342
'no playwright*.config.ts found at the repo root — the discovery is broken',
343-
).toBeGreaterThanOrEqual(4);
343+
).toBeGreaterThanOrEqual(3);
344344

345345
const inProject = programFiles();
346346
const uncovered = onDisk.filter((f) => !inProject.has(f));

0 commit comments

Comments
 (0)