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

如何在Cypress中访问新窗口元素?(Azure登录场景)

测试Azure Login新窗口元素访问问题

[Azure登录按钮截图]

我正在测试Azure Login功能。

在此场景中,点击后会打开一个新窗口,我需要访问该新窗口内的元素,但新窗口的确切URL未知。

[Azure登录界面截图]

我尝试了以下解决方案,但无法衔接新窗口的操作逻辑:

export const loginWithAzure = (email, password) => {

  cy.window().then(win => {
    cy.stub(win, 'open').as('open')
  })

  // 在测试窗口操作
  clickButtonByText('Azure Login');
  cy.get('@open').should('have.been.calledOnce');

  //------如何衔接新窗口的操作逻辑------------

  // 新窗口内的操作(无法执行)
  getElement('[name=loginfmt]').typeIfNotEmpty(email).should('have.value', email);
  clickButtonByText('Next');
  getElement('[name=passwd]').typeIfNotEmpty(password).should('have.value', password);
  clickButtonByText('Sign in');

}

解决方法

方法一:通过Stub获取新窗口实例直接操作

拦截window.open获取新窗口的引用,之后直接对新窗口的DOM进行操作:

export const loginWithAzure = (email, password) => {
  let newWindow;

  cy.window().then(win => {
    // 拦截open方法,保存新窗口实例
    cy.stub(win, 'open').callsFake((url, target) => {
      newWindow = win.open(url, target);
      return newWindow;
    }).as('open');
  });

  // 触发登录按钮点击
  clickButtonByText('Azure Login');
  cy.get('@open').should('have.been.calledOnce');

  // 切换到新窗口上下文执行操作
  cy.wrap(newWindow).then(win => {
    cy.wrap(win.document).find('[name=loginfmt]').typeIfNotEmpty(email).should('have.value', email);
    cy.wrap(win.document).contains('Next').click();
    cy.wrap(win.document).find('[name=passwd]').typeIfNotEmpty(password).should('have.value', password);
    cy.wrap(win.document).contains('Sign in').click();
  });
}

方法二:使用cy.origin处理跨域场景

如果新窗口属于不同域名(Azure登录通常是跨域),Cypress 9+支持cy.origin直接切换到目标域名上下文操作:

export const loginWithAzure = (email, password) => {
  let loginUrl;

  cy.window().then(win => {
    cy.stub(win, 'open').callsFake((url) => {
      loginUrl = url;
      return win.open(url);
    }).as('open');
  });

  clickButtonByText('Azure Login');
  cy.get('@open').should('have.been.calledOnce');

  // 解析新窗口域名,切换到对应上下文
  cy.wrap(loginUrl).then(url => {
    const domain = new URL(url).hostname;
    
    cy.origin(domain, { args: { email, password } }, ({ email, password }) => {
      cy.get('[name=loginfmt]').type(email).should('have.value', email);
      cy.contains('Next').click();
      cy.get('[name=passwd]').type(password).should('have.value', password);
      cy.contains('Sign in').click();
    });
  });
}

注意事项

  • 确保自定义命令clickButtonByText、typeIfNotEmpty能在新窗口上下文正常工作,若出现问题可替换为Cypress原生命令(如cy.contains().click())
  • 同源新窗口直接用方法一即可,跨域场景必须使用cy.origin,否则Cypress会因为跨域限制无法操作元素

内容的提问来源于stack exchange,提问作者Tirath Sojitra

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 14:45:25