All guidesMore providers: databases, auth, hosting, email and payments
On this page

Playwright and Vercel

VercelPlaywright

How do I run Playwright tests against a Vercel preview that has Deployment Protection?

By Ohad Krispin, founder of VibeRaven · LinkedIn

Give Playwright the Protection Bypass for Automation secret from Vercel. Deployment Protection puts a Vercel login in front of preview URLs, while Standard Protection leaves production domains open, so a test that passes on production can fail on a preview: a browser test lands on the login redirect, and Vercel's own guide says CI jobs get 401. Create the secret in the project's Deployment Protection settings, store it as a GitHub Actions secret, and send it as the x-vercel-protection-bypass header through use.extraHTTPHeaders in playwright.config.ts. Add x-vercel-set-bypass-cookie: true so browser navigation keeps the bypass. Redeploy after you change the secret.

What does the Playwright config look like?

This is the Playwright example from Vercel's Protection Bypass for Automation page, with baseURL added from an environment variable. The check at the top stops the run early with a clear message when the secret is missing. Vercel says to use samesitenone instead of true for x-vercel-set-bypass-cookie when you test inside an iframe.

import { defineConfig } from '@playwright/test';

if (!process.env.VERCEL_AUTOMATION_BYPASS_SECRET) {
  throw new Error(
    'VERCEL_AUTOMATION_BYPASS_SECRET is required to run tests against protected deployments',
  );
}

export default defineConfig({
  use: {
    baseURL: process.env.BASE_URL,
    extraHTTPHeaders: {
      'x-vercel-protection-bypass': process.env.VERCEL_AUTOMATION_BYPASS_SECRET,
      'x-vercel-set-bypass-cookie': 'true',
    },
  },
});

How does the GitHub Actions job get the secret and the preview URL?

Vercel lists VERCEL_AUTOMATION_BYPASS_SECRET as a system environment variable available at build and runtime of a deployment. Nothing in the Vercel docs says it reaches a GitHub Actions job, so copy the value into a repository secret (Settings, Secrets and variables, Actions, New repository secret) and pass it to the test step with env. Vercel's guide on end-to-end tests after a preview deployment runs the workflow on a repository_dispatch event of type vercel.deployment.success and reads the preview URL from github.event.client_payload.url. On a pull request from a fork, GitHub does not pass secrets to the runner, so the config above throws on its first line; see empty secret on forks.

- name: Run Playwright tests
  run: npx playwright test
  env:
    BASE_URL: ${{ github.event.client_payload.url }}
    VERCEL_AUTOMATION_BYPASS_SECRET: ${{ secrets.VERCEL_AUTOMATION_BYPASS_SECRET }}

Is it a problem that the header goes out with every request?

Playwright documents extraHTTPHeaders as headers sent with every request, so the secret is attached to every request the test sends, including requests the page makes to other hosts. Run these tests only against your own preview, and revoke the secret if a log or a trace shows it. Vercel says a secret bypasses protection on all deployments of the project until it is revoked, and that you can create several secrets, one per tool, such as one named for the Playwright tests.

Checklist

How to fix it, then check the fix

  1. 01Open the preview URL in a private window. A Vercel login redirect means Deployment Protection covers that URL; the settings are under the project's Settings, Deployment Protection.
  2. 02In the same settings page, create a secret under Protection Bypass for Automation. Vercel says team members with at least the member role, or project administrators, can do this, and that the feature is on all plans.
  3. 03Add the value to GitHub as a repository secret named VERCEL_AUTOMATION_BYPASS_SECRET, and pass it to the Playwright step with env, as in the workflow above.
  4. 04Put the extraHTTPHeaders block in playwright.config.ts and set BASE_URL to the preview URL, so page.goto('/') resolves against it.
  5. 05
    Check the header before you debug Playwright. The Vercel guide says a 200 confirms the bypass works, so the route you request must answer 200 itself:
    curl -s -o /dev/null -w "%{http_code}\n" -H "x-vercel-protection-bypass: $VERCEL_AUTOMATION_BYPASS_SECRET" https://<your-preview-url>/
  6. 06If you regenerate or delete the secret, redeploy. Vercel says that invalidates previous deployments and that you need to redeploy to get the new value. Then run the tests again.

Related

Sources

Official docs behind this checklist

FAQ

FAQ for builders before launch

Why do my tests pass against production but fail on the preview?

Vercel's Standard Protection protects all deployments except production domains, so a preview URL asks for a Vercel login while the production domain does not. If you chose All Deployments, production is protected too.

Can I use a query parameter instead of a header?

Vercel accepts a query parameter named x-vercel-protection-bypass with the same value, for tools that cannot set custom headers, such as webhook URL checks. It recommends the header, which is what extraHTTPHeaders sends.

Do I need a paid plan to use the bypass?

Vercel's page says Protection Bypass for Automation is available on all plans.