Use a controlled sign-in once, save Playwright’s authenticated browser state, and reuse it in tests. Keep that state outside version control because its cookies and headers may be enough to impersonate the account. For passkey (WebAuthn) coverage, use Playwright’s virtual authenticator and seeded credentials instead of trying to automate a physical key. Other factors—TOTP, push, SMS, recovery codes and identity-provider challenges—are application-specific and must be validated with an authorized test account.
How do I handle 2FA in Playwright?
Separate authentication from the test cases. A setup project or worker-scoped fixture signs in through the normal application flow, completes the approved second-factor step, and writes storageState. Tests then create contexts from that state instead of repeating interactive login.
- Create a dedicated test account (or one account per worker when tests mutate shared data).
- Run a setup project that completes login and the permitted MFA flow.
- Save the state to a temporary, ignored directory.
- Configure dependent projects to load that state.
- Delete and regenerate it when the session expires or the account is disabled.
Shared account for read-only or independent tests
One setup account is practical when tests can run concurrently without conflicting server-side changes. The account must have only the permissions required by the suite, and its credentials should come from your secret manager or CI variables.
Separate account per parallel worker
If tests create, edit or delete shared records, use a distinct account and state file for each worker. This prevents one test from revoking a session, changing a profile, or consuming a one-time challenge needed by another worker.
Free tools Windows power users keep installed
One-click scans. No signup required.
#1 Best Overall
- POWERFUL SECURITY KEY: The Security Key C NFC is the essential physical passkey for protecting your digital life from phishing attacks. It ensures only you can access your accounts.
- WORKS WITH 1000+ ACCOUNTS: Compatible with Google, Microsoft, and Apple. A single Security Key C NFC secures 100 of your favorite accounts, including email, password managers, and more.
- FAST & CONVENIENT LOGIN: Plug in your Security Key C NFC via USB-C and tap it, or tap it against your phone (NFC) to authenticate. No batteries, no internet connection, and no extra fees required.
- TRUSTED PASSKEY TECHNOLOGY: Uses the latest passkey standards (FIDO2/WebAuthn & FIDO U2F) but does not support One-Time Passwords. For complex needs, check out the YubiKey 5 Series.
- BUILT TO LAST: Made from tough, waterproof, and crush-resistant materials. Manufactured in Sweden and programmed in the USA with the highest security standards.
Reusable storageState setup
The following JavaScript configuration uses a setup project. Replace selectors and URLs with those in your authorized test environment. The second-factor step is deliberately represented as an application-owned helper: there is no universal, safe automation method for every MFA product.
playwright.config.js
const { defineConfig } = require('@playwright/test');
const path = require('path');
module.exports = defineConfig({
testDir: './tests',
projects: [
{
name: 'setup',
testMatch: /.*\.setup\.js/,
},
{
name: 'chromium',
use: {
browserName: 'chromium',
storageState: path.join(__dirname, 'playwright/.auth/user.json'),
},
dependencies: ['setup'],
},
],
});
tests/auth.setup.js
const { test: setup, expect } = require('@playwright/test');
const fs = require('fs');
const path = require('path');
const authFile = path.join('playwright', '.auth', 'user.json');
setup('authenticate', async ({ page }) => {
await page.goto('https://example.test/login');
await page.getByLabel('Email').fill(process.env.E2E_EMAIL);
await page.getByLabel('Password').fill(process.env.E2E_PASSWORD);
await page.getByRole('button', { name: 'Sign in' }).click();
// Implement only the MFA flow your test tenant explicitly permits.
// For example, a test-only TOTP helper or an approved IdP sandbox step.
await completeAuthorizedMfa(page);
await expect(page).toHaveURL(/dashboard/);
fs.mkdirSync(path.dirname(authFile), { recursive: true });
await page.context().storageState({ path: authFile });
});
async function completeAuthorizedMfa(page) {
// Replace with your application's documented test hook.
// Do not put real recovery codes or production secrets in source control.
await page.getByRole('heading', { name: 'Dashboard' }).waitFor();
}
Store E2E_EMAIL and E2E_PASSWORD in CI secrets, not in the repository. In a real setup helper, assert that the challenge belongs to the test tenant and fail closed when the expected MFA screen is missing. A missing challenge can indicate a policy change or an accidentally weakened account.
Is Playwright storageState safe to commit?
No. Treat the file as a credential. Playwright warns that serialized cookies and headers can be sufficient to impersonate the account. Add the directory to .gitignore, restrict filesystem and CI-artifact access, and avoid uploading it to logs or build artifacts.
Rank #2
- POWERFUL SECURITY KEY: The YubiKey 5C NFC is the most versatile physical passkey, protecting your digital life from phishing attacks. It ensures only you can access your accounts
- WORKS WITH 1000+ ACCOUNTS: Compatible with popular accounts like Google, Microsoft, and Apple. A single YubiKey 5C NFC secures 100+ of your favorite accounts, including email, password managers, and more
- FAST & CONVENIENT LOGIN: Plug in your YubiKey 5C NFC via USB and tap it, or tap it against your phone (NFC), to authenticate. No batteries, no internet connection, and no extra fees required
- MOST SECURE PASSKEY: Supports FIDO2/WebAuthn, FIDO U2F, Yubico OTP, OATH-TOTP/HOTP, Smart card (PIV), and OpenPGP. That means it’s versatile, working almost anywhere you need it
- PRIMARY & SPARE KEYS: Just like having a spare house key, we recommend buying two YubiKeys - one for daily use and one as a spare. That way you’ll never get locked out of your accounts
# .gitignore
playwright/.auth/
Limit lifetime and permissions
- Write run-only state beneath the test output directory when possible; that directory is cleaned before a run.
- Set a refresh policy based on the session’s actual expiry. Delete the file and rerun setup after expiry, logout, password rotation or policy changes.
- Use a low-privilege account with synthetic data. Never use a production administrator session.
- Redact request and response logging that could contain authorization headers or cookies.
- Make CI jobs that can read the state mutually exclusive from untrusted pull-request jobs.
Detect stale state
Have setup verify a page that requires authentication and fail with a clear message when redirected to login. A test that silently proceeds unauthenticated can produce misleading authorization failures. Regenerate state rather than trying to patch cookies by hand.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Can Playwright automate passkey authentication?
Yes, for WebAuthn ceremonies, Playwright provides a virtual authenticator on BrowserContext. You can seed known credentials and let the context answer create/get operations without a physical key. The Credentials API is documented as added in Playwright v1.61, so pin and verify the version used by your runner before adopting it.
Virtual-authenticator example
const { test, expect } = require('@playwright/test');
test('passkey sign-in', async ({ browser }) => {
const context = await browser.newContext();
const authenticator = await context.newCDPSession(
await context.newPage()
);
// Use the BrowserContext virtual-authenticator API available in your
// installed Playwright version to create an authenticator and seed the
// credential required by your test tenant.
// Keep the credential data private; it includes a private key.
const page = await context.newPage();
await page.goto('https://example.test/passkey-login');
await page.getByRole('button', { name: 'Use a passkey' }).click();
await expect(page).toHaveURL(/dashboard/);
await context.close();
});
Use the exact virtual-authenticator methods documented by the Playwright version installed in your project; method names and options should be checked against that pinned API. Persisted virtual credential data carries private keys. Keep it isolated to WebAuthn tests, and remember that restoring a state containing virtual credentials installs that authenticator in the context and prevents real authenticators from working there.
Rank #3
- POWERFUL SECURITY KEY: The YubiKey 5 NFC is the most versatile physical passkey, protecting your digital life from phishing attacks. It ensures only you can access your accounts
- WORKS WITH 1000+ ACCOUNTS: Compatible with popular accounts like Google, Microsoft, and Apple. A single YubiKey 5 NFC secures 100+ of your favorite accounts, including email, password managers, and more
- FAST & CONVENIENT LOGIN: Plug in your YubiKey 5 NFC via USB and tap it, or tap it against your phone (NFC), to authenticate. No batteries, no internet connection, and no extra fees required
- MOST SECURE PASSKEY: Supports FIDO2/WebAuthn, FIDO U2F, Yubico OTP, OATH-TOTP/HOTP, Smart card (PIV), and OpenPGP. That means it’s versatile, working almost anywhere you need it
- PRIMARY & SPARE KEYS: Just like having a spare house key, we recommend buying two YubiKeys - one for daily use and one as a spare. That way you’ll never get locked out of your accounts
Virtual versus physical FIDO2 keys
| Need | Best fit | Reason |
|---|---|---|
| Automated WebAuthn ceremony coverage | Playwright virtual authenticator | Runs in CI without attached hardware and can use seeded credentials. |
| Human administrator enrollment | Real FIDO2 security key | Provides the hardware-backed interaction a person must verify. |
| Manual hardware or recovery check | Real FIDO2 security key | Exercises browser, OS and device behavior that a virtual authenticator does not model. |
A physical key is not required for Playwright’s documented virtual WebAuthn path. TOTP, push approval, SMS, recovery codes and provider-specific challenges are not covered by that API; implement only an authorized test-tenant mechanism and document its boundaries.
Worker isolation and fixtures
For mutating suites, create state per worker. A worker-scoped fixture can choose credentials from a CI-provided list, authenticate once, and expose a context to that worker’s tests. Ensure the account-to-worker mapping is deterministic, and clean up records created by the worker. Never let two workers share a one-time recovery code or a mutable profile.
Recommended Free Tools
When a shared state is acceptable
- Tests are read-only or operate on independent resources.
- The application does not revoke or rotate the session during a test.
- Parallel requests cannot change permissions, billing, MFA enrollment or other shared settings.
When to isolate
- Tests alter server-side records visible to other tests.
- A test enrolls, removes or resets an MFA factor.
- Logout, password changes or risk checks invalidate other sessions.
- The identity provider enforces one active challenge or device binding.
Troubleshooting common failures
Every test is redirected to login
The state file may be missing, expired or written before the final redirect. Check the configured path, wait for a post-login URL or authenticated API response, and regenerate the file. Confirm the dependent project lists the setup project.
Rank #4
- POWERFUL SECURITY KEY: The Security Key NFC is the essential physical passkey for protecting your digital life from phishing attacks. It ensures only you can access your accounts.
- WORKS WITH 1000+ ACCOUNTS: Compatible with Google, Microsoft, and Apple. A single Security Key NFC secures 100 of your favorite accounts, including email, password managers, and more.
- FAST & CONVENIENT LOGIN: Plug in your Security Key NFC via USB-A and tap it, or tap it against your phone (NFC) to authenticate. No batteries, no internet connection, and no extra fees required.
- TRUSTED PASSKEY TECHNOLOGY: Uses the latest passkey standards (FIDO2/WebAuthn & FIDO U2F) but does not support One-Time Passwords. For complex needs, check out the YubiKey 5 Series.
- BUILT TO LAST: Made from tough, waterproof, and crush-resistant materials. Manufactured in Sweden and programmed in the USA with the highest security standards.
WebAuthn reports “no credential”
The virtual authenticator was not created in the current context, the credential’s relying-party ID does not match the test origin, or the credential was seeded in a different context. Create and seed it before navigation and keep origin, RP ID and tenant configuration aligned.
Real security keys stop working
A restored state containing virtual credentials installs the virtual authenticator. Use a fresh context without that state for manual hardware checks.
Parallel tests change each other’s results
Move from one shared account to one account and state file per worker. Reset test data between runs and avoid mutating account-level MFA settings in parallel.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsBest Value
- The information below is per-pack only
- POWERFUL SECURITY KEY: The Security Key C NFC is the essential physical passkey for protecting your digital life from phishing attacks. It ensures only you can access your accounts.
- WORKS WITH 1000+ ACCOUNTS: Compatible with Google, Microsoft, and Apple. A single Security Key C NFC secures 100 of your favorite accounts, including email, password managers, and more.
- FAST & CONVENIENT LOGIN: Plug in your Security Key C NFC via USB-C and tap it, or tap it against your phone (NFC) to authenticate. No batteries, no internet connection, and no extra fees required.
- TRUSTED PASSKEY TECHNOLOGY: Uses the latest passkey standards (FIDO2/WebAuthn & FIDO U2F) but does not support One-Time Passwords. For complex needs, check out the YubiKey 5 Series.
CI exposes credentials
Remove auth files from artifacts and logs, rotate the affected account immediately, review repository history, and tighten job permissions. A private repository is not a sufficient reason to commit impersonation-capable state.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Performance, reliability and cost controls
- Authenticate once per setup or worker rather than once per test; this reduces MFA prompts and identity-provider load.
- Prefer a stable setup URL and explicit readiness assertion over arbitrary sleeps.
- Use retries only for transient navigation failures; do not retry a failed MFA assertion blindly, because a challenge may be one-time.
- Keep browser, Playwright and test-tenant versions pinned together, especially when relying on the v1.61 Credentials API.
- Record whether failure occurred at password entry, second factor, session persistence or authorization. Each layer has a different fix.
Or skip the browser setup
If your goal is a clean image or PDF of an authenticated or public page rather than an interactive MFA test, ScreenshotNeo makes a single HTTP request. Its API accepts cookies, custom headers and Authorization when you need an authorized capture, while its cleanup steps remove cookie-consent banners, newsletter popups and chat widgets before the shot. Bot checks, blank pages, timeouts, failed loads and cache hits are not billed, and the response identifies the page verdict and billing status in headers.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
See the complete parameter list and authentication details in the ScreenshotNeo documentation. ScreenshotNeo also provides an MCP server with take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients. The free plan includes 1,000 shots a month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
Frequently Asked Questions
Should authentication setup run in every test file?
No. Put it in a setup project or worker-scoped fixture and make dependent tests consume the resulting state.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Does a virtual authenticator test prove that a real key works?
No. It covers WebAuthn ceremony logic; manual hardware, browser and operating-system behavior still require a real FIDO2 key.
What should happen when an auth-state file expires during CI?
Fail the authenticated check, delete the stale file, and rerun the authorized setup flow rather than editing cookies or headers.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

