describe('隆基系统页面验证', () => { // 环境配置 const ENV_CONFIG = { DEV: { url: 'https://ibp-dev.longi.com/main/#/login', needCredentials: false }, UAT: { url: 'https://ibp-test.longi.com/main/#/login?debug=ly', needCredentials: true, username: 'qichenadmin', password: '123456' } }; let SELECT_ENV; // 登录处理函数 const handleLogin = () => { const envConfig = ENV_CONFIG[SELECT_ENV]; if (!envConfig) { throw new Error(`未知的环境: ${SELECT_ENV}`); } cy.log(`正在登录 ${SELECT_ENV} 环境: ${envConfig.url}`); cy.visit(envConfig.url); // 忽略未捕获的异常 Cypress.on('uncaught:exception', (err, runnable) => false); cy.get('#app', {timeout: 10000}).should('exist'); if (envConfig.needCredentials) { // 清空输入框 cy.get('input[name="username"]').clear(); cy.get('input[name="passWord"]').clear(); // 输入账号密码 cy.get('input[name="username"]').type(envConfig.username); cy.get('input[name="passWord"]').type(envConfig.password); } // 执行登录 cy.get('.container-button').click(); // 等待登录完成 cy.wait(3000); }; // 清理内存 const cleanupMemory = () => { cy.task('clearMemory'); }; // 创建常用元素别名 const createAliases = () => { cy.log('创建常用元素别名'); // 页面主体 cy.get('body').as('pageBody'); // 侧边栏导航 cy.get('.ly-side-nav').as('sideNav'); // 主菜单 cy.get('.el-scrollbar__view > .el-menu').as('mainMenu'); // 菜单项 cy.get('.el-menu-item').as('menuItems'); // 子菜单标题 cy.get('.el-sub-menu__title').as('subMenuTitles'); // 内容区域 cy.get('.vab-content').as('contentArea'); // 标签页 cy.get('.vab-tabs').as('tabs'); // 菜单切换按钮 cy.get('.vab-content .toggle-icon').as('menuToggle'); cy.log('别名创建完成'); }; // 确保菜单展开 const ensureMenuExpanded = () => { cy.log('确保菜单处于展开状态'); cy.get('@sideNav').then(($el) => { cy.log(`菜单现在的偏移量是:${$el.css('left')}`); const leftValue = $el.css('left'); if (leftValue !== '0px') { cy.log('菜单未展开,点击展开'); cy.get('@menuToggle').click(); cy.wait(500); // 等待菜单展开动画 cy.log('已点击展开菜单'); } else { cy.log('菜单已经处于展开状态'); } }); }; // 获取菜单数据 const getMenuItems = () => { cy.log('开始获取菜单结构'); return cy.get('@mainMenu').then(($elMenu) => { const menuItems = []; // 获取所有菜单项 const allMenuItems = $elMenu.find('.el-sub-menu__title, .el-menu-item'); // 过滤并整理菜单项 allMenuItems.each((index, el) => { const $el = Cypress.$(el); const menuText = $el.find('.titleSpan').text().trim() || $el.text().trim(); const isFirstLevel = $el.find('.menuIcon').length > 0; // 只添加二级菜单项 if (isFirstLevel) { return; } const hasThirdMenu = $el.find('i.el-icon').length > 0; // 将菜单项添加到数组 menuItems.push({ index: index, text: menuText, hasThirdMenu: hasThirdMenu }); }); return cy.wrap(menuItems); }); }; // 将菜单数据序列化到文件 const saveMenuItemsToFile = () => { cy.log('开始保存菜单数据到文件'); // 获取命令行传入的测试标识,如果没有则使用数字时间戳 const testId = Cypress.env('testId') || 'testId'; cy.log(`🔖 使用测试标识: ${testId}`); return getMenuItems().then(menuItems => { // 创建可序列化的菜单数据(移除DOM元素) const serializableMenuItems = menuItems.map(item => ({ index: item.index, text: item.text, hasThirdMenu: item.hasThirdMenu, tested: false })); // 生成文件名(包含测试标识) const filename = `cypress/fixtures/${SELECT_ENV}-needs-clicked-data-${testId}.json`; // 将数据写入文件 cy.writeFile(filename, { testId: testId, environment: SELECT_ENV, timestamp: Date.now(), totalMenuItems: menuItems.length, menuItems: serializableMenuItems }).then(() => { cy.log(`✅ 菜单数据已保存到文件: ${filename}`); }); // 返回菜单项和测试标识,以便链式调用 return cy.wrap({ menuItems, testId: testId }); }); }; // 关闭活动的标签页 const closeActiveTab = (menuText) => { cy.log(`尝试关闭标签页: ${menuText}`); cy.get('.vab-tabs .el-tabs__item').each(($tab) => { if ($tab.text().trim() === menuText) { cy.wrap($tab).find('.el-icon-close').click(); cy.wait(500); } }); }; // 处理二级菜单的方法 const handleSecondLevelMenu = (menuItem) => { cy.log(`📎 处理二级菜单: ${menuItem.text}`); // 点击菜单项 cy.get('.el-sub-menu__title, .el-menu-item').eq(menuItem.index).then($element => { cy.wrap($element).click(); cy.wait(1000); // 等待页面加载 waitForPageLoad(); // 检查并处理标签页 cy.get('.vab-tabs .el-tabs__item').then($tabs => { if ($tabs.length > 0) { // 遍历所有标签页 cy.get('.vab-tabs .el-tabs__item').each(($tab) => { const tabText = $tab.text().trim(); cy.log(`处理标签页: ${tabText}`); // 点击标签页 cy.wrap($tab).click(); cy.wait(1000); // 等待页面加载 waitForPageLoad(); }); } }); // 关闭当前菜单的所有标签页 closeActiveTab(menuItem.text); }); }; // 处理三级菜单的方法 const handleThirdLevelMenu = (menuItem) => { cy.log(`📑 处理三级菜单: ${menuItem.text}`); // 获取二级菜单元素 cy.get('.el-sub-menu__title, .el-menu-item').eq(menuItem.index).as('secondMenu'); // 定义获取三级菜单的命令 Cypress.Commands.add('getThirdMenuItems', () => { return cy.get('@secondMenu').click() .then(() => { return cy.get('.el-popper.is-light.el-popover', {timeout: 5000}) .should('be.visible') .find('.menuTitle.canClick') .should('be.visible'); }); }); const processThirdMenuItems = ($thirdMenuItems, currentIndex = 0) => { if (currentIndex >= $thirdMenuItems.length) { cy.log(`✅ 完成所有三级菜单处理: ${menuItem.text}`); return; } // 获取并处理当前三级菜单项 cy.getThirdMenuItems().then($updatedThirdMenus => { const $currentThirdMenu = $updatedThirdMenus.eq(currentIndex); const thirdMenuText = $currentThirdMenu.text().trim(); cy.log(`处理第 ${currentIndex + 1}/${$thirdMenuItems.length} 个三级菜单: ${thirdMenuText}`); // 点击三级菜单项 cy.wrap($currentThirdMenu).click(); waitForPageLoad(); // 检查并处理标签页 cy.get('.vab-tabs .el-tabs__item').then($tabs => { if ($tabs.length > 0) { // 遍历所有标签页 cy.get('.vab-tabs .el-tabs__item').each(($tab) => { const tabText = $tab.text().trim(); cy.log(`处理标签页: ${tabText}`); // 点击标签页 cy.wrap($tab).click(); cy.wait(1000); // 等待页面加载 waitForPageLoad(); }); } }); // 关闭当前菜单的标签页 closeActiveTab(thirdMenuText); // 处理下一个三级菜单项 cy.wait(1000).then(() => { processThirdMenuItems($thirdMenuItems, currentIndex + 1); }); }); }; // 开始处理三级菜单 cy.getThirdMenuItems().then($thirdMenuItems => { if ($thirdMenuItems.length > 0) { cy.log(`发现 ${$thirdMenuItems.length} 个三级菜单项`); processThirdMenuItems($thirdMenuItems); } else { cy.log('没有找到三级菜单项'); } }); }; const waitForPageLoad = () => { cy.log('等待页面数据加载...'); let retryCount = 0; const maxRetries = 30; function check() { if (retryCount >= maxRetries) { cy.log('页面加载超时,记录失败并继续执行...'); return; } cy.get('@pageBody').then($body => { const hasLoadingMask = $body.find('.el-loading-mask').length > 0; const hasError = $body.find('.el-message-box__message').length > 0 || $body.find('.el-message--error').length > 0; if (hasError) { cy.log('页面加载出现错误'); return; } if (hasLoadingMask) { retryCount++; cy.wait(500).then(check); } else { cy.log('页面数据加载完成'); } }); } check(); }; // 验证环境参数 const validateEnvironment = () => { // 从环境变量获取环境参数,默认为DEV const environment = Cypress.env('environment') || 'DEV'; // 验证环境参数 if (!ENV_CONFIG[environment]) { cy.log(`❌ 无效的环境参数: ${environment}`); cy.log('有效的环境参数: DEV, UAT'); throw new Error(`无效的环境参数: ${environment}`); } else { cy.log(`🚀 开始在 ${environment} 环境测试页面`); SELECT_ENV = environment; } }; // 获取最新的测试数据文件 const getLatestDataFileContent = () => { cy.log('🔍 正在查找最新的测试数据文件'); return cy.task('getLatestDataFile').then(result => { if (!result) { cy.log('❌ 没有找到可测试的数据文件,将初始化数据'); // throw new Error('没有可测试的数据,请先运行初始化测试生成数据'); initializeSystem(); return; } cy.log(`✅ 找到最新的数据文件: ${result.filename}`); return cy.wrap(result); }); }; const initializeSystem = () => { cy.log('🚀 开始系统初始化'); // 获取菜单数据并保存到文件 saveMenuItemsToFile(); }; // 处理菜单测试的方法 const processMenuTests = (menuData) => { const {menuItems} = menuData.content; const totalMenus = menuItems.length; const untestedMenus = menuItems.filter(item => !item.tested); cy.log('📊 菜单测试统计'); cy.log(`总菜单数: ${totalMenus}`); cy.log(`待测试数: ${untestedMenus.length}`); cy.log(`已完成数: ${totalMenus - untestedMenus.length}`); // 遍历每个菜单项 menuItems.forEach((menuItem, index) => { // 跳过已测试的菜单项 if (menuItem.tested) { cy.log(`⏭️ 跳过已测试的菜单项:${menuItem.text}`); return; } cy.log(`🔄 正在处理第 ${index + 1}/${totalMenus} 个菜单项:${menuItem.text}`); // 根据菜单类型调用对应的处理方法 if (menuItem.hasThirdMenu) { handleThirdLevelMenu(menuItem); } else { handleSecondLevelMenu(menuItem); } }); }; // 测试入口 it('验证系统页面是否可用', () => { // 验证环境参数 validateEnvironment(); // 登录系统 handleLogin(); // 创建常用元素别名 createAliases(); // 确保菜单展开 ensureMenuExpanded(); getLatestDataFileContent().then(result => { if (result && result.content && result.content.menuItems) { processMenuTests(result); } else { cy.log('❌ 没有找到有效的菜单数据'); } }); cy.log('✅ 系统菜单加载成功'); cy.log(`🏁 测试完成,环境: ${SELECT_ENV}`); }); });