DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • Supercharging Pytest: Integration With External Tools
  • Playwright Fixtures vs POM: Which One Should You Choose?
  • Exploring Playwright’s Feature “Copy Prompt”
  • Mastering Redirects With Cloudflare Bulk Redirects

Trending

  • Simpler Data Transfer Objects With Java Records
  • Assessing Bias in AI Chatbot Responses
  • How Can Developers Drive Innovation by Combining IoT and AI?
  • Navigating Double and Triple Extortion Tactics
  1. DZone
  2. Coding
  3. Tools
  4. Fixtures (Built-in Fixtures) in Playwright

Fixtures (Built-in Fixtures) in Playwright

Playwright fixtures, like page or browser, simplify tests by saving setup time, ensuring isolation, and handling automatic cleanup for consistency.

By 
Kailash Pathak user avatar
Kailash Pathak
DZone Core CORE ·
Mar. 07, 25 · Tutorial
Likes (1)
Comment
Save
Tweet
Share
3.2K Views

Join the DZone community and get the full member experience.

Join For Free

What Are Fixtures In Playwright?

In Playwright, fixtures are objects that help you set up your tests efficiently. Think of them as “ready-made helpers” that provide things you commonly need, like a browser page, so you don’t have to create them from scratch every time.

Explanation

Let’s start with an example of a page fixture. Here’s the code to explain the page fixture:

JavaScript
 
import { test, expect } from '@playwright/test'; 

test('basic test', async ({ page }) => { 
  await page.goto('https://playwright.dev/'); 
  await expect(page).toHaveTitle(/Playwright/); 
});


In the above code:

  • 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.

A Very Basic Example

Imagine you’re testing a simple website, like a login page. Here’s how page fixtures help.

JavaScript
 
import { test, expect } from '@playwright/test';
test('login page test', async ({ page }) => {
  
  await page.goto('https://example.com/login'); 
  await expect(page).toHaveURL(/login/); 
});


  • Without fixtures: You’d have to manually write code to launch a browser, open a new tab, etc.
  • With fixtures: Playwright says, “Don’t worry, I’ll give you a page ready to go!”

Why Are Fixtures Useful?

  • Saves time. You don’t need to set up a browser or page yourself.
  • Ensure consistency. Every test gets the same fresh page to work with.
  • Automatic cleanup. Playwright automatically closes the browser after the test, so you don’t have to.

Other Fixtures in Playwright

Besides page, Playwright offers other fixtures like:

  • browser – Gives you a whole browser
  • context – Gives you a browser context (like a fresh session with cookies)
  • request – Helps you make API calls
  • browserName – Help you to know in which browser your test is running

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.

JavaScript
 
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/);
});


Why use it? If you need to control the browser directly or create multiple pages in one test.

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.

JavaScript
 
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
});


Why use it? To manage cookies, local storage, or test multiple user sessions without interference.

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.

JavaScript
 
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);
});


Why use it? To test backend APIs or mock responses without needing a browser page.

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.

JavaScript
 
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 for 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.

Leverage Built-In Fixtures Instead of Manual Setup

Playwright’s built-in fixtures (like page, context, browser) are optimized and handle setup/teardown for you. Avoid manually creating resources unless absolutely necessary.

JavaScript
 
// Bad: Manually launching a browser
import { chromium } from '@playwright/test';
test('manual setup', async () => {
  const browser = await chromium.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await browser.close();
});

// Good: Use the built-in fixtures
import { test, expect } from '@playwright/test';
test('using fixture', async ({ page }) => {
  await page.goto('https://example.com');
});


Reason? The page fixture automatically manages browser launch and cleanup, saving you code and ensuring consistency.

Use Fixtures Only When Needed

Don’t include unused fixtures in your test signature — it keeps your code cleaner and avoids unnecessary overhead.

JavaScript
 
// 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');
});


Reason? Unused fixtures still get initialized, which can slightly slow down your tests and clutter your code.

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.

JavaScript
 
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');
});


Reason? 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).

JavaScript
 
// 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/);
});


Reason? Custom fixtures reduce duplication and make tests more readable and maintainable.

Summary

In Playwright, fixtures are handy objects that are provided to make testing easier. It’s like borrowing a pre-opened notebook to write your test instead of making a new one from scratch. You just use it, and Playwright handles the rest!

Fixture (tool) Requests Testing Tool

Published at DZone with permission of Kailash Pathak. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Supercharging Pytest: Integration With External Tools
  • Playwright Fixtures vs POM: Which One Should You Choose?
  • Exploring Playwright’s Feature “Copy Prompt”
  • Mastering Redirects With Cloudflare Bulk Redirects

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!