350 lines
12 KiB
JavaScript
350 lines
12 KiB
JavaScript
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 handleSecondLevelMenu = (menuItem) => {
|
||
cy.log(`📎 处理二级菜单: ${menuItem.text}`);
|
||
// TODO: 添加二级菜单的具体处理逻辑
|
||
// 1. 点击菜单
|
||
// 2. 验证页面加载
|
||
// 3. 检查页面内容
|
||
};
|
||
|
||
// 处理三级菜单的方法
|
||
const handleThirdLevelMenu = (menuItem) => {
|
||
cy.log(`📑 处理三级菜单: ${menuItem.text}`);
|
||
|
||
// 根据菜单索引找到对应的菜单元素
|
||
cy.get('.el-sub-menu__title, .el-menu-item').eq(menuItem.index).then($element => {
|
||
const processThirdMenuItems = ($thirdMenuItems, currentIndex = 0) => {
|
||
if (currentIndex >= $thirdMenuItems.length) {
|
||
cy.log(`✅ 完成所有三级菜单处理: ${menuItem.text}`);
|
||
return;
|
||
}
|
||
|
||
// 确保二级菜单展开并等待三级菜单出现
|
||
cy.wrap($element).click();
|
||
|
||
// 等待三级菜单弹出框出现
|
||
cy.get('.el-popper.is-light.el-popover', {timeout: 5000})
|
||
.should('be.visible')
|
||
.then(() => {
|
||
// 重新获取三级菜单项
|
||
cy.get('.el-popper.is-light.el-popover .menuTitle.canClick')
|
||
.should('be.visible')
|
||
.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.wait(1000).then(() => {
|
||
processThirdMenuItems($thirdMenuItems, currentIndex + 1);
|
||
});
|
||
});
|
||
});
|
||
};
|
||
|
||
// 开始处理三级菜单
|
||
cy.wrap($element).click();
|
||
|
||
// 等待三级菜单弹出框出现
|
||
cy.get('.el-popper.is-light.el-popover', {timeout: 5000})
|
||
.should('be.visible')
|
||
.then(() => {
|
||
cy.get('.el-popper.is-light.el-popover .menuTitle.canClick')
|
||
.should('be.visible')
|
||
.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();
|
||
};
|
||
|
||
// 测试入口
|
||
it('验证系统页面是否可用', () => {
|
||
// 验证环境参数
|
||
validateEnvironment();
|
||
// 登录系统
|
||
handleLogin();
|
||
|
||
// 创建常用元素别名
|
||
createAliases();
|
||
|
||
// 确保菜单展开
|
||
ensureMenuExpanded();
|
||
|
||
getLatestDataFileContent().then(result => {
|
||
if (result && result.content && result.content.menuItems) {
|
||
const totalMenus = result.content.menuItems.length;
|
||
const untestedMenus = result.content.menuItems.filter(item => !item.tested);
|
||
|
||
cy.log(`菜单项统计:总数 ${totalMenus},待测试 ${untestedMenus.length},已完成 ${totalMenus - untestedMenus.length}`);
|
||
|
||
// 遍历每个菜单项
|
||
result.content.menuItems.forEach((menuItem, index) => {
|
||
// 如果菜单项已测试,则跳过
|
||
if (menuItem.tested) {
|
||
cy.log(`⏭️ 跳过已测试的菜单项:${menuItem.text}`);
|
||
return;
|
||
}
|
||
|
||
cy.log(`🔄 正在处理第 ${index + 1} 个菜单项:${menuItem.text}`);
|
||
// 根据菜单层级调用不同的处理方法
|
||
if (menuItem.hasThirdMenu) {
|
||
handleThirdLevelMenu(menuItem);
|
||
} else {
|
||
handleSecondLevelMenu(menuItem);
|
||
}
|
||
|
||
});
|
||
} else {
|
||
cy.log('❌ 没有找到有效的菜单数据');
|
||
}
|
||
})
|
||
|
||
cy.log('✅ 系统菜单加载成功');
|
||
cy.log(`🏁 测试完成,环境: ${SELECT_ENV}`);
|
||
});
|
||
}); |