Initial commit: Telegram Management System
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>
This commit is contained in:
你的用户名
2025-11-04 15:37:50 +08:00
commit 237c7802e5
3674 changed files with 525172 additions and 0 deletions

View File

@@ -0,0 +1,305 @@
import { test, expect, Page } from '@playwright/test';
test.describe('菜单验证测试', () => {
let page: Page;
test.beforeAll(async ({ browser }) => {
page = await browser.newPage();
// 设置视口大小以确保菜单完全可见
await page.setViewportSize({ width: 1920, height: 1080 });
// 访问登录页面
await page.goto('http://localhost:5174');
await page.waitForLoadState('networkidle');
// 登录
await page.fill('input[placeholder="请输入用户名"]', 'admin');
await page.fill('input[placeholder="密码"]', '111111');
await page.click('button:has-text("登录")');
// 等待登录成功,跳转到主页
await page.waitForURL(/dashboard/, { timeout: 30000 });
await page.waitForLoadState('networkidle');
console.log('✅ 登录成功');
});
test.afterAll(async () => {
await page.close();
});
test('验证菜单总数和新增菜单项', async () => {
// 等待页面完全加载
await page.waitForTimeout(2000);
// 展开所有菜单项的函数
const expandAllMenus = async () => {
console.log('🔍 开始展开所有菜单项...');
// 找到所有可展开的菜单项
const menuItems = await page.locator('.ant-menu-submenu').all();
console.log(`发现 ${menuItems.length} 个子菜单`);
for (let i = 0; i < menuItems.length; i++) {
try {
const menuItem = menuItems[i];
const isOpen =
(await menuItem.locator('.ant-menu-submenu-open').count()) > 0;
if (!isOpen) {
const menuTitle = await menuItem
.locator('.ant-menu-submenu-title')
.first();
const titleText = await menuTitle.textContent();
console.log(`📂 展开菜单: ${titleText}`);
await menuTitle.click();
await page.waitForTimeout(500); // 等待动画完成
}
} catch (error) {
console.log(`⚠️ 展开菜单项 ${i} 时出错:`, error);
}
}
// 等待所有菜单展开完成
await page.waitForTimeout(1000);
};
// 展开所有菜单
await expandAllMenus();
// 收集所有菜单项
const collectAllMenuItems = async () => {
console.log('📝 开始收集菜单项...');
const menuItems: string[] = [];
// 获取所有菜单项(包含子菜单标题和叶子菜单项)
const allMenuElements = await page
.locator('.ant-menu-item, .ant-menu-submenu-title')
.all();
for (const element of allMenuElements) {
try {
const text = await element.textContent();
if (text && text.trim() && !menuItems.includes(text.trim())) {
menuItems.push(text.trim());
}
} catch (error) {
console.log('收集菜单项时出错:', error);
}
}
return menuItems.sort();
};
const allMenuItems = await collectAllMenuItems();
console.log('📊 所有菜单项列表:');
allMenuItems.forEach((item, index) => {
console.log(`${index + 1}. ${item}`);
});
console.log(`\n📈 菜单总数: ${allMenuItems.length}`);
// 验证新增的菜单项
const expectedNewMenus = [
'工具箱',
'文件上传',
'Excel导入导出',
'WebSocket调试',
'帮助中心',
'系统文档',
'权限示例',
];
console.log('\n🔍 验证新增菜单项:');
const foundNewMenus: string[] = [];
const missingMenus: string[] = [];
expectedNewMenus.forEach((menuName) => {
const found = allMenuItems.some((item) => item.includes(menuName));
if (found) {
foundNewMenus.push(menuName);
console.log(`✅ 找到: ${menuName}`);
} else {
missingMenus.push(menuName);
console.log(`❌ 缺失: ${menuName}`);
}
});
// 统计结果
console.log('\n📊 验证结果总结:');
console.log(`菜单总数: ${allMenuItems.length}`);
console.log(
`新增菜单找到: ${foundNewMenus.length}/${expectedNewMenus.length}`,
);
console.log(`找到的新菜单: ${foundNewMenus.join(', ')}`);
if (missingMenus.length > 0) {
console.log(`❌ 缺失的菜单: ${missingMenus.join(', ')}`);
}
// 特别检查工具箱相关菜单
const toolboxMenus = allMenuItems.filter(
(item) =>
item.includes('工具箱') ||
item.includes('文件上传') ||
item.includes('Excel') ||
item.includes('WebSocket'),
);
console.log('\n🛠 工具箱相关菜单:');
toolboxMenus.forEach((menu) => console.log(` - ${menu}`));
// 特别检查帮助中心相关菜单
const helpMenus = allMenuItems.filter(
(item) =>
item.includes('帮助中心') ||
item.includes('系统文档') ||
item.includes('权限示例'),
);
console.log('\n❓ 帮助中心相关菜单:');
helpMenus.forEach((menu) => console.log(` - ${menu}`));
// 断言验证
expect(allMenuItems.length).toBeGreaterThan(49); // 应该比49个更多
expect(foundNewMenus.length).toBeGreaterThanOrEqual(5); // 至少找到5个新菜单
// 截图保存
await page.screenshot({
path: 'test-results/screenshots/menu-validation-full.png',
fullPage: true,
});
console.log('✅ 菜单验证测试完成');
});
test('详细菜单结构分析', async () => {
// 等待页面加载
await page.waitForTimeout(2000);
console.log('🔍 开始详细菜单结构分析...');
// 获取菜单结构
const menuStructure = await page.evaluate(() => {
const getMenuStructure = (element: Element, level = 0): any => {
const result: any = {};
if (element.classList.contains('ant-menu-submenu')) {
const titleElement = element.querySelector('.ant-menu-submenu-title');
const title = titleElement?.textContent?.trim() || '';
result.title = title;
result.type = 'submenu';
result.level = level;
result.children = [];
const childMenu = element.querySelector('.ant-menu-sub');
if (childMenu) {
const childItems = childMenu.children;
for (let i = 0; i < childItems.length; i++) {
const child = childItems[i];
if (
child.classList.contains('ant-menu-item') ||
child.classList.contains('ant-menu-submenu')
) {
result.children.push(getMenuStructure(child, level + 1));
}
}
}
} else if (element.classList.contains('ant-menu-item')) {
const title = element.textContent?.trim() || '';
result.title = title;
result.type = 'item';
result.level = level;
}
return result;
};
const menuContainer = document.querySelector('.ant-menu-root');
const structure: any[] = [];
if (menuContainer) {
const topLevelItems = menuContainer.children;
for (let i = 0; i < topLevelItems.length; i++) {
const item = topLevelItems[i];
if (
item.classList.contains('ant-menu-item') ||
item.classList.contains('ant-menu-submenu')
) {
structure.push(getMenuStructure(item));
}
}
}
return structure;
});
// 打印菜单结构
const printMenuStructure = (items: any[], indent = '') => {
items.forEach((item) => {
console.log(
`${indent}${item.type === 'submenu' ? '📁' : '📄'} ${item.title}`,
);
if (item.children && item.children.length > 0) {
printMenuStructure(item.children, indent + ' ');
}
});
};
console.log('\n📋 完整菜单结构:');
printMenuStructure(menuStructure);
// 统计菜单数量
const countMenuItems = (items: any[]): number => {
let count = 0;
items.forEach((item) => {
count += 1;
if (item.children && item.children.length > 0) {
count += countMenuItems(item.children);
}
});
return count;
};
const totalMenuCount = countMenuItems(menuStructure);
console.log(`\n📊 菜单结构统计: ${totalMenuCount} 个菜单项`);
// 验证特定菜单的存在
const findMenuInStructure = (
items: any[],
searchTitle: string,
): boolean => {
return items.some((item) => {
if (item.title.includes(searchTitle)) {
return true;
}
if (item.children && item.children.length > 0) {
return findMenuInStructure(item.children, searchTitle);
}
return false;
});
};
const menuChecks = [
'工具箱',
'文件上传',
'Excel导入导出',
'WebSocket调试',
'帮助中心',
'系统文档',
'权限示例',
];
console.log('\n🔍 菜单存在性检查:');
menuChecks.forEach((menuName) => {
const exists = findMenuInStructure(menuStructure, menuName);
console.log(
`${exists ? '✅' : '❌'} ${menuName}: ${exists ? '存在' : '不存在'}`,
);
});
});
});