如何在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
相关产品推荐
相关产品推荐

