test(e2e): 覆盖 5i 的字体加载/评论不误报/灯箱关闭/开源页动效(46→55 项)

新增九条断言,把本包修的四类回归固化成门禁:
- 字体真加载:技术轨文章的 document.fonts 必须含 LXGW WenKai Screen 与 WF-Hwmc
  (此前「class 在、计算值对、字体集里没有」是静默失效,只有这条能抓到)
- 评论不误报:进视口挂载后 #artalk-retry 必须保持 hidden,且容器打上 mounted 标记
- 灯箱关闭:点 #lb-close 后 dialog 必须变 closed(此前被右侧全高侧栏吃掉点击,
  表现是点了没反应,只能靠这条兜住)
- 开源页:零第三方外链图 + 打字机存在 + 数据板有自托管资产

验证: E2E_BASE=http://127.0.0.1:18934 node tests/e2e.mjs → 55/55 PASS

Spec: 2026-11-02_blog-5i-fonts-polish

Co-authored-by: GLM-5.3
This commit is contained in:
wait4xandGLM-5.3 committed 2026-11-03 11:50:10 +08:00
1 parent cfe508ff14
commit 6061c16396
1 file changed
+44
+44
View File
@@ -56,6 +56,50 @@ ok('5h·瞬间计数为只读模式', (await page.locator('.mom-cm-meta [data-vi
await page.goto(BASE + '/about/', { waitUntil: 'networkidle' }); await page.goto(BASE + '/about/', { waitUntil: 'networkidle' });
ok('5h·关于页由块驱动', (await page.locator('[data-block]').count()) > 0, `blocks=${await page.locator('[data-block]').count()}`); ok('5h·关于页由块驱动', (await page.locator('[data-block]').count()) > 0, `blocks=${await page.locator('[data-block]').count()}`);
// 0b) Phase 5i:字体真加载 / 评论不误报 / 灯箱关闭 / 开源页动效与数据板
await page.goto(BASE + '/archives/writing-template/', { waitUntil: 'networkidle' });
await page.waitForTimeout(2500);
const fontState = await page.evaluate(() => {
const fams = [...new Set([...document.fonts].map((f) => f.family.replace(/"/g, '')))];
return {
kai: fams.includes('LXGW WenKai Screen'),
huiwen: fams.includes('WF-Hwmc'),
kaiFamily: getComputedStyle(document.querySelector('.font-kai')).fontFamily.split(',')[0].trim(),
};
});
ok('5i·字体真加载(楷体在字体集内)', fontState.kai, fontState.kaiFamily);
ok('5i·汇文明朝按需加载', fontState.huiwen);
await page.evaluate(() => {
const el = document.getElementById('artalk-container');
el?.scrollIntoView();
});
await page.waitForTimeout(3500);
ok('5i·评论不误报(失败提示保持隐藏)', (await page.locator('#artalk-retry').getAttribute('hidden')) !== null);
ok('5i·评论区已挂载', (await page.locator('#artalk-container[data-artalk-mounted="1"]').count()) === 1);
await page.goto(BASE + '/gallery/', { waitUntil: 'networkidle' });
await page.locator('.shot-btn').first().click();
await page.waitForTimeout(400);
ok('5i·灯箱可开', (await page.locator('#lb[open]').count()) === 1);
await page.locator('#lb-close').click({ timeout: 5000 }).catch(() => {});
await page.waitForTimeout(300);
ok('5i·灯箱右上关闭真的能关', (await page.locator('#lb[open]').count()) === 0);
await page.goto(BASE + '/opensource/', { waitUntil: 'networkidle' });
const osState = await page.evaluate(() => {
const html = document.documentElement.outerHTML;
return {
thirdParty: ['img.shields.io', 'readme-typing-svg', 'github-readme-stats', 'streak-stats', 'komarev']
.some((u) => html.includes(u)),
typing: !!document.querySelector('[class*=typing]'),
board: document.querySelectorAll('.pf-card').length,
localAssets: [...document.querySelectorAll('img')].filter((i) => i.src.includes('/github-assets/')).length,
};
});
ok('5i·开源页零第三方外链图', !osState.thirdParty);
ok('5i·打字机动效存在', osState.typing);
ok('5i·数据板渲染', osState.board > 0 && osState.localAssets > 0, `cards=${osState.board} assets=${osState.localAssets}`);
// 1) 明暗切换:按钮 + 状态持久 + t 键 // 1) 明暗切换:按钮 + 状态持久 + t 键
const before = await page.getAttribute('html', 'data-theme'); const before = await page.getAttribute('html', 'data-theme');
await page.click('[data-theme-toggle]'); await page.click('[data-theme-toggle]');