You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 23:32:11