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

为何Puppeteer的waitForNavigation()未等待重定向完成?

Puppeteer中waitForNavigation未捕捉到服务器重定向的问题解决

问题分析

你的场景是点击无权限链接后,服务器会先完成到a/conversations的跳转,紧接着又通过HTTP重定向到a/。page.waitForNavigation()默认只会等待单次导航完成,也就是到a/conversations这一步就结束监听,不会等待后续的服务器重定向跳转——这就是不加Bun.sleep(3000)时断言失败的核心原因:此时页面还未完成第二次重定向。

解决方案

方案1:等待两次导航完成

整个流程包含两次连续导航(点击链接→a/conversations→a/),可以连续调用两次waitForNavigation()来覆盖完整跳转流程:

await Promise.all([
  page.click('a[href="a/conversations"]'),
  page.waitForNavigation(), // 等待到a/conversations的跳转
  page.waitForNavigation()  // 等待到a/的重定向跳转
]);

方案2:监听导航事件直到目标URL出现

通过监听framenavigated事件,持续检查页面URL,直到其变为预期的目标地址:

// 封装等待目标URL的工具函数
const waitForTargetUrl = async (page, targetUrl) => {
  return new Promise(resolve => {
    const checkUrl = () => {
      if (page.url() === targetUrl) {
        page.off('framenavigated', checkUrl);
        resolve();
      }
    };
    page.on('framenavigated', checkUrl);
    // 立即检查一次,避免页面已提前到达目标URL
    checkUrl();
  });
};

// 点击链接并等待目标URL
await page.click('a[href="a/conversations"]');
await waitForTargetUrl(page, 'http://localhost:3000/a');

方案3:直接用waitForFunction断言URL

跳过waitForNavigation(),直接通过page.waitForFunction()等待页面URL符合预期:

await page.click('a[href="a/conversations"]');
await page.waitForFunction(
  () => window.location.href === 'http://localhost:3000/a'
);

优化后的完整测试代码

it('should validate test@test.org access flow', async () => {
  const browser = await puppeteer.launch({ slowMo:10 })
  await browser.deleteCookie()
  const page = await browser.newPage()
  page.setViewport({ width: 1080, height: 1024 })

  await page.goto('http://localhost:3000/a')
  expect(page.url()).toBe('http://localhost:3000/a/login')

  await page.type('input[type="email"]', 'test@test.org')
  await page.type('input[type="password"]', 'de17a9bb-1cd0')
  await Promise.all([
    page.click('input[type="submit"]'),
    page.waitForNavigation()
  ])

  expect(page.url()).toBe('http://localhost:3000/a')

  // 使用方案3的方式等待重定向完成
  await page.click('a[href="a/conversations"]');
  await page.waitForFunction(
    () => window.location.href === 'http://localhost:3000/a'
  );

  expect(page.url()).toBe('http://localhost:3000/a')

  await browser.close()
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 03:56:13