如何用Puppeteer获取Google Pay iframe上下文,完成Adyen支付测试
问题
测试Adyen Drop-in Google Pay集成时,完成登录、跳转至含GPay按钮的页面并点击按钮后,无法点击弹出窗口中的支付按钮。尝试使用targets和frames方法均未成功获取支付弹窗内容,附上测试脚本寻求帮助。
测试脚本:
const puppeteer = require('puppeteer-extra'); const StealthPlugin = require('puppeteer-extra-plugin-stealth'); puppeteer.use(StealthPlugin()); const dotenv = require('dotenv'); dotenv.config(); const clickGooglePayButton = async () => {}; const loginFromPage = async (browser) => { const page = await browser.newPage(); await page.goto(process.env.LOGIN_LINK); const email = 'input[type="email"]'; const password = 'input[type="password"]'; await page.waitForSelector(email); await page.type(email, process.env.EMAIL); await page.keyboard.press('Enter'); await page.waitForNavigation(); await page.waitForSelector(password); await page.type(password, process.env.PASS); await page.keyboard.press('Enter'); await page.waitForNavigation(); return page; } const run = async () => { const browser = await puppeteer.launch({ headless: false, slowMo: 50, args: [ '--disable-web-security', '--disable-features=IsolateOrigins,site-per-process', ], }); await loginFromPage(browser); const gpayTabRef = await browser.newPage(); await gpayTabRef.goto(process.env.GPAY_LINK); const gpayButton = await gpayTabRef.waitForSelector('div.gpay-card-info-container-fill button'); console.log(gpayButton); await gpayButton.click(); const openPages = await browser.pages(); console.log(openPages); const targets = browser.targets(); const targetFrame = await browser.waitForTarget(target => target.url().includes('https://pay.google.com/gp/p/ui/payframe?origin')); console.log('returning the target type'); console.log(targetFrame.type()); console.log(await targetFrame.page()); } run();
尝试操作targets时,支付框架并非页面,target的page方法返回null;尝试frames方法也无法获取支付弹窗内容,需要指导。
解决方案
核心思路
Google Pay支付弹窗是嵌入在主页面的iframe中,而非独立页面,因此不能通过target.page()获取,需切换到iframe上下文进行操作。
具体调整步骤
- 禁用弹窗拦截
在浏览器启动参数中加入--disable-popup-blocking,确保Google Pay弹窗正常加载:
const browser = await puppeteer.launch({ headless: false, slowMo: 50, args: [ '--disable-web-security', '--disable-features=IsolateOrigins,site-per-process', '--disable-popup-blocking' // 新增参数 ], });
- 定位并切换到Google Pay iframe
点击GPay按钮后,等待目标iframe加载完成,通过frame的URL特征匹配定位:
// 点击GPay按钮后,等待iframe加载 await gpayButton.click(); const gpayIframe = await gpayTabRef.waitForFrame(frame => frame.url().includes('https://pay.google.com/gp/p/ui/payframe') );
- 在iframe上下文操作支付按钮
切换到iframe后,等待支付按钮出现并点击。注意需根据实际弹窗中的按钮属性调整选择器(可通过Chrome开发者工具查看元素):
// 等待支付按钮加载并点击 await gpayIframe.waitForSelector('button[aria-label="完成支付"]'); // 替换为实际按钮选择器 await gpayIframe.click('button[aria-label="完成支付"]');
修改后的完整run函数
const run = async () => { const browser = await puppeteer.launch({ headless: false, slowMo: 50, args: [ '--disable-web-security', '--disable-features=IsolateOrigins,site-per-process', '--disable-popup-blocking' ], }); await loginFromPage(browser); const gpayTabRef = await browser.newPage(); await gpayTabRef.goto(process.env.GPAY_LINK); const gpayButton = await gpayTabRef.waitForSelector('div.gpay-card-info-container-fill button'); await gpayButton.click(); // 定位Google Pay iframe const gpayIframe = await gpayTabRef.waitForFrame(frame => frame.url().includes('https://pay.google.com/gp/p/ui/payframe') ); // 点击支付按钮(需根据实际元素调整选择器) await gpayIframe.waitForSelector('button[aria-label="完成支付"]'); await gpayIframe.click('button[aria-label="完成支付"]'); }
注意点
- 若按钮选择器不匹配,直接在浏览器中打开Google Pay弹窗,右键检查元素获取准确的选择器(如class、id或其他属性)。
- 若iframe加载延迟较高,可添加
page.waitForTimeout(1000)(应急可用)或结合waitForNavigation确保页面状态稳定。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

