使用Puppeteer进行Google登录E2E测试的问题求助
解决Puppeteer无法访问Google登录弹窗元素的问题
Google登录弹窗是独立的新浏览器窗口(或标签页),你当前的page对象绑定的是原React应用页面,自然无法获取新窗口内的元素。需要先获取新窗口对应的Page实例,再进行后续操作。
具体修改步骤:
- 点击登录按钮前,监听浏览器的
targetcreated事件,捕获新创建的目标窗口 - 切换到新窗口的
Page实例,再等待并操作邮箱输入框 - 移除原来的
navigationPromise,因为点击按钮后不会触发原页面的导航
修改后的代码:
const chalk = require( 'chalk' ); class LoginAccount { constructor( page, browser ) { // 新增browser参数,用于监听新窗口 this.url = "http://localhost:3000" this.page = page; this.browser = browser; } async login( username, password ) { try { await this.page.goto( this.url ); const selector = '[role="button"]'; await this.page.waitForSelector( selector ); // 监听新窗口创建事件 const newWindowPromise = new Promise(resolve => { const listener = async target => { if (target.type() === 'page') { const newPage = await target.page(); // 验证是否是Google登录页面(可选,避免误捕获) if (newPage.url().includes('accounts.google.com')) { this.browser.off('targetcreated', listener); resolve(newPage); } } }; this.browser.on('targetcreated', listener); }); // 点击登录按钮 await this.page.click(selector); // 获取新窗口的Page实例 const googleLoginPage = await newWindowPromise; await googleLoginPage.waitForLoadState(); // 等待页面加载完成 // 操作新窗口内的邮箱输入框 const email_field = 'input[type="email"]' await googleLoginPage.waitForSelector( email_field ); console.log("Got email input") await googleLoginPage.type( email_field, username ); // 后续可以继续处理密码输入、登录按钮点击等操作 // const password_field = 'input[type="password"]' // await googleLoginPage.waitForSelector(password_field); // await googleLoginPage.type(password_field, password); // await googleLoginPage.click('button[type="submit"]'); // 如果登录后会跳回原页面,可切换回去 // await this.page.bringToFront(); } catch ( err ) { console.log( chalk.red( 'ERROR => ', err ) ); } } } // 导出时需要传入browser参数 module.exports = ( page, browser ) => new LoginAccount( page, browser );
额外注意事项:
- 初始化
LoginAccount时,需要把Puppeteer的browser实例也传进去,比如在测试入口处:const puppeteer = require('puppeteer'); const LoginAccount = require('./your-file-path'); (async () => { const browser = await puppeteer.launch({ headless: false }); // 非无头模式方便调试 const page = await browser.newPage(); const login = LoginAccount(page, browser); await login.login('your-email', 'your-password'); // 后续操作... await browser.close(); })(); - 如果是无头模式运行,需要确保Puppeteer的配置允许弹出新窗口,可在
launch时添加参数:const browser = await puppeteer.launch({ headless: 'new', args: ['--disable-popup-blocking'] });
内容的提问来源于stack exchange,提问作者TonyM
相关产品推荐
相关产品推荐

