testing-library/playwright-testing-library

Usage of fixtures with a new browser context

ptbrowne opened this issue · 2 comments

Hi,

I've successfully used the screen and page fixtures provided by playwright-testing-library, thank you !
Now I want to record an HAR from my test to be able to replay it.
From the Playwright docs, we are instructed to create a new browser context https://playwright.dev/docs/network#recording-har-with-a-script. When I create a new browser context, I think I have to create a new page / screen fixture manually otherwise the page from the fixture is not the right one.

I haven't seen an example from the docs. I am currently trying with

import { locatorFixtures as fixtures } from "@playwright-testing-library/test/fixture";

...

      const context = await browser.newContext({
        recordHar: { path: `record.har` },
      });

      const page = await context.newPage();
      const screen = await fixtures.screen({ page });
      const within = await fixtures.within({ screen, page });

but it seems I've missing something to make it work. And the fixtures types do not have screen and within 🤔 Am I going in the right direction for this ? Would you do any other way ?

Hi @ptbrowne, thanks for creating an issue for this. The fixtures exported from @playwright-testing-library/test/fixture (locatorFixtures) must be applied to @playwright/test via the extend API per the setup instructions from the readme. It sounds like you are probably already doing that correctly, but that bit is snipped out in your example above (...) so I just want to be explicit about that. The only way to access Testing Library queries is from the fixtures (page, screen, within) provided to your test() functions.

Fortunately, the within fixture is designed to handle use cases like the one you've described. If you pass a Page instance to within(page) instead of a Locator, it will return a Screen instance for you like so:

import { locatorFixtures as fixtures } from '@playwright-testing-library/test/fixture';
import { test as base } from '@playwright/test';

// --- ✂️ --- (`base.extend` setup from readme)

test('example with HAR recording', async ({ within }) => {
	const context = await browser.newContext({ recordHar: { path: `record.har` } });
	const page = await context.newPage();
	
	// Pass the `Page` instance spawned from the HAR context to `within`
	const screen = within(page);
	
	const locator = screen.getByRole('button', { name: 'Hi Mom!' });

	await locator.click();
	
    // --- ✂️ ---
});

Let me know if you have any problems with the above approach. You could probably even abstract it into your own fixture if you use the recording in many tests.

Some alternatives that may also be worth considering:

  • Use the CLI options to set up the recording.
  • I'd be remiss if I didn't point out that Playwright just released native Testing Library queries in 1.27.0. Check out #558 for more details and a comparison with this library.

Thanks for the quick and thorough response @jrolfs !

  • In the meantime, I used the global testing library Playwright options to set up the recording option in the browser context.
  • I had not thought of using directly within against the page, thanks, it would work for me, and I would be able to more easily control dynamically the name of the recording, than if I do it in the global config !
  • Thanks for the links, I'll have to dig into that !