🎛️ Playwright Advanced Configuration
The Control Room of Your Test Factory
Imagine you’re the boss of a giant toy testing factory. Every day, hundreds of robots test thousands of toys. But running such a big operation needs special controls—buttons to start everything up, switches to decide which toys to test, and emergency stop buttons when things go wrong.
Playwright’s Advanced Configuration is exactly like having that control room. Let’s explore all the special buttons and switches!
🌅 Global Setup File: Opening the Factory
What Is It?
Think of the global setup file as your morning routine before the factory opens. Before any robot tests a single toy, you need to:
- Turn on the lights
- Start the machines
- Log into the computer systems
In Playwright terms: A global setup file runs once before ALL your tests start.
When Would You Use It?
- Log into a website and save the login session
- Create test data in a database
- Start a test server
- Clear old test files
How It Works
// playwright.config.js
export default {
globalSetup: './global-setup.js'
};
// global-setup.js
async function globalSetup() {
console.log('🌅 Factory opening!');
// Your setup code here
}
export default globalSetup;
Real Example: Save Login Session
// global-setup.js
import { chromium } from '@playwright/test';
async function globalSetup() {
const browser = await chromium.launch();
const page = await browser.newPage();
// Log in once
await page.goto('https://myapp.com/login');
await page.fill('#email', 'test@test.com');
await page.fill('#password', 'secret123');
await page.click('button[type="submit"]');
// Save the login session
await page.context().storageState({
path: './auth.json'
});
await browser.close();
}
export default globalSetup;
💡 Why is this cool? Instead of logging in 100 times for 100 tests, you log in once and all tests share that session!
🌙 Global Teardown File: Closing the Factory
What Is It?
After all the toys are tested, someone needs to clean up and close the factory:
- Turn off the machines
- Lock the doors
- Save the day’s report
The global teardown file runs once after ALL tests finish.
How It Works
// playwright.config.js
export default {
globalSetup: './global-setup.js',
globalTeardown: './global-teardown.js'
};
// global-teardown.js
async function globalTeardown() {
console.log('🌙 Factory closing!');
// Cleanup code here
}
export default globalTeardown;
Real Example: Cleanup Test Data
// global-teardown.js
import { deleteTestUsers } from './test-helpers';
async function globalTeardown() {
// Remove all test users we created
await deleteTestUsers();
// Delete temporary files
console.log('✨ All cleaned up!');
}
export default globalTeardown;
🔍 Test Grep Filtering: Finding Specific Toys
What Is It?
Imagine you have 10,000 toys but you only want to test the red cars today. Instead of testing everything, you use a filter!
Test grep lets you run only tests whose names match a pattern.
How It Works
From Command Line:
# Only run tests with "login" in the name
npx playwright test --grep "login"
# Only run tests with "cart" in the name
npx playwright test --grep "cart"
In Config File:
// playwright.config.js
export default {
grep: /login/, // Only run login tests
};
Grep Invert: Skip Certain Tests
# Run everything EXCEPT slow tests
npx playwright test --grep-invert "slow"
// playwright.config.js
export default {
grepInvert: /slow/, // Skip slow tests
};
Real Example
// Your tests
test('user can login', async () => { });
test('user can logout', async () => { });
test('user can add to cart', async () => { });
test('slow: big file upload', async () => { });
# Running this...
npx playwright test --grep "login"
# ...only runs "user can login"!
🛑 Max Failures Configuration: The Emergency Stop
What Is It?
In a toy factory, if 5 robots break down, you might want to stop everything and fix the problem first. No point running more tests if something is badly broken!
Max failures stops the test run after a certain number of failures.
How It Works
From Command Line:
# Stop after 10 failures
npx playwright test --max-failures=10
In Config File:
// playwright.config.js
export default {
maxFailures: 10,
};
Why Use It?
- Save time: Don’t wait for 500 tests when 10 already failed
- Quick feedback: Find problems faster
- CI pipelines: Fail fast and save resources
Real Example
// playwright.config.js
export default {
// In CI, stop early
maxFailures: process.env.CI ? 5 : 0,
// 0 means no limit
};
🚫 Forbid Only Option: No Favorites Allowed!
What Is It?
Sometimes developers use test.only() to run just one test while developing:
test.only('my special test', async () => {
// Only this test runs
});
But if you forget to remove it, you accidentally skip all other tests!
Forbid only makes the test run fail if any .only() is found.
How It Works
From Command Line:
npx playwright test --forbid-only
In Config File:
// playwright.config.js
export default {
forbidOnly: !!process.env.CI,
// true in CI, false locally
};
Real Example
// Someone forgot to remove this:
test.only('quick debug test', async () => {
// ...
});
// With forbid-only enabled:
// ❌ Error: test.only() is not allowed!
💡 Pro tip: Always enable this in your CI pipeline!
⚙️ test.use for Options: Custom Settings Per Test
What Is It?
Different toys need different testing conditions. A water toy needs to be tested in water. A glow toy needs darkness.
test.use() lets you set custom options for specific tests or files.
How It Works
import { test } from '@playwright/test';
// All tests in this file use Firefox
test.use({ browserName: 'firefox' });
test('works in Firefox', async ({ page }) => {
// Runs in Firefox!
});
Common Options
// Change browser
test.use({ browserName: 'webkit' });
// Change viewport size
test.use({ viewport: { width: 375, height: 667 } });
// Set locale
test.use({ locale: 'fr-FR' });
// Set timezone
test.use({ timezoneId: 'Europe/Paris' });
// Use saved login state
test.use({ storageState: './auth.json' });
Scoped Options
import { test } from '@playwright/test';
test.describe('Mobile tests', () => {
test.use({
viewport: { width: 375, height: 667 },
isMobile: true,
});
test('looks good on phone', async ({ page }) => {
// Test runs on mobile viewport
});
});
test.describe('Desktop tests', () => {
test.use({
viewport: { width: 1920, height: 1080 },
});
test('looks good on desktop', async ({ page }) => {
// Test runs on big screen
});
});
🏷️ testIdAttribute Configuration: Finding Elements Your Way
What Is It?
When you’re looking for a toy in a big warehouse, each toy has a label. By default, Playwright looks for labels called data-testid:
<button data-testid="submit-btn">Submit</button>
But maybe your toys use different labels! Some companies use data-test or data-cy.
How It Works
// playwright.config.js
export default {
use: {
testIdAttribute: 'data-test',
},
};
Now Playwright will look for data-test instead:
// This now looks for data-test="submit"
await page.getByTestId('submit').click();
<!-- Matches this -->
<button data-test="submit">Submit</button>
Common Test ID Attributes
| Framework | Attribute Used |
|---|---|
| Default | data-testid |
| Cypress | data-cy |
| Some teams | data-test |
| Custom | Anything you want! |
Real Example
// playwright.config.js
export default {
use: {
// Our company uses data-qa
testIdAttribute: 'data-qa',
},
};
// test file
await page.getByTestId('login-button').click();
// Finds: <button data-qa="login-button">Login</button>
🐢 slowMo Option: Watching in Slow Motion
What Is It?
Playwright tests run super fast—so fast you can’t see what’s happening! It’s like watching a movie at 100x speed.
slowMo adds a delay between every action, so you can watch and understand what your test does.
How It Works
In Config:
// playwright.config.js
export default {
use: {
// Wait 500ms between actions
launchOptions: {
slowMo: 500,
},
},
};
Just for Debugging:
import { chromium } from '@playwright/test';
const browser = await chromium.launch({
slowMo: 1000, // 1 second between clicks
headless: false, // Watch the browser
});
When to Use It
- Debugging: See exactly what your test does
- Demos: Show your tests to teammates
- Learning: Understand test flow
⚠️ Warning: Don’t use slowMo in CI/production—tests will take forever!
Real Example
// playwright.config.js
export default {
use: {
launchOptions: {
// Only slow down when not in CI
slowMo: process.env.CI ? 0 : 500,
},
},
};
🎯 Putting It All Together
Here’s a complete config file using everything we learned:
// playwright.config.js
import { defineConfig } from '@playwright/test';
export default defineConfig({
// 🌅 Before all tests
globalSetup: './global-setup.js',
// 🌙 After all tests
globalTeardown: './global-teardown.js',
// 🔍 Only run certain tests
grep: process.env.TEST_GREP
? new RegExp(process.env.TEST_GREP)
: undefined,
// 🛑 Stop early on failures
maxFailures: process.env.CI ? 5 : 0,
// 🚫 No test.only in CI
forbidOnly: !!process.env.CI,
use: {
// 🏷️ Our custom test ID
testIdAttribute: 'data-qa',
// 🐢 Slow mode for debugging
launchOptions: {
slowMo: process.env.SLOW ? 500 : 0,
},
},
});
📊 Quick Reference Flow
graph TD A["🌅 Global Setup Runs"] --> B["🔍 Grep Filters Tests"] B --> C["🎯 Tests Run with test.use Options"] C --> D{Test Failed?} D -->|Yes| E["🛑 Check Max Failures"] E -->|Limit Hit| F["Stop Testing"] E -->|Under Limit| C D -->|No| C C -->|All Done| G["🌙 Global Teardown Runs"]
🎉 You Did It!
You now know how to control your Playwright test factory like a pro:
| Control | What It Does |
|---|---|
| Global Setup | Runs once before all tests |
| Global Teardown | Runs once after all tests |
| Grep | Run only matching tests |
| Max Failures | Stop after N failures |
| Forbid Only | Block .only() in CI |
| test.use | Custom options per test |
| testIdAttribute | Custom element locator |
| slowMo | Slow down for debugging |
Now go configure your tests like a boss! 🚀
