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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 07:25:39