From 8d38687583fa0be24dfff9ef4f5bf30fb64dd230 Mon Sep 17 00:00:00 2001 From: dengqichen Date: Mon, 10 Mar 2025 15:45:40 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=88=86=E6=89=B9=E6=89=A7?= =?UTF-8?q?=E8=A1=8C=E7=82=B9=E5=87=BB=E8=8F=9C=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.dev | 2 +- src/pages/BasePage.js | 16 +-- src/pages/LongiMainPage.js | 27 ++-- test-data/menu-data.json | 246 ----------------------------------- test-data/test-progress.json | 4 +- 5 files changed, 26 insertions(+), 269 deletions(-) diff --git a/.env.dev b/.env.dev index ab39936..ba6ae3d 100644 --- a/.env.dev +++ b/.env.dev @@ -7,7 +7,7 @@ IBP_PASSWORD=123456 # 测试配置 TEST_DATA_DIR=test-data -TEST_BATCH_SIZE=5 +TEST_BATCH_SIZE=2 TEST_RETRY_COUNT=3 TEST_BATCH_INTERVAL=2000 TEST_MAX_RETRY_DELAY=10000 diff --git a/src/pages/BasePage.js b/src/pages/BasePage.js index f3264de..94258dc 100644 --- a/src/pages/BasePage.js +++ b/src/pages/BasePage.js @@ -92,7 +92,7 @@ class BasePage { */ async waitForElement(selector, options = {}) { try { - const element = options.firstOnly ? this.page.locator(selector).first() : this.page.locator(selector); + let element = options.firstOnly ? this.page.locator(selector).first() : this.page.locator(selector); await element.waitFor({ state: 'visible', @@ -114,7 +114,7 @@ class BasePage { * @param {Object} options 选项 */ async clickBySelector(selector, options = {}) { - const element = await this.waitForElement(selector, options); + let element = await this.waitForElement(selector, options); await element.click(options); } @@ -168,7 +168,7 @@ class BasePage { * @param {Object} options 选项 */ async fill(selector, value, options = {}) { - const element = await this.waitForElement(selector, options); + let element = await this.waitForElement(selector, options); await element.fill(value); } @@ -194,22 +194,22 @@ class BasePage { async waitForIBPPageLoadWithRetry(pageName) { console.log(`等待页面 ${pageName} 数据加载...`); - const startTime = Date.now(); + let startTime = Date.now(); let retryCount = 0; - const {maxRetries, retryInterval, stabilityDelay} = this.config.pageLoad; - let errorMessage = null; + let {maxRetries, retryInterval, stabilityDelay} = this.config.pageLoad; + let errorMessage = ''; try { while (retryCount < maxRetries) { // 检查错误状态 - const hasError = await this.checkPageError(pageName); + let hasError = await this.checkPageError(pageName); if (hasError) { errorMessage = await this.getErrorMessage(); break; } // 检查加载状态 - const isLoading = await this.elementExistsBySelector(this.selectors.loadingMask); + let isLoading = await this.elementExistsBySelector(this.selectors.loadingMask); if (!isLoading) { await this.waitForTimeout(stabilityDelay); console.log(`✅ 页面 ${pageName} 加载完成`); diff --git a/src/pages/LongiMainPage.js b/src/pages/LongiMainPage.js index 5f73e5f..b6d280c 100644 --- a/src/pages/LongiMainPage.js +++ b/src/pages/LongiMainPage.js @@ -33,7 +33,7 @@ class LongiMainPage extends BasePage { thirdLevelIndicator: '.el-icon-arrow-right', subMenuIndicator: '.el-sub-menu__icon-arrow', // Tab相关 - tabContainer: '.workSpaceBaseTab .el-tabs__item', + tabContainer: '.workSpaceBaseTab>.el-tabs__header .el-tabs__item', activeTab: '.vab-tabs .el-tabs--card .el-tabs__item.is-active', closeButton: '.el-icon.is-icon-close', tabItems: '.workSpaceBaseTab .el-tabs__item', @@ -388,17 +388,17 @@ class LongiMainPage extends BasePage { * @private */ async findTabInfos(menu) { - const tabs = await this.page.locator(this.selectors.tabContainer).all(); + let tabs = await this.page.locator(this.selectors.tabContainer).all(); if (tabs.length === 0) { console.log(`📝 ${menu.text} 没有TAB页`); return []; } console.log(`📑 ${menu.text} 找到 ${tabs.length} 个TAB页`); - const tabInfos = []; + let tabInfos = []; for (const tab of tabs) { - const text = await tab.textContent(); - const isActive = await tab.evaluate(el => el.classList.contains('is-active')); + let text = await tab.textContent(); + let isActive = await tab.evaluate(el => el.classList.contains('is-active')); tabInfos.push({ text: text.trim(), element: tab, @@ -416,7 +416,7 @@ class LongiMainPage extends BasePage { try { await this.waitForTimeout(1000); - const tabInfos = await this.findTabInfos(menu); + let tabInfos = await this.findTabInfos(menu); if (tabInfos.length === 0) { return; } @@ -441,9 +441,10 @@ class LongiMainPage extends BasePage { * @param {Object} parentMenu 父级菜单对象 */ async handleSingleTab(tabInfo, parentMenu) { + let menuPath, tabPath = ''; try { - const menuPath = parentMenu.path || parentMenu.text; - const tabPath = `${menuPath} > ${tabInfo.text}`; + menuPath = parentMenu.path || parentMenu.text; + tabPath = `${menuPath} > ${tabInfo.text}`; await tabInfo.element.click(); await this.waitForIBPPageLoadWithRetry(tabPath); } catch (error) { @@ -456,8 +457,8 @@ class LongiMainPage extends BasePage { */ async closeActiveTab(parentMenu) { try { - const activeTab = this.page.locator(this.selectors.activeTab); - const closeButton = activeTab.locator(this.selectors.closeButton); + let activeTab = this.page.locator(this.selectors.activeTab); + let closeButton = activeTab.locator(this.selectors.closeButton); if (await this.canCloseTab(activeTab, closeButton)) { await closeButton.waitFor({state: 'visible', timeout: 5000}); await this.clickByElement(closeButton); @@ -478,8 +479,8 @@ class LongiMainPage extends BasePage { * @private */ async canCloseTab(activeTab, closeButton) { - const hasActiveTab = await activeTab.count() > 0; - const hasCloseButton = await closeButton.count() > 0; + let hasActiveTab = await activeTab.count() > 0; + let hasCloseButton = await closeButton.count() > 0; return hasActiveTab && hasCloseButton; } @@ -490,7 +491,7 @@ class LongiMainPage extends BasePage { async cleanupMemory(context = '') { try { await this.page.evaluate((selector) => { - const elements = document.querySelectorAll(selector); + let elements = document.querySelectorAll(selector); elements.forEach(el => el.remove()); if (window.gc) window.gc(); }, this.selectors.temporaryElements); diff --git a/test-data/menu-data.json b/test-data/menu-data.json index 0631720..2bd33d8 100644 --- a/test-data/menu-data.json +++ b/test-data/menu-data.json @@ -1,254 +1,8 @@ [ - { - "id": 1, - "text": "主数据", - "path": "主数据", - "hasThirdMenu": true - }, - { - "id": 2, - "text": "业务数据", - "path": "业务数据", - "hasThirdMenu": true - }, - { - "id": 3, - "text": "电池基础数据", - "path": "电池基础数据", - "hasThirdMenu": true - }, - { - "id": 4, - "text": "主需求计划", - "path": "主需求计划", - "hasThirdMenu": false - }, - { - "id": 5, - "text": "供需粗匹配", - "path": "供需粗匹配", - "hasThirdMenu": false - }, - { - "id": 6, - "text": "产线规划", - "path": "产线规划", - "hasThirdMenu": true - }, { "id": 7, "text": "电池投放计划", "path": "电池投放计划", "hasThirdMenu": true - }, - { - "id": 8, - "text": "主生产计划", - "path": "主生产计划", - "hasThirdMenu": true - }, - { - "id": 9, - "text": "基地生产计划", - "path": "基地生产计划", - "hasThirdMenu": true - }, - { - "id": 10, - "text": "ATP生成和发布", - "path": "ATP生成和发布", - "hasThirdMenu": false - }, - { - "id": 11, - "text": "ATP分配调整", - "path": "ATP分配调整", - "hasThirdMenu": false - }, - { - "id": 12, - "text": "ATP查询", - "path": "ATP查询", - "hasThirdMenu": false - }, - { - "id": 13, - "text": "产量预测", - "path": "产量预测", - "hasThirdMenu": true - }, - { - "id": 14, - "text": "入库预测", - "path": "入库预测", - "hasThirdMenu": false - }, - { - "id": 15, - "text": "硅片投入需求", - "path": "硅片投入需求", - "hasThirdMenu": false - }, - { - "id": 16, - "text": "硅片到货需求", - "path": "硅片到货需求", - "hasThirdMenu": false - }, - { - "id": 17, - "text": "硅片需求预测", - "path": "硅片需求预测", - "hasThirdMenu": false - }, - { - "id": 18, - "text": "硅片缺口审视", - "path": "硅片缺口审视", - "hasThirdMenu": false - }, - { - "id": 19, - "text": "电池需求数据", - "path": "电池需求数据", - "hasThirdMenu": false - }, - { - "id": 20, - "text": "基地产能利用率", - "path": "基地产能利用率", - "hasThirdMenu": false - }, - { - "id": 21, - "text": "电池生产计划", - "path": "电池生产计划", - "hasThirdMenu": false - }, - { - "id": 22, - "text": "入库节奏基础参数", - "path": "入库节奏基础参数", - "hasThirdMenu": false - }, - { - "id": 23, - "text": "入库节奏", - "path": "入库节奏", - "hasThirdMenu": false - }, - { - "id": 24, - "text": "电池基地生产计划", - "path": "电池基地生产计划", - "hasThirdMenu": false - }, - { - "id": 25, - "text": "电池入库比例", - "path": "电池入库比例", - "hasThirdMenu": false - }, - { - "id": 26, - "text": "电池入库计划", - "path": "电池入库计划", - "hasThirdMenu": false - }, - { - "id": 27, - "text": "电池要货计划", - "path": "电池要货计划", - "hasThirdMenu": false - }, - { - "id": 28, - "text": "电池发货计划", - "path": "电池发货计划", - "hasThirdMenu": false - }, - { - "id": 29, - "text": "jiahx测试", - "path": "jiahx测试", - "hasThirdMenu": false - }, - { - "id": 30, - "text": "业务参数", - "path": "业务参数", - "hasThirdMenu": false - }, - { - "id": 31, - "text": "计划对象", - "path": "计划对象", - "hasThirdMenu": false - }, - { - "id": 32, - "text": "排产优先级", - "path": "排产优先级", - "hasThirdMenu": false - }, - { - "id": 33, - "text": "逃生通道", - "path": "逃生通道", - "hasThirdMenu": false - }, - { - "id": 34, - "text": "主需求计划", - "path": "主需求计划", - "hasThirdMenu": true - }, - { - "id": 35, - "text": "电池投放", - "path": "电池投放", - "hasThirdMenu": true - }, - { - "id": 36, - "text": "供需粗匹配", - "path": "供需粗匹配", - "hasThirdMenu": true - }, - { - "id": 37, - "text": "ATP", - "path": "ATP", - "hasThirdMenu": true - }, - { - "id": 38, - "text": "电池要发货", - "path": "电池要发货", - "hasThirdMenu": true - }, - { - "id": 39, - "text": "主计划/基地计划", - "path": "主计划/基地计划", - "hasThirdMenu": true - }, - { - "id": 40, - "text": "基地计划", - "path": "基地计划", - "hasThirdMenu": true - }, - { - "id": 41, - "text": "产品系列(内部手工维护)", - "path": "产品系列(内部手工维护)", - "hasThirdMenu": true - }, - { - "id": 42, - "text": "管理视图", - "path": "管理视图", - "hasThirdMenu": false } ] \ No newline at end of file diff --git a/test-data/test-progress.json b/test-data/test-progress.json index 0637a08..71a8711 100644 --- a/test-data/test-progress.json +++ b/test-data/test-progress.json @@ -1 +1,3 @@ -[] \ No newline at end of file +[ + 7 +] \ No newline at end of file