第一次
This commit is contained in:
parent
67149da27a
commit
08910deeed
@ -263,224 +263,6 @@ class LongiMainPage extends BasePage {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过索引查找菜单项
|
||||
* @param {number} index 菜单项索引
|
||||
* @param {Array} menuItems 菜单项数组,如果未提供则会调用findMenuItems获取
|
||||
* @returns {Promise<Object|null>} 找到的菜单项或null
|
||||
*/
|
||||
async findMenuItemByIndex(index, menuItems = null) {
|
||||
try {
|
||||
// 如果未提供菜单项数组,则获取
|
||||
if (!menuItems) {
|
||||
menuItems = await this.findMenuItems();
|
||||
}
|
||||
|
||||
// 查找指定索引的菜单项
|
||||
const menuItem = menuItems.find(item => item.index === index);
|
||||
|
||||
if (menuItem) {
|
||||
console.log(`通过索引 ${index} 找到菜单项: "${menuItem.text}"`);
|
||||
return menuItem;
|
||||
} else {
|
||||
console.log(`未找到索引为 ${index} 的菜单项`);
|
||||
return null;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`通过索引查找菜单项时出错: ${error}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过文本和可选的索引查找菜单项
|
||||
* 当有多个同名菜单项时,可以通过指定occurrence来选择第几个匹配项
|
||||
* @param {string} text 菜单项文本
|
||||
* @param {number} occurrence 第几个匹配项,从0开始计数,默认为0(第一个)
|
||||
* @param {Array} menuItems 菜单项数组,如果未提供则会调用findMenuItems获取
|
||||
* @returns {Promise<Object|null>} 找到的菜单项或null
|
||||
*/
|
||||
async findMenuItemByText(text, occurrence = 0, menuItems = null) {
|
||||
try {
|
||||
// 如果未提供菜单项数组,则获取
|
||||
if (!menuItems) {
|
||||
menuItems = await this.findMenuItems();
|
||||
}
|
||||
|
||||
// 查找所有匹配文本的菜单项
|
||||
const matchingItems = menuItems.filter(item => item.text === text);
|
||||
|
||||
if (matchingItems.length > 0) {
|
||||
if (occurrence < matchingItems.length) {
|
||||
const menuItem = matchingItems[occurrence];
|
||||
console.log(`通过文本 "${text}" 找到第 ${occurrence + 1} 个菜单项,索引为 ${menuItem.index}`);
|
||||
return menuItem;
|
||||
} else {
|
||||
console.log(`未找到第 ${occurrence + 1} 个文本为 "${text}" 的菜单项,只有 ${matchingItems.length} 个匹配项`);
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
console.log(`未找到文本为 "${text}" 的菜单项`);
|
||||
return null;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`通过文本查找菜单项时出错: ${error}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过唯一ID查找菜单项
|
||||
* @param {string} uniqueId 菜单项的唯一ID
|
||||
* @param {Array} menuItems 菜单项数组,如果未提供则会调用findMenuItems获取
|
||||
* @returns {Promise<Object|null>} 找到的菜单项或null
|
||||
*/
|
||||
async findMenuItemByUniqueId(uniqueId, menuItems = null) {
|
||||
try {
|
||||
// 如果未提供菜单项数组,则获取
|
||||
if (!menuItems) {
|
||||
menuItems = await this.findMenuItems();
|
||||
}
|
||||
|
||||
// 查找指定唯一ID的菜单项
|
||||
const menuItem = menuItems.find(item => item.uniqueId === uniqueId);
|
||||
|
||||
if (menuItem) {
|
||||
console.log(`通过唯一ID ${uniqueId} 找到菜单项: "${menuItem.text}"`);
|
||||
return menuItem;
|
||||
} else {
|
||||
console.log(`未找到唯一ID为 ${uniqueId} 的菜单项`);
|
||||
return null;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`通过唯一ID查找菜单项时出错: ${error}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否存在三级菜单并进行相应处理
|
||||
* @param {Object} menuItem 菜单项对象,包含索引、文本和元素
|
||||
* @param {number} timeout 超时时间(毫秒),默认30秒
|
||||
* @returns {Promise<{hasThirdMenu: boolean, thirdMenuItems: Array}>} 是否有三级菜单及三级菜单项数组
|
||||
*/
|
||||
async checkForThirdLevelMenu(menuItem, timeout = 30000) {
|
||||
try {
|
||||
console.log(`点击菜单项 "${menuItem.text}" 检查三级菜单...`);
|
||||
|
||||
// 点击菜单项,触发三级菜单弹出
|
||||
await menuItem.element.click();
|
||||
|
||||
// 等待弹出动画完成,增加等待时间
|
||||
await this.page.waitForTimeout(2000);
|
||||
|
||||
// 检查三级菜单
|
||||
const thirdMenuSelector = this.selectors.thirdLevelMenu;
|
||||
|
||||
// 尝试等待三级菜单出现,但不抛出错误
|
||||
const hasThirdMenu = await this.page.locator(thirdMenuSelector).count().then(count => count > 0).catch(() => false);
|
||||
|
||||
// 如果没有立即找到,再等待一段时间再次检查
|
||||
let thirdMenuCount = 0;
|
||||
if (hasThirdMenu) {
|
||||
thirdMenuCount = await this.page.locator(thirdMenuSelector).count();
|
||||
} else {
|
||||
// 再等待一段时间,有些菜单可能加载较慢
|
||||
await this.page.waitForTimeout(1000);
|
||||
thirdMenuCount = await this.page.locator(thirdMenuSelector).count();
|
||||
}
|
||||
|
||||
console.log(`菜单项 "${menuItem.text}" ${thirdMenuCount > 0 ? '有' : '没有'}三级菜单,找到 ${thirdMenuCount} 个三级菜单项`);
|
||||
|
||||
// 如果没有三级菜单,直接返回
|
||||
if (thirdMenuCount === 0) {
|
||||
return {hasThirdMenu: false, thirdMenuItems: []};
|
||||
}
|
||||
|
||||
// 收集三级菜单项
|
||||
const thirdMenuItems = [];
|
||||
for (let i = 0; i < thirdMenuCount; i++) {
|
||||
const item = this.page.locator(thirdMenuSelector).nth(i);
|
||||
const text = await item.textContent();
|
||||
|
||||
thirdMenuItems.push({
|
||||
index: i,
|
||||
text: text.trim(),
|
||||
element: item
|
||||
});
|
||||
}
|
||||
|
||||
// 输出三级菜单项文本
|
||||
const menuTexts = thirdMenuItems.map(item => item.text).join(', ');
|
||||
console.log(`三级菜单项: ${menuTexts}`);
|
||||
|
||||
return {hasThirdMenu: true, thirdMenuItems};
|
||||
} catch (error) {
|
||||
console.error(`检查三级菜单时出错: ${error}`);
|
||||
return {hasThirdMenu: false, thirdMenuItems: []};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理菜单项,包括检查和处理可能的三级菜单
|
||||
* @param {Object} menuItem 菜单项对象,包含索引、文本和元素以及hasThirdMenu标志
|
||||
* @param {Function} processWithThirdMenu 处理有三级菜单情况的回调函数
|
||||
* @param {Function} processWithoutThirdMenu 处理没有三级菜单情况的回调函数
|
||||
* @returns {Promise<{hasThirdMenu: boolean, thirdMenuItems: Array}>} 处理结果
|
||||
*/
|
||||
async processMenuItem(menuItem, processWithThirdMenu = null, processWithoutThirdMenu = null) {
|
||||
try {
|
||||
console.log(`处理菜单项: "${menuItem.text}"`);
|
||||
|
||||
// 使用菜单项中的hasThirdMenu字段
|
||||
const hasThirdMenu = menuItem.hasThirdMenu;
|
||||
|
||||
// 点击菜单项
|
||||
await menuItem.element.click();
|
||||
await this.page.waitForTimeout(1000); // 等待可能的动画完成
|
||||
|
||||
let thirdMenuItems = [];
|
||||
|
||||
// 如果有三级菜单,获取三级菜单项
|
||||
if (hasThirdMenu) {
|
||||
const thirdMenuSelector = this.selectors.thirdLevelMenu;
|
||||
const thirdMenuCount = await this.page.locator(thirdMenuSelector).count();
|
||||
|
||||
console.log(`菜单项 "${menuItem.text}" 有三级菜单,找到 ${thirdMenuCount} 个三级菜单项`);
|
||||
|
||||
// 收集三级菜单项
|
||||
for (let i = 0; i < thirdMenuCount; i++) {
|
||||
const item = this.page.locator(thirdMenuSelector).nth(i);
|
||||
const text = await item.textContent();
|
||||
|
||||
thirdMenuItems.push({
|
||||
index: i,
|
||||
text: text.trim(),
|
||||
element: item
|
||||
});
|
||||
}
|
||||
|
||||
// 输出三级菜单项文本
|
||||
const menuTexts = thirdMenuItems.map(item => item.text).join(', ');
|
||||
console.log(`三级菜单项: ${menuTexts}`);
|
||||
} else {
|
||||
console.log(`菜单项 "${menuItem.text}" 没有三级菜单`);
|
||||
}
|
||||
|
||||
// 根据是否有三级菜单调用相应的处理函数
|
||||
if (hasThirdMenu && processWithThirdMenu) {
|
||||
await processWithThirdMenu(menuItem, thirdMenuItems);
|
||||
} else if (!hasThirdMenu && processWithoutThirdMenu) {
|
||||
await processWithoutThirdMenu(menuItem);
|
||||
}
|
||||
|
||||
return {hasThirdMenu, thirdMenuItems};
|
||||
} catch (error) {
|
||||
console.error(`处理菜单项时出错: ${error}`);
|
||||
return {hasThirdMenu: false, thirdMenuItems: []};
|
||||
}
|
||||
}
|
||||
|
||||
async handleAllMenuClicks(menuItems) {
|
||||
for (let i = 0; i < menuItems.length; i++) {
|
||||
await this.handleSingleMenuClick(menuItems[i]);
|
||||
@ -547,6 +329,33 @@ class LongiMainPage extends BasePage {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行内存回收
|
||||
* @param {string} context 执行内存回收的上下文信息,用于日志
|
||||
* @returns {Promise<void>}
|
||||
* @private
|
||||
*/
|
||||
async cleanupMemory(context = '') {
|
||||
try {
|
||||
await this.page.evaluate(() => {
|
||||
// 清理DOM中的临时元素
|
||||
const cleanup = () => {
|
||||
const elements = document.querySelectorAll('.el-loading-mask, .el-message, .el-message-box');
|
||||
elements.forEach(el => el.remove());
|
||||
|
||||
// 如果浏览器支持手动垃圾回收,则执行
|
||||
if (window.gc) {
|
||||
window.gc();
|
||||
}
|
||||
};
|
||||
cleanup();
|
||||
});
|
||||
console.log(`🧹 执行内存回收${context ? ` - ${context}` : ''}`);
|
||||
} catch (error) {
|
||||
console.warn('执行内存回收时出错:', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
async handleSingleMenuClick(menu) {
|
||||
try {
|
||||
await this.expandSideMenu();
|
||||
@ -566,20 +375,7 @@ class LongiMainPage extends BasePage {
|
||||
}
|
||||
|
||||
// 执行内存回收
|
||||
await this.page.evaluate(() => {
|
||||
// 清理DOM中的临时元素
|
||||
const cleanup = () => {
|
||||
const elements = document.querySelectorAll('.el-loading-mask, .el-message, .el-message-box');
|
||||
elements.forEach(el => el.remove());
|
||||
|
||||
// 如果浏览器支持手动垃圾回收,则执行
|
||||
if (window.gc) {
|
||||
window.gc();
|
||||
}
|
||||
};
|
||||
cleanup();
|
||||
});
|
||||
console.log(`🧹 执行内存回收 - ${menu.text}`);
|
||||
await this.cleanupMemory(menu.text);
|
||||
|
||||
} catch (error) {
|
||||
console.error(`处理菜单失败 [${menu.text}]:`, error.message);
|
||||
@ -723,58 +519,59 @@ class LongiMainPage extends BasePage {
|
||||
* @param {Object} menu 菜单对象
|
||||
*/
|
||||
async handleThreeLevelMenu(menu) {
|
||||
try {
|
||||
console.log(`正在处理 ${menu.text} 菜单`);
|
||||
await menu.element.click();
|
||||
console.log(`处理三级菜单: ${menu.text}`);
|
||||
|
||||
// 等待一个短暂的时间让弹出层出现
|
||||
await this.page.waitForTimeout(500);
|
||||
// 1. 点击展开三级菜单
|
||||
await menu.element.click();
|
||||
await this.page.waitForTimeout(500);
|
||||
|
||||
// 获取三级菜单列表
|
||||
const thirdMenus = await this.getThirdLevelMenus(menu);
|
||||
// 2. 获取三级菜单列表
|
||||
const thirdMenus = await this.getThirdLevelMenus(menu);
|
||||
if (thirdMenus.length === 0) {
|
||||
console.log(`未找到三级菜单项`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 这里可以根据需要处理三级菜单项
|
||||
for (const thirdMenu of thirdMenus) {
|
||||
await this.handleMenuClick(thirdMenu, menu);
|
||||
// 3. 处理每个三级菜单项
|
||||
for (let i = 0; i < thirdMenus.length; i++) {
|
||||
const thirdMenu = thirdMenus[i];
|
||||
console.log(`处理第 ${i + 1}/${thirdMenus.length} 个三级菜单项: ${thirdMenu.text}`);
|
||||
|
||||
// 如果不是最后一个菜单项,需要重新点击父菜单展开三级菜单
|
||||
if (thirdMenu !== thirdMenus[thirdMenus.length - 1]) {
|
||||
await menu.element.click();
|
||||
await this.page.waitForTimeout(500);
|
||||
}
|
||||
await this.handleMenuClick(thirdMenu, menu);
|
||||
|
||||
// 如果还有下一个菜单项,重新展开三级菜单
|
||||
if (i < thirdMenus.length - 1) {
|
||||
await menu.element.click();
|
||||
await this.page.waitForTimeout(500);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error(`处理三级菜单时出错 [${menu.text}]:`, error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用的菜单点击和页面加载处理方法
|
||||
* @param {Object} menuInfo 菜单信息对象,包含text属性
|
||||
* 处理菜单点击和页面加载
|
||||
* @param {Object} menuInfo 菜单信息对象
|
||||
* @param {Object} parentMenu 父级菜单(可选)
|
||||
* @returns {Promise<boolean>} 处理是否成功
|
||||
*/
|
||||
async handleMenuClick(menuInfo, parentMenu) {
|
||||
try {
|
||||
const menuPath = parentMenu.text ? `${parentMenu.text} > ${menuInfo.text}` : menuInfo.text;
|
||||
console.log(`🔸 点击菜单: ${menuPath}`);
|
||||
await menuInfo.element.click();
|
||||
// 等待页面加载
|
||||
const loadResult = await this.waitForPageLoadWithRetry(menuInfo);
|
||||
if (loadResult) {
|
||||
// 处理所有TAB页
|
||||
await this.handleAllTabs(menuInfo);
|
||||
async handleMenuClick(menuInfo, parentMenu = null) {
|
||||
const menuPath = parentMenu ? `${parentMenu.text} > ${menuInfo.text}` : menuInfo.text;
|
||||
console.log(`点击菜单: ${menuPath}`);
|
||||
|
||||
// 关闭标签页
|
||||
await this.closeActiveTab(menuPath);
|
||||
}
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error(`处理菜单点击失败 [${menuInfo.text}]:`, error.message);
|
||||
// 1. 点击菜单并等待页面加载
|
||||
await menuInfo.element.click();
|
||||
const loadResult = await this.waitForPageLoadWithRetry(menuInfo);
|
||||
|
||||
if (!loadResult) {
|
||||
console.warn(`页面加载失败: ${menuPath}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. 处理页面中的标签页
|
||||
await this.handleAllTabs(menuInfo);
|
||||
|
||||
// 3. 关闭当前标签页
|
||||
await this.closeActiveTab(menuPath);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -792,14 +589,7 @@ class LongiMainPage extends BasePage {
|
||||
// 直接使用传入的element点击
|
||||
await tabInfo.element.click();
|
||||
|
||||
// 等待页面加载
|
||||
const loadResult = await this.waitForPageLoadWithRetry(parentMenu, tabInfo.text);
|
||||
if (!loadResult) {
|
||||
console.warn('页面加载失败');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return !await this.waitForPageLoadWithRetry(parentMenu, tabInfo.text);
|
||||
} catch (error) {
|
||||
console.error(`处理TAB页失败 [${parentMenu.text} > ${tabInfo.text}]:`, error.message);
|
||||
return false;
|
||||
@ -851,6 +641,7 @@ class LongiMainPage extends BasePage {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = LongiMainPage;
|
||||
Loading…
Reference in New Issue
Block a user