What Are Fixtures in Playwright?
Fixtures are reusable components that are automatically set up before your test runs and torn down after it finishes. They can provide things like:
- A browser or browser context
- A logged-in state
- Page objects
- Custom test data
In simpler terms, fixtures are like helpers that make sure everything your test needs is ready to go — and cleaned up afterward.
Built-in Fixtures in Playwright
Playwright comes with several built-in fixtures, including:
- page : A new browser tab for each test. Most used fixture.
- browser : Provides access to the browser instance.
- context : An isolated browser context for each test (like a new browser profile).
- request : Used for API testing. Sends HTTP requests without launching a browser.
- testInfo : Contains metadata like test title, timeout, retries, etc.
1. page fixture
Let’s start with taking an example of page fixture, Here’s the code to explain the page fixture:
import { test, expect } from '@playwright/test'; test('basic test', async ({ page }) => { await page.goto('https://playwright.dev/'); await expect(page).toHaveTitle(/Playwright/); });
- The page object is a fixture provided by Playwright.
- It’s automatically created for your test, and it represents a browser page (like a tab in Chrome or Firefox) that you can use to interact with a website.
- { page }: Playwright gives this fixture to you inside the curly braces {}. It’s like saying, “Hey, give me a browser page to work with!”
- You didn’t have to write code to open a browser or create a page — Playwright does that for you automatically using the page fixture.
2. browser Fixture
The browser fixture gives you access to the entire browser instance (e.g., Chrome, Firefox). You can use it to control the browser or launch multiple pages.
import { test, expect } from '@playwright/test'; test('check browser type', async ({ browser }) => { // Open a new page manually using the browser fixture const page = await browser.newPage(); await page.goto('https://example.com'); await expect(page).toHaveTitle(/Example/); });
If you need to control the browser directly or create multiple pages in one test.
3. context Fixture
The context fixture provides a browser context, which is like a fresh browsing session (e.g., with its own cookies, storage, etc.). It’s useful for testing things like logins or isolated sessions.
import { test, expect } from '@playwright/test'; test('check cookies in context', async ({ context }) => { // "context" fixture gives you a fresh browser session const page = await context.newPage(); await page.goto('https://example.com'); // Add a cookie to the context await context.addCookies([{ name: 'myCookie', value: 'hello', domain: '.example.com', path: '/' }]); console.log('Cookies:', await context.cookies()); // Prints the cookies });
To manage cookies, local storage, or test multiple user sessions without interference.
4. request Fixture
The request fixture lets you make HTTP requests (like GET or POST) directly, which is great for testing APIs alongside your webpage tests.
import { test, expect } from '@playwright/test'; test('test an API', async ({ request }) => { // "request" fixture lets you send HTTP requests const response = await request.get('https://api.example.com/data'); // Check if the API returns a successful status expect(response.ok()).toBe(true); // Check the response body const data = await response.json(); console.log('API Response:', data); });To test backend APIs or mock responses without needing a browser page.
5. browserName Fixture
The browserName fixture tells you which browser your test is running in (e.g., “chromium”, “firefox”, or “webkit”). It’s handy for writing browser-specific tests.
import { test, expect } from '@playwright/test'; test('check browser name', async ({ browserName }) => { // "browserName" fixture tells you the browser being used console.log('Running in:', browserName); if (browserName === 'chromium') { console.log('This is Chrome or Edge!'); } else if (browserName === 'firefox') { console.log('This is Firefox!'); } });
Best Practices of Using Fixtures in Playwright
Using fixtures in Playwright effectively can make your tests cleaner, more maintainable, and easier to scale. Below are some best practices for using fixtures in Playwright, explained with simple examples and reasoning. These practices will help you avoid common pitfalls and get the most out of Playwright’s powerful fixture system.
Use Fixtures Only When Needed
Don’t include unused fixtures in your test signature — it keeps your code cleaner and avoids unnecessary overhead.
// Bad: Including unused fixtures test('simple test', async ({ page, browser, context, request }) => { await page.goto('https://example.com'); // Only "page" is used }); // Good: Only include what you need test('simple test', async ({ page }) => { await page.goto('https://example.com'); });
Use context for Isolation
The context fixture provides a fresh browser context (e.g., separate cookies, storage). Use it when you need isolated sessions, like testing multiple users.
test('test two users', async ({ context }) => { const page1 = await context.newPage(); await page1.goto('https://example.com/login'); await page1.fill('#user', 'user1'); // New context for a second user const newContext = await context.browser().newContext(); const page2 = await newContext.newPage(); await page2.goto('https://example.com/login'); await page2.fill('#user', 'user2'); });
context ensures each test or user session is independent, avoiding interference (e.g., shared cookies).
Create Custom Fixtures for Reusable Setup
If you have repeated setup logic (e.g., logging in), create a custom fixture to keep your tests DRY (Don’t Repeat Yourself).
// Define a custom fixture const { test: base } = require('@playwright/test'); const test = base.extend({ loggedInPage: async ({ page }, use) => { await page.goto('https://example.com/login'); await page.fill('#username', 'testuser'); await page.fill('#password', 'password123'); await page.click('button[type="submit"]'); await use(page); // Pass the logged-in page to the test }, }); // Use the custom fixture test('use logged-in page', async ({ loggedInPage }) => { await loggedInPage.goto('https://example.com/dashboard'); await expect(loggedInPage).toHaveURL(/dashboard/); });
Custom fixtures reduce duplication and make tests more readable and maintainable.
This is all about built in fixture in playwright with basic and simple example.
No comments:
Post a Comment