GitLab CI中Cypress+Azure AD认证测试登录弹窗异常问题
解决GitLab CI中Cypress AAD认证测试的登出弹窗问题
问题分析
本地执行Cypress的AAD认证测试时,靠cy.wait(1000)能绕过偶尔出现的登出弹窗,但在GitLab CI环境里,哪怕把等待时长拉到4000ms,测试还是会因这个弹窗失败。核心问题在于固定等待没法适配CI环境的网络、加载波动,而且初始访问应用时可能残留未清理的会话状态。
解决方案
1. 用条件处理替代固定等待
别依赖固定时长等弹窗消失,直接检测登出弹窗是否存在,有就主动处理,确保页面能正常跳转到登录流程:
修改loginViaAAD函数开头的逻辑:
function loginViaAAD(username, password) { cy.visit('http://localhost:3000/'); // 检测并处理登出弹窗,替换固定等待 cy.get('body').then(($body) => { // 这里根据你实际的登出弹窗元素选择器调整,比如登出按钮、弹窗容器 const logoutElement = $body.find('[data-testid="logout-btn"], .logout-modal'); if (logoutElement.length > 0) { // 如果有登出弹窗,点击取消按钮(或者根据页面逻辑等待弹窗自动关闭) cy.get('[data-testid="cancel-logout"]').click(); // 或者用断言等待弹窗消失:cy.get('.logout-modal').should('not.exist'); } // 确保页面进入登录入口状态 cy.get('[data-testid="login-trigger"]').should('be.visible'); }); // 后续原有登录逻辑保持不变... }
2. 优化Session管理逻辑
在会话初始化时主动清理缓存和Cookie,避免残留会话导致异常,同时强化验证步骤:
Cypress.Commands.add('loginToAAD', (username, password) => { cy.session( `AAD-${username}`, () => { const log = Cypress.log({ displayName: 'Azure Active Directory Login', message: [`Authenticating | ${username}`], autoEnd: false, }); log.snapshot('before'); // 主动清理缓存,确保登录环境干净 cy.clearCookies(); cy.clearLocalStorage(); loginViaAAD(username, password); log.snapshot('after'); log.end(); }, { validate: () => { cy.visit('http://localhost:3000'); // 用更精准的元素校验登录状态,比如用户头像或专属登录标识 cy.get('.header__avatar-name').should('contain', Cypress.env('AAD_FULLNAME')); }, // 适配CI环境,延长会话超时时间 cacheAcrossSpecs: true, timeout: 60000, }, ); });
3. 确保CI中应用完全启动
CI脚本里应用启动后,必须等服务就绪再跑Cypress,避免提前访问导致页面异常:
e2e-tests: image: cypress/browsers:node-20.14.0-chrome-126.0.6478.114-1-ff-127.0.1-edge-126.0.2592.61-1 stage: test before_script: - npm ci --cache .npm --prefer-offline script: - npm run linux_start & # 等待应用服务就绪,检测3000端口是否可访问 - wait-on http://localhost:3000 - npx cypress run --browser chrome --env AAD_USERNAME=$AAD_USERNAME,AAD_FULLNAME=$AAD_FULLNAME,AAD_PASSWORD=$AAD_PASSWORD,TOTP_SECRET=$TOTP_SECRET artifacts: when: always paths: - cypress/videos/**/*.mp4 - cypress/screenshots/**/*.png expire_in: 1 day
注意:需要先安装
wait-on依赖:npm install wait-on --save-dev
4. 禁用浏览器缓存
在cypress.config.js里配置浏览器启动参数,禁用缓存避免会话残留:
module.exports = defineConfig({ e2e: { // ...其他原有配置 setupNodeEvents(on, config) { // ...原有逻辑 }, }, // 浏览器启动参数 browserLaunchOptions: { args: [ '--disable-cache', '--disable-application-cache', '--disable-offline-load-stale-cache', '--disk-cache-size=0', ], }, });
核心思路总结
- 抛弃固定等待,改用条件判断+元素可见性校验,适配不同环境的加载差异;
- 会话初始化时主动清理缓存和Cookie,确保每次登录都是全新状态;
- CI中必须等待应用完全就绪后再启动测试,避免提前访问导致的页面异常;
- 禁用浏览器缓存,防止会话残留引发的异常弹窗。
内容的提问来源于stack exchange,提问作者Georgios
相关产品推荐
相关产品推荐

