Rayrun
← Back to Discord Forum

Modifying page fixture in beforeEach

Hey! I am working on setting up Playwright for our front-end application and we want to be able to test just the front-end and mock all API request. The idea was to use Playwright to record HTTP activity to HAR and then replay it when needed.

I want to have it as an easily reusable chunk to be able to use it in any test module and my idea was as follows:

before a test runs, check if a HAR file for this test (/tests/har/test-title,har) exists. If it does, use page.routeFromHAR.

If the HAR file doesn't exist, run the test normally and record network activity to a new HAR file with the recordHar field in browser.newContext.

But it seems that just creating a new context is not enough, I need to create a new page with browserContext.newPage() and then use the return of that for any successive .goto() etc calls?

But how can I create a page fixture in a beforeEach hook and then access that fixture from within the test itself? Or is there another recommended way to achieve the effect I'm trying to get to?

For reference, here's the hook I've come to so far:

test.beforeEach(async ({ page, browser, browserName }, testInfo) => {
  const harFilePath = getTestFileName(testInfo.title, browserName);
  console.debug(`Checking HAR file at: ${harFilePath}`);

  if (existsSync(harFilePath)) {
    console.debug('HAR file found, using it for the test');
    await page.routeFromHAR(harFilePath);
  } else {
    console.debug(
      'HAR file not found, running test without it and recording answers to a new HAR file'
    );
    browserContext = await browser.newContext({
      recordHar: {
        path: harFilePath,
        mode: 'full',
        urlFilter: '*',
      },
    });
    const page = await browserContext.newPage();
    // How to use the above inside each test?
  }
});

This thread is trying to answer question "How can I create a page fixture in a beforeEach hook and then access that fixture from within the test itself?"

2 replies

You can't replace page fixture for a test in beforeEach hook. You can, however, create your own page fixture.

// fixture.ts
import { test as base, Page } from '@playwright/test'

export const test = base.extend({
    page: async ({ browser, browserName }, use) => {
        const page: Page;
        // branch out initialization of page here
        // ... do beforeEach stuff here
        await use(page);
    }
});

Thank you! I just got to it myself as well:

export const test = base.extend({
  page: async ({ page, browser, browserName }, use, testInfo) => {
    const harFilePath = getTestFileName(testInfo.title, browserName);
    console.debug(`Checking HAR file at: ${harFilePath}`);

    if (existsSync(harFilePath)) {
      console.debug('HAR file found, using it for the test');
      await page.routeFromHAR(harFilePath);
      await use(page);
    } else {
      console.debug(
        'HAR file not found, running test without it and recording answers to a new HAR file'
      );
      const browserContext = await browser.newContext({
        recordHar: {
          path: harFilePath,
          mode: 'minimal',
          urlFilter: '**/api/**',
        },
      });
      const page = await browserContext.newPage();

      // Run the test
      await use(page);

      await browserContext.close();
    }
  },
});
TwitterGitHubLinkedIn
AboutQuestionsDiscord ForumBrowser ExtensionTagsQA Jobs

Rayrun is a community for QA engineers. I am constantly looking for new ways to add value to people learning Playwright and other browser automation frameworks. If you have feedback, email luc@ray.run.