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

Node.js下Playwright点击链接打开新页后出现waitForEvent超时报错

问题原因

该问题属于旧版Playwright v14的时序竞争问题,非调试模式下运行速度快,会触发两种异常场景:

  • context级别的page事件监听会捕获当前上下文所有新创建的页面,若点击后除了预期弹窗外还有后台隐形页面/iframe创建,会导致监听器捕获到非预期页面对象,预期的页面事件未被命中,监听器持续挂起直到触发全局30秒超时。
  • 旧版本context.waitForEvent的内部监听器注册存在微小时序窗口,极端情况下点击触发弹窗的速度快于监听器注册完成的速度,导致事件被漏掉,监听器无限等待超时。
    调试模式下运行速度慢,监听器可完全注册完成后才触发点击动作,因此不会触发报错。
解决方案

按优先级选择以下方案即可解决:

  1. 优先使用当前页面的popup事件替代全局context的page事件,专门捕获当前页点击触发的弹窗,避免捕获无关页面创建事件:
await test.step(`Step name`, async () => {
    const [newPage] = await Promise.all([ 
        page.waitForEvent('popup'),
        page.click('//span[normalize-space(@title)="Bup"]')
    ]);
    // 可选:等待新页面加载完成,保证后续操作稳定执行
    await newPage.waitForLoadState();
});
  1. 若需保留context.waitForEvent用法,可增加匹配规则和显式超时,避免无限制等待:
await test.step(`Step name`, async () => {
    const [newPage] = await Promise.all([ 
        context.waitForEvent('page', {
            // 只匹配目标页面的URL特征,替换为你实际的页面地址特征
            predicate: page => page.url().includes('目标页面url关键词'),
            timeout: 10000
        }), 
        page.click('//span[normalize-space(@title)="Bup"]', {
            timeout: 10000
        })
    ]);
    await newPage.waitForLoadState();
});
  1. 兜底时序优化写法,拆分监听和点击逻辑,彻底避免注册时序问题:
await test.step(`Step name`, async () => {
    // 先预注册弹窗监听
    const newPagePromise = page.waitForEvent('popup');
    // 再执行点击操作
    await page.click('//span[normalize-space(@title)="Bup"]');
    // 等待获取新页面
    const newPage = await newPagePromise;
    await newPage.waitForLoadState();
});

内容的提问来源于stack exchange,提问作者Antony

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 10:39:03