网页侧证据复跑并修掉 Vite 冷启动造成的假失败
Project CI / AI game creator shell Rust crates (push) Successful in 1m33s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m45s
Project CI / AI game creator shell Rust lane 2/2 (push) Has been cancelled
Project CI / Frontend tests (push) Has been cancelled
Project CI / Repository checks (push) Has been cancelled
Project CI / Backend tests (push) Has been cancelled
Project CI / AI game creator shell web tests (push) Has been cancelled
Project CI / AI game creator shell Rust lane 1/2 (push) Has been cancelled
Project CI / Native shell tests (push) Has been cancelled
Project CI / AI game creator shell Rust crates (push) Successful in 1m33s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m45s
Project CI / AI game creator shell Rust lane 2/2 (push) Has been cancelled
Project CI / Frontend tests (push) Has been cancelled
Project CI / Repository checks (push) Has been cancelled
Project CI / Backend tests (push) Has been cancelled
Project CI / AI game creator shell web tests (push) Has been cancelled
Project CI / AI game creator shell Rust lane 1/2 (push) Has been cancelled
Project CI / Native shell tests (push) Has been cancelled
- check-game-distribution-web-e2e:导航前先 fetch 预热 /games、/games/detail、/games/play 三条路由(120s 上限,失败只告警),首个 goto 超时提到 120s,避免 Vite dev 冷启动(实测 /games 首请求 20.2s、warm 后 14ms)被当成页面故障 - 复跑合并 Web 预检改动之后的网页侧四条 E2E:web-e2e 24/24 PASS、web-publish 全过、web-publish-recovery 全过、web-a11y 全过 - 里程碑补「网页侧证据复跑(2026-09-29)」小节;pitfalls 记录冷启动判据与修法
This commit is contained in:
@@ -38,6 +38,23 @@ function check(name, ok, detail = '') {
|
||||
);
|
||||
}
|
||||
|
||||
// Vite dev 是按需编译的:某条路由第一次被访问时现编译模块图,实测 /games 冷启动可以到
|
||||
// 20 秒以上,超过导航默认超时就会被当成"页面打不开"。先预热一遍路由,把冷启动从断言
|
||||
// 语义里摘出去(预热失败不致命:真正导航时还会再试一次,失败信息照旧可见)。
|
||||
async function warmUpWebRoute(url, timeoutMs = 120_000) {
|
||||
const controller = new AbortController();
|
||||
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
||||
try {
|
||||
const response = await fetch(url, { signal: controller.signal });
|
||||
await response.arrayBuffer();
|
||||
console.log(`[warmup] ${url} -> ${response.status}`);
|
||||
} catch (error) {
|
||||
console.warn(`[warmup] ${url} 预热失败,导航阶段会再试一次:${error}`);
|
||||
} finally {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
}
|
||||
|
||||
async function api(pathname, options = {}) {
|
||||
const { method = 'GET', token, body, headers = {}, binary } = options;
|
||||
const finalHeaders = { ...ENVELOPE, ...headers };
|
||||
@@ -265,6 +282,15 @@ async function main() {
|
||||
const title = `网页链路 ${String(stamp).slice(-6)}`;
|
||||
const { gameId } = await publishFixtureGame(stamp, title);
|
||||
|
||||
// 先把这次要用到的三条网页路由预热一遍,避免 dev 冷启动把它们误伤成"打不开"。
|
||||
for (const route of [
|
||||
'/games',
|
||||
`/games/detail?id=${gameId}`,
|
||||
`/games/play?id=${gameId}`,
|
||||
]) {
|
||||
await warmUpWebRoute(`${WEB}${route}`);
|
||||
}
|
||||
|
||||
const { chromium } = await loadPlaywright();
|
||||
const executablePath = (process.env.E2E_CHROMIUM_EXECUTABLE ?? '').trim();
|
||||
const browser = await chromium.launch({
|
||||
@@ -281,7 +307,11 @@ async function main() {
|
||||
// 平台顶栏也有一个全局搜索框,这里只取游戏目录自己的筛选输入。
|
||||
const searchInput = page.locator('label.game-search input');
|
||||
|
||||
await page.goto(`${WEB}/games`, { waitUntil: 'domcontentloaded' });
|
||||
// 即使预热过了,首次导航仍可能撞上按需编译的尾巴:给足超时,别把编译慢判成页面故障。
|
||||
await page.goto(`${WEB}/games`, {
|
||||
waitUntil: 'domcontentloaded',
|
||||
timeout: 120_000,
|
||||
});
|
||||
await card.waitFor({ state: 'visible', timeout: 20_000 });
|
||||
check('游客目录用真实数据显示已发布游戏', await card.isVisible());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user