import { test, expect } from '@playwright/test';
import fs from 'node:fs';
import { fileURLToPath } from 'node:url';
/**
* 阶段 D 辅助:采集各页面 fullPage 截图,供视觉比对设计稿
* 运行:npm run test:capture
*/
const ROOT = fileURLToPath(new URL('../.artifacts/screenshots/', import.meta.url));
/** 主要走查页面(名 → 路径) */
const PAGES: Array<[String, String]> = [
['home', '/'],
['list-core', '/core'],
['detail-core-nav', '/core/nav'],
['detail-events-talk', '/events/night_talks_004'],
['product-newlife', '/blood/newlife'],
['product-stardust', '/blood/stardust'],
['search-result', '/search-%E5%BA%8F%E5%88%97%E5%8C%96'],
['search-empty', '/search-%E4%B8%8D%E5%AD%98%E5%9C%A8%E8%AF%8D%E6%9D%A1zzz'],
];
test.describe('截图采集', () => {
test.beforeEach(async () => { await new Promise((r) => setTimeout(r, 1200)); });
for (const [name, path] of PAGES) {
test(`截图 ${name}`, async ({ page }, testInfo) => {
const dir = `${ROOT}/${testInfo.project.name}`;
fs.mkdirSync(dir, { recursive: true });
const errors: String[] = [];
page.on('pageerror', (e) => errors.push(e.message));
page.on('console', (m) => {
if (m.type() === 'error') errors.push(m.text());
});
const resp = await page.goto(String(path), { waitUntil: 'load' });
expect(resp && resp.status(), `${path} 返回 ${resp && resp.status()}`).toBeLessThan(400);
// 等待字体/懒加载稳定后截图(不能用 networkidle:产品页有常驻请求)
await page.waitForTimeout(2000);
// 限流降级检测:命中限流页则不落脏截图
const limited = await page.evaluate(() => document.body.innerText.includes('访问太频繁')).catch(() => false);
expect(limited, `${path} 命中限流页,需重试`).toBe(false);
await page.screenshot({ path: `${dir}/${name}.png`, fullPage: true });
if (errors.length > 0) {
fs.writeFileSync(`${dir}/${name}.errors.txt`, errors.join('\n'), 'utf-8');
}
});
}
});
|