docs(test): 添加设计文档、测试规范与 E2E 测试套件

- 新增 ADR 架构决策记录 (Design DNA 集成与深化)
- 新增 CMS 系统设计文档
- 新增实施计划文档 (Phase1-3)
- 新增 Bain 品牌升级设计规格
- 新增 E2E 分层测试套件 (P1-P4)
- 新增视觉回归测试配置
- 新增光效分析、视觉验证等辅助脚本
- 更新验收测试报告
This commit is contained in:
张翔
2026-07-07 06:54:25 +08:00
parent 8def296301
commit 636bc4ecde
31 changed files with 9262 additions and 41 deletions
+90
View File
@@ -0,0 +1,90 @@
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);