const { chromium } = require('playwright'); const fs = require('fs'); (async () => { let browser; try { console.log('启动浏览器收集菜单...'); browser = await chromium.launch({ headless: false, slowMo: 300 }); const context = await browser.newContext({ viewport: { width: 1920, height: 1080 } }); const page = await context.newPage(); // 登录 console.log('\n执行登录...'); await page.goto('http://localhost:5174/', { waitUntil: 'networkidle' }); await page.fill('[name="username"]', 'admin'); await page.fill('[name="password"]', '111111'); await page.click('button:has-text("登录")'); await page.waitForTimeout(2000); // 访问首页 if (page.url().includes('login')) { await page.goto('http://localhost:5174/dashboard/home', { waitUntil: 'networkidle' }); } await page.waitForTimeout(1000); console.log('\n查找菜单容器...'); // 尝试不同的选择器 const menuSelectors = [ '.ant-menu', '[role="menu"]', '.ant-layout-sider .ant-menu', 'aside .ant-menu', '.sidebar-menu', '.menu-container' ]; let menuContainer = null; for (const selector of menuSelectors) { const count = await page.locator(selector).count(); if (count > 0) { console.log(`✓ 找到菜单容器: ${selector}`); menuContainer = selector; break; } } if (!menuContainer) { console.log('❌ 未找到菜单容器'); return; } // 获取所有菜单项的文本 console.log('\n收集菜单项...'); const menuData = await page.evaluate((selector) => { const container = document.querySelector(selector); if (!container) return []; const menus = []; // 收集所有菜单项 const allItems = container.querySelectorAll('.ant-menu-item, .ant-menu-submenu'); allItems.forEach(item => { const text = item.textContent?.trim(); if (text) { const isSubmenu = item.classList.contains('ant-menu-submenu'); const level = item.closest('.ant-menu-sub') ? 2 : 1; menus.push({ text: text, isSubmenu: isSubmenu, level: level, classes: Array.from(item.classList) }); } }); return menus; }, menuContainer); console.log(`\n找到 ${menuData.length} 个菜单项:`); menuData.forEach((menu, index) => { const prefix = menu.level === 2 ? ' └─ ' : ''; const type = menu.isSubmenu ? '[目录]' : '[菜单]'; console.log(`${index + 1}. ${prefix}${type} ${menu.text}`); }); // 进一步整理菜单结构 const structuredMenus = []; let currentParent = null; for (const menu of menuData) { if (menu.level === 1) { if (menu.isSubmenu) { currentParent = menu.text; } else { structuredMenus.push({ name: menu.text, parent: null, type: 'menu-item' }); } } else if (menu.level === 2 && currentParent) { structuredMenus.push({ name: menu.text, parent: currentParent, type: 'submenu-item' }); } } // 保存结果 fs.writeFileSync('vben-menus.json', JSON.stringify({ raw: menuData, structured: structuredMenus, timestamp: new Date().toISOString() }, null, 2)); console.log('\n菜单数据已保存到 vben-menus.json'); // 截图当前菜单状态 await page.screenshot({ path: 'test-screenshots/menu-state.png', fullPage: true }); await page.waitForTimeout(5000); } catch (error) { console.error('出错了:', error); } finally { if (browser) { await browser.close(); } } })();