如何将Cypress测试运行器从第三方登录弹窗页面中脱离控制?
你想要的效果完全可以实现,核心思路是绕过Cypress对新窗口的劫持,复用同一个浏览器上下文让Puppeteer处理登录流程,具体操作如下:
实现步骤
1. 解除Cypress对登录弹窗的绑定
Cypress默认会劫持所有window.open调用,把新创建的窗口绑定到自身运行时上下文。你可以在触发登录弹窗的操作执行前,先覆盖原生方法绕过劫持:
// 点击登录按钮前执行该代码 cy.window().then(win => { // 缓存浏览器原生的open方法,避开Cypress的劫持逻辑 const nativeWindowOpen = win.open; win.open = (...args) => { const authPopup = nativeWindowOpen.apply(win, args); // 弹窗完全脱离Cypress控制,你可以将实例挂载到全局方便后续定位 win.__externalAuthPopup = authPopup; return authPopup; }; });
2. 配置Puppeteer接管弹窗完成登录
通过Cypress的cy.task能力调用Puppeteer进程,匹配到刚打开的第三方登录弹窗,完成自动化登录操作:
首先在cypress.config.js中注册调用Puppeteer的任务:
const { defineConfig } = require('cypress'); const puppeteer = require('puppeteer'); module.exports = defineConfig({ e2e: { chromeWebSecurity: false, // 关闭同源校验,避免跨域相关限制 setupNodeEvents(on, config) { on('task', { async completeThirdPartyAuth(authUrlMatchRule) { // 连接Cypress正在使用的Chrome实例(需提前开启远程调试端口) const browser = await puppeteer.connect({ browserURL: 'http://localhost:9222', defaultViewport: null }); // 匹配第三方登录弹窗页面 const allPages = await browser.pages(); const authPage = allPages.find(page => page.url().match(authUrlMatchRule)); if (!authPage) throw new Error('未找到第三方登录弹窗'); // 以下为登录操作示例,需根据你实际的登录页元素调整 await authPage.waitForSelector('input[name="username"]', { timeout: 10000 }); await authPage.type('input[name="username"]', '测试账号'); await authPage.type('input[name="password"]', '测试密码'); await authPage.click('button[type="submit"]'); // 等待登录完成、弹窗自动关闭 await authPage.waitForClose({ timeout: 15000 }); await browser.disconnect(); return null; } }); } } });
之后在测试用例中调用该任务即可:
// 触发登录弹窗 cy.get('#open-login-btn').click(); // 调用Puppeteer完成登录 cy.task('completeThirdPartyAuth', '^https://你的第三方登录域名前缀').then(() => { // 登录完成后Cypress主页面已同步登录态,直接执行业务测试逻辑即可 cy.url().should('include', '/login-success'); // 后续你的业务测试用例代码 });
3. 启动参数配置
运行测试前需要给Chrome开启远程调试端口,启动Cypress时添加对应参数即可:
cypress open --browser chrome --env CHROME_ARGS="--remote-debugging-port=9222"
可选优化方案
如果你不想用弹窗流程,也可以直接用Puppeteer提前走完第三方登录流程,将拿到的Cookie、localStorage等登录态信息导出,通过cy.setCookie、cy.setLocalStorage等API直接注入到Cypress上下文,完全跳过前端登录步骤,测试执行效率更高。
内容的提问来源于stack exchange,提问作者McCrockett
相关产品推荐
相关产品推荐

