- 新增 ADR 架构决策记录 (Design DNA 集成与深化) - 新增 CMS 系统设计文档 - 新增实施计划文档 (Phase1-3) - 新增 Bain 品牌升级设计规格 - 新增 E2E 分层测试套件 (P1-P4) - 新增视觉回归测试配置 - 新增光效分析、视觉验证等辅助脚本 - 更新验收测试报告
91 lines
3.0 KiB
JavaScript
91 lines
3.0 KiB
JavaScript
const { chromium } = require('@playwright/test');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const BASE_URL = 'http://localhost:3000';
|
|
const OUTPUT_DIR = '/tmp/screenshots/phase7-visual-test';
|
|
|
|
const PAGES = [
|
|
{ name: '01-home', path: '/' },
|
|
{ name: '02-products-list', path: '/products' },
|
|
{ name: '03-product-detail-erp', path: '/products/erp' },
|
|
{ name: '04-solutions-list', path: '/solutions' },
|
|
{ name: '05-solutions-detail', path: '/solutions/manufacturing' },
|
|
{ name: '06-services-list', path: '/services' },
|
|
{ name: '07-service-detail', path: '/services/consulting' },
|
|
{ name: '08-about', path: '/about' },
|
|
{ name: '09-contact', path: '/contact' },
|
|
{ name: '10-news-list', path: '/news' },
|
|
{ name: '11-team', path: '/team' },
|
|
];
|
|
|
|
const VIEWPORTS = [
|
|
{ name: 'mobile', width: 390, height: 844 },
|
|
{ name: 'tablet', width: 768, height: 1024 },
|
|
{ name: 'desktop', width: 1440, height: 900 },
|
|
];
|
|
|
|
async function runVisualTest() {
|
|
if (!fs.existsSync(OUTPUT_DIR)) {
|
|
fs.mkdirSync(OUTPUT_DIR, { recursive: true });
|
|
}
|
|
|
|
const browser = await chromium.launch();
|
|
const results = [];
|
|
|
|
for (const viewport of VIEWPORTS) {
|
|
const viewportDir = path.join(OUTPUT_DIR, viewport.name);
|
|
if (!fs.existsSync(viewportDir)) {
|
|
fs.mkdirSync(viewportDir, { recursive: true });
|
|
}
|
|
|
|
const page = await browser.newPage({
|
|
viewport: { width: viewport.width, height: viewport.height },
|
|
});
|
|
|
|
for (const pageInfo of PAGES) {
|
|
const url = `${BASE_URL}${pageInfo.path}`;
|
|
const screenshotPath = path.join(viewportDir, `${pageInfo.name}.png`);
|
|
|
|
try {
|
|
console.log(`[${viewport.name}] Capturing: ${pageInfo.name}...`);
|
|
await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 45000 });
|
|
await page.waitForTimeout(2000);
|
|
await page.screenshot({ path: screenshotPath, fullPage: true });
|
|
results.push({ viewport: viewport.name, page: pageInfo.name, status: 'success', path: screenshotPath });
|
|
console.log(` ✓ Saved to ${screenshotPath}`);
|
|
} catch (error) {
|
|
results.push({ viewport: viewport.name, page: pageInfo.name, status: 'failed', error: error.message });
|
|
console.log(` ✗ Failed: ${error.message}`);
|
|
}
|
|
}
|
|
|
|
await page.close();
|
|
}
|
|
|
|
await browser.close();
|
|
|
|
const successCount = results.filter(r => r.status === 'success').length;
|
|
const failCount = results.filter(r => r.status === 'failed').length;
|
|
|
|
console.log('\n' + '='.repeat(60));
|
|
console.log('Visual Test Summary');
|
|
console.log('='.repeat(60));
|
|
console.log(`Total: ${results.length} pages`);
|
|
console.log(`Success: ${successCount}`);
|
|
console.log(`Failed: ${failCount}`);
|
|
console.log(`Output: ${OUTPUT_DIR}`);
|
|
console.log('='.repeat(60));
|
|
|
|
if (failCount > 0) {
|
|
console.log('\nFailed pages:');
|
|
results.filter(r => r.status === 'failed').forEach(r => {
|
|
console.log(` - [${r.viewport}] ${r.page}: ${r.error}`);
|
|
});
|
|
}
|
|
|
|
return results;
|
|
}
|
|
|
|
runVisualTest().catch(console.error);
|