From 83117e8169d22a8dcde31c29c63e2b59eab4d4a3 Mon Sep 17 00:00:00 2001 From: dengqichen Date: Mon, 3 Mar 2025 12:30:01 +0800 Subject: [PATCH] =?UTF-8?q?=E5=86=85=E5=AD=98=E4=BC=98=E5=8C=962?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cypress/e2e/需求计划页面是否可用.cy.js | 699 +++++++++++++++---------- 1 file changed, 432 insertions(+), 267 deletions(-) diff --git a/cypress/e2e/需求计划页面是否可用.cy.js b/cypress/e2e/需求计划页面是否可用.cy.js index 6e393ec..ca16bcc 100644 --- a/cypress/e2e/需求计划页面是否可用.cy.js +++ b/cypress/e2e/需求计划页面是否可用.cy.js @@ -12,6 +12,33 @@ describe('隆基系统全部页面验证', () => { cleanupMemory(); }); + // 创建通用对话框模板函数 + const createDialogTemplate = (options) => { + const { + dialogClass, + title, + width, + bodyContent, + footerContent + } = options; + + return ` +
+
+
+ ${title} +
+
+ ${bodyContent} +
+ +
+
+ `; + }; + // 格式化时间的辅助函数 const formatTime = (date) => { return date.toLocaleString('zh-CN', { @@ -84,29 +111,28 @@ describe('隆基系统全部页面验证', () => { Cypress.on('uncaught:exception', (err, runnable) => false); // 创建环境选择对话框 - const dialogHtml = ` -
-
-
- 选择测试环境 -
-
-
- 请选择要测试的环境 -
-
- - -
-
-
+ const envDialogBodyContent = ` +
+ 请选择要测试的环境 +
+
+ +
`; + const dialogHtml = createDialogTemplate({ + dialogClass: 'env-select-dialog', + title: '选择测试环境', + width: '400px', + bodyContent: envDialogBodyContent, + footerContent: '' + }); + // 添加对话框到页面 cy.get('body').then($body => { $body.append(dialogHtml); @@ -159,35 +185,101 @@ describe('隆基系统全部页面验证', () => { } }; - // 添加内存清理的公共方法 + // 优化内存清理函数,确保与Cypress命令链兼容 const cleanupMemory = () => { - // 执行垃圾回收 - cy.task('clearMemory', null, {log: false}); - - // 清理DOM快照 - cy.get('body').then(() => { + cy.log('🧹 执行内存清理...'); + + // 记录清理前的内存使用情况 + cy.window({log: false}).then(win => { + if (win.performance && win.performance.memory) { + const beforeMemory = Math.round(win.performance.memory.usedJSHeapSize / 1024 / 1024); + cy.log(`清理前内存使用: ${beforeMemory}MB`); + } + + // 执行内存清理操作 try { - // 移除一些可能导致内存泄漏的元素 - Cypress.$('.el-loading-mask').remove(); - Cypress.$('.el-message').remove(); - Cypress.$('.el-message-box').remove(); + // 1. 清理DOM元素 + const elementsToRemove = [ + '.el-loading-mask', + '.el-message', + '.el-message-box:not(.is-message)', + '.el-notification', + '.el-drawer__wrapper:not(.active)', + '.el-tooltip__popper', + '.el-select-dropdown', + '.el-popover', + '.el-dropdown-menu', + '.v-modal' + ]; - // 清理事件监听器 - 只清理特定元素的事件 - Cypress.$('.el-dialog__wrapper').off(); - Cypress.$('.el-notification').off(); - Cypress.$('.el-drawer__wrapper').off(); + elementsToRemove.forEach(selector => { + if (Cypress.$(selector).length > 0) { + Cypress.$(selector).remove(); + } + }); - // 清理控制台 + // 2. 清理iframe内容 + Cypress.$('iframe').each((_, el) => { + try { + el.src = 'about:blank'; + } catch (e) { + // 忽略错误 + } + }); + + // 3. 清理大型表格内容 + Cypress.$('.el-table__body tr').each((index, el) => { + if (index > 20) { + Cypress.$(el).remove(); + } + }); + + // 4. 清理事件监听器(保留菜单相关元素) + Cypress.$('*:not(.el-menu):not(.el-menu-item):not(.el-submenu):not(.sidebar-menu):not(.el-scrollbar__view)').each((_, el) => { + try { + const element = Cypress.$(el); + // 只清理非菜单元素的事件 + if (!element.closest('.el-menu, .sidebar-menu').length) { + element.off(); + } + } catch (e) { + // 忽略错误 + } + }); + + // 5. 清理定时器 + let id = window.setTimeout(() => {}, 0); + while (id--) { + window.clearTimeout(id); + window.clearInterval(id); + } + + // 6. 清理Vue相关引用 + if (win.__VUE_DEVTOOLS_GLOBAL_HOOK__) { + win.__VUE_DEVTOOLS_GLOBAL_HOOK__.Vue = null; + } + + // 7. 手动触发一些可能的内存释放 + win.dispatchEvent(new Event('beforeunload')); + + // 8. 清理控制台 console.clear(); } catch (e) { console.error('清理DOM时出错:', e); } + }).then(() => { + // 等待一段时间让垃圾回收生效 + return cy.wait(1000, {log: false}); + }).then(() => { + // 再次检查内存使用情况 + return cy.window({log: false}).then(win => { + if (win.performance && win.performance.memory) { + const afterMemory = Math.round(win.performance.memory.usedJSHeapSize / 1024 / 1024); + cy.log(`清理后内存使用: ${afterMemory}MB`); + } + cy.log('🧹 内存清理完成'); + }); }); - - // 手动清理一些可能的引用 - if (window.gc) { - window.gc(); - } }; // 添加关闭tab的公共方法 @@ -311,18 +403,19 @@ describe('隆基系统全部页面验证', () => { cy.log(`\n📑 页面 "${currentPage.name}" 发现 ${$inactiveTabs.length} 个待访问的tab页`); testReport.summary.totalTabs += $inactiveTabs.length; - const processTab = (index = 0) => { - if (index >= $inactiveTabs.length) { + // 使用迭代方式处理Tab页,避免深度递归 + const processTabsSequentially = (tabs, startIndex = 0) => { + if (startIndex >= tabs.length) { cy.log(`✅ 页面 "${currentPage.name}" 的所有tab页处理完成`); - return; + return cy.wrap(null); } - - const tabProgress = ((index + 1) / $inactiveTabs.length * 100).toFixed(1); - const $currentTab = Cypress.$($inactiveTabs[index]); + + const $currentTab = Cypress.$(tabs[startIndex]); const tabText = $currentTab.text().trim(); - - cy.log(`🔸 正在处理tab页 [${index + 1}/${$inactiveTabs.length}] (${tabProgress}%): ${currentPage.name} > ${tabText}`); - + const tabProgress = ((startIndex + 1) / tabs.length * 100).toFixed(1); + + cy.log(`🔸 正在处理tab页 [${startIndex + 1}/${tabs.length}] (${tabProgress}%): ${currentPage.name} > ${tabText}`); + const tabStartTime = new Date(); const tabInfo = { name: tabText, @@ -331,53 +424,59 @@ describe('隆基系统全部页面验证', () => { duration: '', status: 'pending' }; - + if (!currentPage.tabs) { currentPage.tabs = []; } currentPage.tabs.push(tabInfo); - - cy.wrap($currentTab).click({force: true}).then(() => { - cy.log(`⏳ [${currentPage.name}] 已点击tab页: ${tabText},等待加载...`); - - let tabLoadRetry = 0; - const waitForTabLoad = () => { - if (tabLoadRetry >= 30) { - cy.log(`❌ [${currentPage.name}] Tab页 ${tabText} 加载超时 [${tabLoadRetry}次重试],继续下一个`); - updateTabInfo(tabInfo, tabStartTime, 'timeout'); - processTab(index + 1); - return; - } - - cy.get('@pageBody').then($body => { - const isLoading = $body.find('.el-loading-mask').length > 0; - const hasTabError = $body.find('.el-message-box__message').length > 0 || - $body.find('.el-message--error').length > 0; - - if (hasTabError) { - cy.log(`❌ [${currentPage.name}] Tab页 ${tabText} 加载出现错误`); - updateTabInfo(tabInfo, tabStartTime, 'error'); - processTab(index + 1); - return; - } - - if (isLoading) { - tabLoadRetry++; - cy.log(`⏳ [${currentPage.name}] Tab页 ${tabText} 第 ${tabLoadRetry} 次检查加载状态...`); - cy.wait(500).then(waitForTabLoad); - } else { - updateTabInfo(tabInfo, tabStartTime, 'success'); - cy.log(`✅ [${currentPage.name}] Tab页 ${tabText} 加载完成 (耗时: ${tabInfo.duration}秒)`); - cy.wait(1000).then(() => processTab(index + 1)); - } + + // 处理单个Tab,然后链式处理下一个 + return cy.wrap($currentTab) + .click({force: true}) + .then(() => { + cy.log(`⏳ [${currentPage.name}] 已点击tab页: ${tabText},等待加载...`); + return waitForTabLoadWithTimeout(currentPage, tabInfo, tabStartTime, 30); + }) + .then(() => { + // 处理下一个Tab + return processTabsSequentially(tabs, startIndex + 1); + }); + }; + + // 等待Tab加载的函数,使用超时机制 + const waitForTabLoadWithTimeout = (currentPage, tabInfo, tabStartTime, maxRetries, retryCount = 0) => { + if (retryCount >= maxRetries) { + cy.log(`❌ [${currentPage.name}] Tab页 ${tabInfo.name} 加载超时 [${retryCount}次重试]`); + updateTabInfo(tabInfo, tabStartTime, 'timeout'); + return cy.wrap(null); + } + + return cy.get('@pageBody').then($body => { + const isLoading = $body.find('.el-loading-mask').length > 0; + const hasTabError = $body.find('.el-message-box__message').length > 0 || + $body.find('.el-message--error').length > 0; + + if (hasTabError) { + cy.log(`❌ [${currentPage.name}] Tab页 ${tabInfo.name} 加载出现错误`); + updateTabInfo(tabInfo, tabStartTime, 'error'); + return cy.wrap(null); + } + + if (isLoading) { + cy.log(`⏳ [${currentPage.name}] Tab页 ${tabInfo.name} 第 ${retryCount + 1} 次检查加载状态...`); + return cy.wait(500).then(() => { + return waitForTabLoadWithTimeout(currentPage, tabInfo, tabStartTime, maxRetries, retryCount + 1); }); - }; - - waitForTabLoad(); + } else { + updateTabInfo(tabInfo, tabStartTime, 'success'); + cy.log(`✅ [${currentPage.name}] Tab页 ${tabInfo.name} 加载完成 (耗时: ${tabInfo.duration}秒)`); + return cy.wait(1000); + } }); }; - - processTab(); + + // 开始处理所有Tab + return processTabsSequentially($inactiveTabs); }; // 处理页面中的tab页 @@ -510,38 +609,50 @@ describe('隆基系统全部页面验证', () => { pageInfo.hasThirdMenu = true; cy.log(`✓ ${menuText} 包含 ${$thirdMenuItems.length} 个三级菜单`); - const processThirdMenu = (thirdIndex = 0) => { - if (thirdIndex >= $thirdMenuItems.length) { + // 使用迭代方式处理三级菜单,避免深度递归 + const processThirdMenuSequentially = (items, startIndex = 0) => { + if (startIndex >= items.length) { pageInfo.endTime = formatTime(new Date()); const thirdMenuProgress = (100).toFixed(1); cy.log(`✅ 完成菜单 "${menuText}" 的所有三级菜单处理 (${thirdMenuProgress}%)`); closeActiveTab(menuText); - cy.wait(1000).then(() => processMenuItems(index + 1)); - return; + return cy.wait(1000).then(() => processMenuItems(index + 1)); } - const thirdMenuProgress = ((thirdIndex + 1) / $thirdMenuItems.length * 100).toFixed(1); + const thirdMenuProgress = ((startIndex + 1) / items.length * 100).toFixed(1); - if (thirdIndex > 0) { - cy.wrap($menuItem).click(); - cy.wait(1000); + if (startIndex > 0) { + return cy.wrap($menuItem).click() + .wait(1000) + .then(() => { + return cy.get('@thirdMenuItems') + .eq(startIndex) + .then(processCurrentThirdMenuItem); + }); + } else { + return cy.get('@thirdMenuItems') + .eq(startIndex) + .then(processCurrentThirdMenuItem); } - cy.get('@thirdMenuItems') - .eq(thirdIndex) - .then($thirdMenu => { - const thirdMenuText = $thirdMenu.text().trim(); - cy.log(`\n🔸 处理三级菜单 [${thirdIndex + 1}/${$thirdMenuItems.length}] (${thirdMenuProgress}%): ${menuText} > ${thirdMenuText}`); + function processCurrentThirdMenuItem($thirdMenu) { + const thirdMenuText = $thirdMenu.text().trim(); + cy.log(`\n🔸 处理三级菜单 [${startIndex + 1}/${items.length}] (${thirdMenuProgress}%): ${menuText} > ${thirdMenuText}`); - const thirdMenuPage = new PageInfo(thirdMenuText, true, menuText).addToBatch(); + const thirdMenuPage = new PageInfo(thirdMenuText, true, menuText).addToBatch(); - cy.wrap($thirdMenu).click(); - waitForPageLoad(thirdMenuPage, new Date()); - cy.wait(1000).then(() => processThirdMenu(thirdIndex + 1)); - }); + return cy.wrap($thirdMenu).click() + .then(() => { + waitForPageLoad(thirdMenuPage, new Date()); + return cy.wait(1000); + }) + .then(() => { + return processThirdMenuSequentially(items, startIndex + 1); + }); + } }; - processThirdMenu(); + return processThirdMenuSequentially($thirdMenuItems); }; // 处理没有三级菜单的情况 @@ -609,35 +720,35 @@ describe('隆基系统全部页面验证', () => { cy.log(`🔍 找到 ${menuItems.length} 个可测试的菜单项`); // 创建菜单选择对话框 - const dialogHtml = ` -