Sponsored Link
Looking for a unified way to  viewmonitor, and  debug Playwright Test Automation runs?
Try the Playwright Dashboard by today. Use the coupon code PWSOL10 for a 12 month 10% discount.

How To Fix: apiRequestContext.fetch: Request context disposed

Within my automation tests at work, I found myself running into these two errors within my tests when I use the await page.route() (docs) functionality.

Error: apiRequestContext.fetch: Request context disposed
Error: apiRequestContext.fetch: Browser has been closed

With additional information
1 error was not a part of any test, see above for details

This typically happens when there is a request or a group of network requests that are made within a page, and the test finishes before the API request(s) are complete.

Reproducing the issue

I have an example that I am able to reproduce every 10 or so runs. If you want to see the failure you can download the repo and run this command.

npx playwright test tests/checkout/checkoutWithRoute.spec.ts --repeat-each 20

GitHub - playwrightsolutions/playwright-practicesoftwaretesting.com: Example using Playwright against site https://practicesoftwaretesting.com
Example using Playwright against site https://practicesoftwaretesting.com - GitHub - playwrightsolutions/playwright-practicesoftwaretesting.com: Example using Playwright against site https://practi...

The code for this test is below. You will note I do not have any assertions as I am using this as an example to prove out a solution that will resolve the errors listed above.

// checkoutWithRoute.spec.ts

import { expect } from "@playwright/test";
import { test, HomePage } from "@pages";

test.describe("UI with API Routing", () => {
  test("Checking for disposed api context", async ({ page }) => {
    await page.route(
      "https://api.practicesoftwaretesting.com/products?**",
      async (route) => {
        const response = await page.request.fetch(route.request());
        const responseBody = await response.json();
        route.continue();
      }
    );

    const homePage = new HomePage(page);
    await homePage.goto();
  });
});

An example of the error from the test report

The reason this happens is the network request is not finished even though the test has finished running. Against this application and this api request we are routing, it doesn't happen very often, but if you are routing multiple requests or if the application is fetching a lot of data this is more likely to happen.

Tips to prevent or fix these errors.

Check your awaits in your test file

First off make sure you have any browser or network interactions "awaited" properly ex: await homePage.goto(). If you aren't awaiting things properly you could get these errors or different areas depending on what actions are still being done at the test end.

Utilize waitForResponse()

Next use the function await page.waitForResponse() (docs) before your test ends to ensure all network traffic has responded. See the example below, now this test will never fail because a network connection is still open.

// checkoutWithRoute.spec.ts

import { expect } from "@playwright/test";
import { test, HomePage } from "@pages";

test.describe("UI with API Routing", () => {
  test("Checking for disposed api context", async ({ page }) => {
    await page.route(
      "https://api.practicesoftwaretesting.com/products?**",
      async (route) => {
        const response = await page.request.fetch(route.request());
        const responseBody = await response.json();
        route.continue();
      }
    );

    const homePage = new HomePage(page);
    await homePage.goto();

    await page.waitForResponse(
      "https://api.practicesoftwaretesting.com/products?**"
    );
  });
});

Make your routes very specific

In my repo at work, we have a reporting page where get all payments, and it ends up routing over 10 API calls that match the following pattern

await page.route("**/payment-intents?**", ...

One solution would be to make my route more verbose not using regex matchers something like. For the assertions in my test I really only needed the first 25 requests to be loaded. Limiting the amount of requests that get routed through page.route() should help with these tpyes of issues.

await page.route("**/payment-intents?offset=0&limit=25", ...

Wrapping Up

Overall these can be frustrating errors to troubleshoot, and resolve, mainly due to network timings of systems we test. If you have any other tips or tricks you've used to deal with these issues please reach out to me on LinkedIn and let me know!


Thanks for reading! If you found this helpful, reach out and let me know on LinkedIn or consider buying me a cup of coffee. If you want more content delivered to you in your inbox subscribe below, and be sure to leave a ❤️ to show some love.