Skip to content

Commit a400717

Browse files
chaxusclaude
andcommitted
test(sw): the silent-update case rewrites the served worker, so it runs alone
Simulating a deploy means rewriting dist/sw.js, which the whole origin shares: run beside other cases it replaced their service worker mid-test and wiped the cache under them (an editor mid-load could no longer fetch spell.wasm, and the cache-first case stopped seeing its cached asset). It is @serial now, and it skips where the served files are not on this disk -- the Docker image reported exactly that as ENOENT. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 75a4de0 commit a400717

2 files changed

Lines changed: 21 additions & 2 deletions

File tree

‎docs/explorations/2026-08-22-stale-build-and-panel-flash.md‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,15 @@ Qjgbc rgjc / Qjgbc qs`rgjc / Ajgai rm_bb l mrcq
121121
| `test/unit/update-prompt.test.ts` 五条(出现一次、点刷新会 SKIP_WAITING、接管后 reload 一次、超时兜底、忽略不动 worker) | — |
122122
| `test/e2e/entry-paths.spec.ts` 的"the home-state panel never shows while a named document loads"(从首帧起连采 12 次) | 去掉 `opening-document` 那一行 → 用例报 `the panel was painted while the document was loading` |
123123

124+
### 这条用例必须 `@serial`
125+
126+
第一版没打标签,CI 里连带弄红了同分片的另外两条。原因是它"模拟部署"的手段是改写
127+
**整个源站共用的** `dist/sw.js`:并行跑时别的用例的 worker 也会被换掉,缓存在它们
128+
脚下被清空——一个正在加载的编辑器于是取不到 `spell.wasm`,`sw-vendor-cache-first`
129+
也看不到自己缓存的资源。打上 `@serial` 之后它只在单 worker 那一趟跑;Docker 与
130+
Pages 两趟本来就 `--grep-invert @serial`,而且那里的文件根本不在本机磁盘上
131+
(Docker 那次报的就是 `ENOENT: dist/sw.js`),所以再加一条"文件不在就 skip"。
132+
124133
## 给下一个人
125134

126135
- 面板默认可见这件事本身是个坑:任何新的"启动时决定开什么"的入口(新的 query 参数、

‎test/e2e/sw-silent-update.spec.ts‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { readFileSync, writeFileSync } from 'node:fs';
1+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
22
import { resolve } from 'node:path';
33
import { expect, test } from './lib/l0';
44
import { settleEditor } from './lib/visual';
@@ -20,6 +20,13 @@ import { settleEditor } from './lib/visual';
2020
* The test deploys a second build the only way a static preview can: it
2121
* rewrites the vendor stamp inside the served sw.js, which is exactly what
2222
* bin/build.sh does when the vendored tree changes.
23+
*
24+
* That rewrite is visible to the whole origin, so this case is `@serial`: run
25+
* beside others it replaces THEIR service worker mid-test too, which wipes the
26+
* cache under them (an editor mid-load then fails to fetch spell.wasm, and the
27+
* cache-first case stops seeing its cached asset). It is skipped where the
28+
* served files are not on this disk -- the Docker image and any run against a
29+
* deployed site.
2330
*/
2431
const PORT = process.env.E2E_PORT ?? '4173';
2532
const OUT_DIR = process.env.E2E_PORT ? `dist-e2e-${PORT}` : 'dist';
@@ -38,8 +45,11 @@ const controllerVendorVersion = (page: import('@playwright/test').Page) =>
3845
});
3946
});
4047

41-
test.describe('a stale build heals itself', () => {
48+
test.describe('a stale build heals itself @serial', () => {
4249
test.describe.configure({ timeout: 240_000 });
50+
// The container and a deployed site serve their own copy; there is nothing
51+
// here to rewrite, and no way to deploy a second build mid-run.
52+
test.skip(!existsSync(SW_PATH), 'needs the locally built site this run is serving');
4353

4454
let original = '';
4555
test.beforeAll(() => {

0 commit comments

Comments
 (0)