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

Puppeteer仅首个请求响应正常,其余测试用例报404问题排查

问题原因
  • 首个测试用例处理完目标请求后,调用了page.setRequestInterception(false)直接关闭了全局请求拦截功能,后续测试用例即使重新开启拦截,也会因为状态未正确重置而失效。
  • page.off("request", requestHandler)虽移除了当前用例的拦截器,但如果测试用例间未做页面状态隔离,后续请求无法被新的拦截器捕获,导致请求未被拦截返回404。
修复方案

方案1:每个测试用例使用独立Page实例(推荐)

通过在beforeEach创建新页面、afterEach关闭页面,确保每个用例状态完全隔离:

describe("Login Providers Tests", function () {
  let page;

  beforeEach(async function () {
    page = await browser.newPage();
  });

  afterEach(async function () {
    await page.close();
  });

  it("Renders providers from core", async function () {
    await page.setRequestInterception(true);
    const requestHandler = (request) => {
      if (request.method() === "GET" && request.url() === LOGIN_METHODS_API) {
        request.respond({
          status: 200,
          contentType: "application/json",
          body: JSON.stringify({
            emailPassword: { enabled: true },
            passwordless: { enabled: true },
            thirdParty: {
              enabled: true,
              providers: [
                { id: "apple", name: "Apple" },
                { id: "github", name: "Github" },
              ],
            },
          }),
        });
      } else {
        request.continue();
      }
    };
    page.on("request", requestHandler);
    await Promise.all([
      page.goto(`${TEST_CLIENT_BASE_URL}${DEFAULT_WEBSITE_BASE_PATH}?authRecipe=thirdparty&multitenancy=enabled`),
      page.waitForNavigation({ waitUntil: "networkidle0" }),
    ]);
    const providers = await getProvidersLabels(page);
    assert.deepStrictEqual(providers, ["Continue with Apple", "Continue with Github"]);
  });

  // 其他测试用例结构一致
});

方案2:单Page实例下重置拦截状态

若不想创建多页面,需在每个用例开始前重置拦截状态,且仅移除当前监听器、不关闭全局拦截:

it("Renders providers from core", async function () {
  // 重置拦截状态
  await page.setRequestInterception(false);
  await page.removeAllListeners("request");
  
  await page.setRequestInterception(true);
  const requestHandler = (request) => {
    if (request.method() === "GET" && request.url() === LOGIN_METHODS_API) {
      request.respond({
        status: 200,
        contentType: "application/json",
        body: JSON.stringify({
          emailPassword: { enabled: true },
          passwordless: { enabled: true },
          thirdParty: {
            enabled: true,
            providers: [
              { id: "apple", name: "Apple" },
              { id: "github", name: "Github" },
            ],
          },
        }),
      });
      page.off("request", requestHandler);
    } else {
      request.continue();
    }
  };
  page.on("request", requestHandler);
  await Promise.all([
    page.goto(`${TEST_CLIENT_BASE_URL}${DEFAULT_WEBSITE_BASE_PATH}?authRecipe=thirdparty&multitenancy=enabled`),
    page.waitForNavigation({ waitUntil: "networkidle0" }),
  ]);
  const providers = await getProvidersLabels(page);
  assert.deepStrictEqual(providers, ["Continue with Apple", "Continue with Github"]);
});
关键注意事项
  • 不要在单个用例中调用page.setRequestInterception(false),否则会导致后续所有用例拦截功能失效。
  • 每个测试用例开始前清除旧的请求监听器,避免多监听器冲突。
  • 优先采用独立Page实例的方式,这是Playwright官方推荐的测试隔离最佳实践,能彻底避免状态污染问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 14:30:32