Some checks failed
Deploy / deploy (push) Has been cancelled
Full-stack web application for Telegram management - Frontend: Vue 3 + Vben Admin - Backend: NestJS - Features: User management, group broadcast, statistics 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
220 lines
6.4 KiB
TypeScript
220 lines
6.4 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
||
|
||
test('详细菜单检查', async ({ page }) => {
|
||
// 设置视口大小
|
||
await page.setViewportSize({ width: 1920, height: 1080 });
|
||
|
||
console.log('🚀 开始菜单检查测试...');
|
||
|
||
// 访问登录页面
|
||
await page.goto('http://localhost:5174');
|
||
await page.waitForLoadState('networkidle');
|
||
|
||
console.log('📝 填写登录信息...');
|
||
// 登录
|
||
await page.fill('input[placeholder="请输入用户名"]', 'admin');
|
||
await page.fill('input[placeholder="密码"]', '111111');
|
||
await page.click('button:has-text("登录")');
|
||
|
||
// 等待登录成功
|
||
console.log('⏳ 等待登录成功...');
|
||
await page.waitForURL(/dashboard/, { timeout: 30000 });
|
||
await page.waitForLoadState('networkidle');
|
||
await page.waitForTimeout(3000); // 额外等待确保页面完全加载
|
||
|
||
console.log('✅ 登录成功,当前URL:', page.url());
|
||
|
||
// 截图查看登录后的页面
|
||
await page.screenshot({
|
||
path: 'test-results/screenshots/after-login-full.png',
|
||
fullPage: true,
|
||
});
|
||
|
||
// 查找侧边栏菜单
|
||
console.log('🔍 查找侧边栏菜单...');
|
||
|
||
// 尝试不同的菜单选择器
|
||
const menuSelectors = [
|
||
'.ant-menu',
|
||
'.ant-layout-sider .ant-menu',
|
||
'[class*="menu"]',
|
||
'[class*="sidebar"]',
|
||
'[class*="nav"]',
|
||
'.vben-layout-menu',
|
||
'.layout-menu',
|
||
'aside',
|
||
'.ant-layout-sider',
|
||
];
|
||
|
||
for (const selector of menuSelectors) {
|
||
const elements = await page.locator(selector).count();
|
||
console.log(`选择器 "${selector}": 找到 ${elements} 个元素`);
|
||
|
||
if (elements > 0) {
|
||
const element = page.locator(selector).first();
|
||
const isVisible = await element.isVisible();
|
||
console.log(` - 第一个元素可见: ${isVisible}`);
|
||
|
||
if (isVisible) {
|
||
const text = await element.textContent();
|
||
const preview = text ? text.substring(0, 200) + '...' : '无文本内容';
|
||
console.log(` - 内容预览: ${preview}`);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 查找所有可能的菜单项
|
||
console.log('\n🎯 查找所有可能的菜单项...');
|
||
|
||
const menuItemSelectors = [
|
||
'.ant-menu-item',
|
||
'.ant-menu-submenu',
|
||
'.ant-menu-submenu-title',
|
||
'[role="menuitem"]',
|
||
'[class*="menu-item"]',
|
||
'a[href*="/"]',
|
||
'li[class*="menu"]',
|
||
];
|
||
|
||
let allMenuItems: string[] = [];
|
||
|
||
for (const selector of menuItemSelectors) {
|
||
try {
|
||
const elements = await page.locator(selector).all();
|
||
console.log(`\n选择器 "${selector}": 找到 ${elements.length} 个元素`);
|
||
|
||
for (let i = 0; i < Math.min(elements.length, 20); i++) {
|
||
// 限制输出数量
|
||
const element = elements[i];
|
||
const isVisible = await element.isVisible();
|
||
if (isVisible) {
|
||
const text = await element.textContent();
|
||
if (text && text.trim()) {
|
||
const trimmedText = text.trim();
|
||
if (!allMenuItems.includes(trimmedText)) {
|
||
allMenuItems.push(trimmedText);
|
||
console.log(` ${i + 1}. "${trimmedText}"`);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.log(`选择器 "${selector}" 出错:`, error);
|
||
}
|
||
}
|
||
|
||
console.log(`\n📊 总共收集到 ${allMenuItems.length} 个不重复的菜单项`);
|
||
|
||
// 查找页面中的所有文本,看是否包含我们期望的菜单
|
||
console.log('\n🔍 在页面中搜索特定菜单名称...');
|
||
const pageContent = await page.content();
|
||
|
||
const expectedMenus = [
|
||
'工具箱',
|
||
'文件上传',
|
||
'Excel导入导出',
|
||
'WebSocket调试',
|
||
'帮助中心',
|
||
'系统文档',
|
||
'权限示例',
|
||
'群发任务',
|
||
'群发日志',
|
||
'账号管理',
|
||
'智能姓名管理',
|
||
];
|
||
|
||
expectedMenus.forEach((menuName) => {
|
||
const found = pageContent.includes(menuName);
|
||
console.log(
|
||
`${found ? '✅' : '❌'} "${menuName}": ${found ? '在页面中找到' : '未找到'}`,
|
||
);
|
||
});
|
||
|
||
// 尝试点击可能的菜单展开按钮
|
||
console.log('\n🖱️ 尝试展开菜单...');
|
||
|
||
const expandSelectors = [
|
||
'.ant-menu-submenu-arrow',
|
||
'.ant-menu-submenu-title',
|
||
'[class*="collapse"]',
|
||
'[class*="expand"]',
|
||
'button[aria-expanded]',
|
||
];
|
||
|
||
for (const selector of expandSelectors) {
|
||
try {
|
||
const elements = await page.locator(selector).all();
|
||
console.log(`展开选择器 "${selector}": 找到 ${elements.length} 个元素`);
|
||
|
||
for (let i = 0; i < Math.min(elements.length, 5); i++) {
|
||
const element = elements[i];
|
||
const isVisible = await element.isVisible();
|
||
if (isVisible) {
|
||
console.log(` 点击第 ${i + 1} 个展开元素`);
|
||
await element.click();
|
||
await page.waitForTimeout(500);
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.log(`展开选择器 "${selector}" 出错:`, error);
|
||
}
|
||
}
|
||
|
||
// 再次截图查看展开后的效果
|
||
await page.screenshot({
|
||
path: 'test-results/screenshots/after-expand-menus.png',
|
||
fullPage: true,
|
||
});
|
||
|
||
// 最后再次收集菜单项
|
||
console.log('\n📝 展开后重新收集菜单项...');
|
||
|
||
const finalMenuItems: string[] = [];
|
||
|
||
for (const selector of menuItemSelectors) {
|
||
try {
|
||
const elements = await page.locator(selector).all();
|
||
|
||
for (const element of elements) {
|
||
const isVisible = await element.isVisible();
|
||
if (isVisible) {
|
||
const text = await element.textContent();
|
||
if (text && text.trim()) {
|
||
const trimmedText = text.trim();
|
||
if (!finalMenuItems.includes(trimmedText)) {
|
||
finalMenuItems.push(trimmedText);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
} catch (error) {
|
||
console.log(`最终收集选择器 "${selector}" 出错:`, error);
|
||
}
|
||
}
|
||
|
||
console.log('\n📋 最终菜单列表:');
|
||
finalMenuItems.sort().forEach((item, index) => {
|
||
console.log(`${index + 1}. ${item}`);
|
||
});
|
||
|
||
console.log(`\n🎉 最终统计: 共找到 ${finalMenuItems.length} 个菜单项`);
|
||
|
||
// 检查新增菜单
|
||
const foundNewMenus = expectedMenus.filter((menu) =>
|
||
finalMenuItems.some((item) => item.includes(menu)),
|
||
);
|
||
|
||
console.log('\n✨ 新增菜单检查结果:');
|
||
console.log(
|
||
`找到的新菜单 (${foundNewMenus.length}/${expectedMenus.length}): ${foundNewMenus.join(', ')}`,
|
||
);
|
||
|
||
const missingMenus = expectedMenus.filter(
|
||
(menu) => !finalMenuItems.some((item) => item.includes(menu)),
|
||
);
|
||
|
||
if (missingMenus.length > 0) {
|
||
console.log(`❌ 缺失的菜单: ${missingMenus.join(', ')}`);
|
||
}
|
||
});
|