200 lines
5.5 KiB
JavaScript
200 lines
5.5 KiB
JavaScript
|
|
/**
|
|||
|
|
* 完整的 MCP Playwright 测试 - 包含登录流程
|
|||
|
|
*/
|
|||
|
|
const { chromium } = require('playwright');
|
|||
|
|
const fs = require('fs');
|
|||
|
|
|
|||
|
|
const BASE_URL = 'http://localhost:3000';
|
|||
|
|
const SCREENSHOT_DIR = 'screenshots/complete-test';
|
|||
|
|
const TEST_USER = {
|
|||
|
|
username: 'testuser',
|
|||
|
|
password: 'Password123@'
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
if (!fs.existsSync(SCREENSHOT_DIR)) {
|
|||
|
|
fs.mkdirSync(SCREENSHOT_DIR, { recursive: true });
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
(async () => {
|
|||
|
|
console.log('🎭 开始完整测试(包含登录)...\n');
|
|||
|
|
|
|||
|
|
const browser = await chromium.launch({
|
|||
|
|
headless: false,
|
|||
|
|
channel: 'chrome'
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const context = await browser.newContext({
|
|||
|
|
viewport: { width: 1280, height: 720 }
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const page = await context.newPage();
|
|||
|
|
|
|||
|
|
// 监听控制台
|
|||
|
|
const errors = [];
|
|||
|
|
page.on('console', msg => {
|
|||
|
|
if (msg.type() === 'error') {
|
|||
|
|
errors.push(`[Console] ${msg.text()}`);
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
page.on('pageerror', error => {
|
|||
|
|
errors.push(`[Page] ${error.message}`);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
console.log('🔐 步骤 1: 登录');
|
|||
|
|
console.log(' 访问登录页面...');
|
|||
|
|
await page.goto(`${BASE_URL}/`, {
|
|||
|
|
waitUntil: 'networkidle',
|
|||
|
|
timeout: 30000
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
await page.waitForTimeout(1000);
|
|||
|
|
|
|||
|
|
// 截图登录页
|
|||
|
|
await page.screenshot({
|
|||
|
|
path: `${SCREENSHOT_DIR}/00-login.png`,
|
|||
|
|
fullPage: true
|
|||
|
|
});
|
|||
|
|
console.log(' ✅ 登录页面截图');
|
|||
|
|
|
|||
|
|
// 尝试登录
|
|||
|
|
console.log(' 填写登录信息...');
|
|||
|
|
try {
|
|||
|
|
const usernameInput = page.locator('input[type="text"]').first();
|
|||
|
|
const passwordInput = page.locator('input[type="password"]').first();
|
|||
|
|
|
|||
|
|
await usernameInput.fill(TEST_USER.username);
|
|||
|
|
await passwordInput.fill(TEST_USER.password);
|
|||
|
|
|
|||
|
|
console.log(' 点击登录按钮...');
|
|||
|
|
const loginButton = page.locator('button').filter({ hasText: /登录|Login/i }).first();
|
|||
|
|
await loginButton.click();
|
|||
|
|
|
|||
|
|
// 等待导航
|
|||
|
|
console.log(' 等待登录完成...');
|
|||
|
|
await page.waitForTimeout(3000);
|
|||
|
|
|
|||
|
|
// 截图登录后
|
|||
|
|
await page.screenshot({
|
|||
|
|
path: `${SCREENSHOT_DIR}/00-after-login.png`,
|
|||
|
|
fullPage: true
|
|||
|
|
});
|
|||
|
|
console.log(' ✅ 登录后截图');
|
|||
|
|
|
|||
|
|
} catch (error) {
|
|||
|
|
console.log(` ⚠️ 登录过程: ${error.message}`);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 测试各个页面
|
|||
|
|
const pages = [
|
|||
|
|
{ name: '01-homepage', url: '/', title: '首页' },
|
|||
|
|
{ name: '02-dashboard', url: '/dashboard', title: '仪表盘' },
|
|||
|
|
{ name: '03-documents', url: '/documents', title: '文档管理' },
|
|||
|
|
{ name: '04-todos', url: '/todos', title: '待办事项' },
|
|||
|
|
{ name: '05-images', url: '/images', title: '图片管理' }
|
|||
|
|
];
|
|||
|
|
|
|||
|
|
const results = [];
|
|||
|
|
|
|||
|
|
for (const pageInfo of pages) {
|
|||
|
|
console.log(`\n📄 测试: ${pageInfo.title} (${pageInfo.url})`);
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
await page.goto(`${BASE_URL}${pageInfo.url}`, {
|
|||
|
|
waitUntil: 'networkidle',
|
|||
|
|
timeout: 30000
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 等待页面渲染
|
|||
|
|
await page.waitForTimeout(2000);
|
|||
|
|
|
|||
|
|
// 获取页面信息
|
|||
|
|
const pageInfo_data = await page.evaluate(() => {
|
|||
|
|
return {
|
|||
|
|
title: document.title,
|
|||
|
|
url: window.location.pathname,
|
|||
|
|
bodyText: document.body.innerText.substring(0, 300),
|
|||
|
|
hasLayout: !!document.querySelector('[class*="layout"]'),
|
|||
|
|
hasSidebar: !!document.querySelector('[class*="sidebar"]'),
|
|||
|
|
cardCount: document.querySelectorAll('[class*="card"]').length
|
|||
|
|
};
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 截图
|
|||
|
|
const screenshotPath = `${SCREENSHOT_DIR}/${pageInfo.name}.png`;
|
|||
|
|
await page.screenshot({
|
|||
|
|
path: screenshotPath,
|
|||
|
|
fullPage: true
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
console.log(` ✅ 截图: ${screenshotPath}`);
|
|||
|
|
console.log(` 📋 URL: ${pageInfo_data.url}`);
|
|||
|
|
console.log(` 📝 内容长度: ${pageInfo_data.bodyText.length} 字符`);
|
|||
|
|
console.log(` 🎴 卡片数: ${pageInfo_data.cardCount}`);
|
|||
|
|
console.log(` 📐 有布局: ${pageInfo_data.hasLayout ? '是' : '否'}`);
|
|||
|
|
|
|||
|
|
results.push({
|
|||
|
|
page: pageInfo.title,
|
|||
|
|
url: pageInfo.url,
|
|||
|
|
success: true,
|
|||
|
|
hasContent: pageInfo_data.bodyText.length > 100,
|
|||
|
|
contentPreview: pageInfo_data.bodyText.substring(0, 100).replace(/\n/g, ' ')
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error(` ❌ 错误: ${error.message}`);
|
|||
|
|
results.push({
|
|||
|
|
page: pageInfo.title,
|
|||
|
|
url: pageInfo.url,
|
|||
|
|
success: false,
|
|||
|
|
hasContent: false,
|
|||
|
|
error: error.message
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 生成报告
|
|||
|
|
console.log('\n' + '='.repeat(60));
|
|||
|
|
console.log('📊 测试结果汇总');
|
|||
|
|
console.log('='.repeat(60));
|
|||
|
|
|
|||
|
|
results.forEach(r => {
|
|||
|
|
const status = r.success && r.hasContent ? '✅' : '⚠️';
|
|||
|
|
console.log(`${status} ${r.page}`);
|
|||
|
|
console.log(` URL: ${r.url}`);
|
|||
|
|
if (r.contentPreview) {
|
|||
|
|
console.log(` 内容: ${r.contentPreview}...`);
|
|||
|
|
}
|
|||
|
|
if (r.error) {
|
|||
|
|
console.log(` 错误: ${r.error}`);
|
|||
|
|
}
|
|||
|
|
console.log('');
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
const passed = results.filter(r => r.success && r.hasContent).length;
|
|||
|
|
const total = results.length;
|
|||
|
|
|
|||
|
|
console.log(`总计: ${passed}/${total} 页面有正常内容 (${((passed/total)*100).toFixed(0)}%)`);
|
|||
|
|
|
|||
|
|
if (errors.length > 0) {
|
|||
|
|
console.log('\n⚠️ 控制台错误:');
|
|||
|
|
errors.forEach(e => console.log(` - ${e}`));
|
|||
|
|
} else {
|
|||
|
|
console.log('\n✅ 无控制台错误 - 所有页面展示正常!');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
console.log(`\n📸 所有截图保存在: ${SCREENSHOT_DIR}/`);
|
|||
|
|
|
|||
|
|
// 保存结果
|
|||
|
|
fs.writeFileSync(
|
|||
|
|
'complete-test-results.json',
|
|||
|
|
JSON.stringify({ results, errors }, null, 2)
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
console.log('\n⏳ 5秒后关闭浏览器...');
|
|||
|
|
await page.waitForTimeout(5000);
|
|||
|
|
|
|||
|
|
await browser.close();
|
|||
|
|
console.log('\n🎉 测试完成!');
|
|||
|
|
})();
|