General

Integrating Playwright Tests into Your GitHub Workflow with Vercel

Jamie Kuppens
7 min read
Jamie - Integrating Playwright Tests into Your GitHub Workflow with Vercel

Vercel previews offer a great way to test PRs for a project. They have a predefined environment and don’t require any additional setup work from the reviewer to test changes quickly. Many projects also use end-to-end tests with Playwright as part of the review process to ensure that no regressions slip uncaught.

Usually, workflows configure Playwright to run against a project running on the GitHub action worker itself, maybe with dependencies in Docker containers as well, however, why bother setting that all up and configuring yet another environment for your app to run in when there’s a working preview right there? Not only that, the Vercel preview will be more similar to production as it’s running on the same infrastructure, allowing you to be more confident about the accuracy of your tests.

In this article, I’ll show you how you can run Playwright against the Vercel preview associated with a PR.

Setting up the Vercel Project

To set up a project in Vercel, we first need to have a codebase. I’m going to use the Next.js starter, but you can use whatever you like. What technology stack you use for this project won’t matter, as integrating Playwright with it will be the same experience.

You can create a Next.js project with the following command:

npx create-next-app@latest

If you’ve selected all of the defaults, you should be able to run npm run dev and navigate to the app at http://localhost:3000.

Setting up Playwright

We will set up Playwright the standard way and make a few small changes to the configuration and the example test so that they run against our site and not the Playwright site. Setup Playwright in our existing project by running the following command:

npm init playwright@latest

Install all browsers when prompted, and for the workflow question, say no since the one we’re going to use will work differently than the default one. The default workflow doesn’t set up a development server by default, and if that is enabled, it will run on the GitHub action virtual machine instead of against our Vercel deployment.

To make Playwright run tests against the Vercel deployment, we’ll need to define a baseUrl in playwright.config.ts and send an additional header called X-Vercel-Protection-Bypass where we'll pass the bypass secret that we generated earlier so that we don’t get blocked from making requests to the deployment. I’ll cover how to add this environment variable to GitHub later.

export default defineConfig({
	...

  use: {
	/* Base URL to use in actions like `await page.goto('/')`. */
	baseURL: process.env.DEPLOYMENT_URL ?? "http://127.0.0.1:3000",
	extraHTTPHeaders: {
  	"X-Vercel-Protection-Bypass":
    	process.env.VERCEL_AUTOMATION_BYPASS_SECRET ?? "",
	},

	/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
	trace: "on-first-retry",
  },

	...
}

Our GitHub workflow will set the DEPLOYMENT_URL environment variable automatically.

Now, in tests/example.spec.ts let’s rewrite the tests to work against the Next.js starter that we generated earlier:

import { test, expect } from "@playwright/test";

test("has title", async ({ page }) => {
  await page.goto("/");
  await expect(page).toHaveTitle(/Create Next App/);
});

test("has deploy button", async ({ page }) => {
  await page.goto("/");
  await expect(page.getByRole("link", { name: "Deploy now" })).toBeVisible();
});

This is similar to the default test provided by Playwright. The main difference is we’re loading pages relative to baseURL instead of Playwright’s website. With that done and your Next.js dev server running, you should be able to run npx playwright test and see 6 passing tests against your local server. Now that the boilerplate is handled let’s get to the interesting part.

The Workflow

There is a lot going on in the workflow that we’ll be using, so we’ll go through it step by step, starting from the top. At the top of the file, we name the workflow and specify when it will run.

name: E2E Tests (Playwright)

on:
  pull_request:
	branches:
  	- main
  push:
	branches:
  	- main

This workflow will run against new PRs against the default branch and whenever new commits are merged against it. If you only want the workflow to run against PRs, you can remove the push object.

Be careful about running workflows against your main branch if the deployment associated with it in Vercel is the production deployment. Some tests might not be safe to run against production such as destructive tests or those that modify customer data. In our simple example, however, this isn’t something to worry about.

Installing Playwright in the Virtual Machine

Workflows have jobs associated with them, and each job has multiple steps. Our test job takes a few steps to set up our project and install Playwright.

jobs:
  test:
	runs-on: ubuntu-latest
	steps:
  	- uses: actions/checkout@v4

  	- uses: actions/setup-node@v4
    	with:
      	node-version: 22
      	cache: 'npm'

  	- name: Install npm dependencies
    	run: npm ci

  	- name: Install system dependencies needed by Playwright
    	run: sudo npx playwright install-deps

  	- name: Install all supported Playwright browsers
    	run: npx playwright install

The actions/checkout@v4 step clones our code since it isn’t available straight out of the gate. After that, we install Node v22 with actions/setup-node@v4, which, at the time of writing this article, is the latest LTS available. The latest LTS version of Node should always work with Playwright. With the project cloned and Node installed, we can install dependencies now. We run npm ci to install packages using the versions specified in the lock file.

After our JS dependencies are installed, we have to install dependencies for Playwright now. sudo npx playwright install-deps installs all system dependencies that Playwright needs to work using apt, which is the package manager used by Ubuntu. This command needs to be run as the administrative user since higher privilege is needed to install system packages. Playwright’s dependencies aren’t all available in npm because the browser engines are native code that has native library dependencies that aren’t in the registry.

Vercel Preview URL and GitHub Action Await Vercel

The next couple of steps is where the magic happens. We need two things to happen to run our tests against the deployment. First, we need the URL of the deployment we want to test. Second, we want to wait until the deployment is ready to go before we run our tests. We have written about this topic before on our blog if you want more information about this step, but we’ll reiterate some of that here.

Thankfully, the community has created GitHub actions that allow us to do this called zentered/vercel-preview-url and UnlyEd/github-action-await-vercel. Here is how you can use these actions:

jobs:
  test:
	runs-on: ubuntu-latest
	steps:
    	...

  	- name: Get the Vercel preview url
    	id: vercel_preview_url
    	uses: zentered/vercel-preview-url@v1.4.0
    	env:
      	VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
    	with:
      	vercel_app: 'playwright-vercel-preview-demo'

  	- uses: UnlyEd/github-action-await-vercel@v2.0.0
    	env:
      	VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
    	with:
      	deployment-url: ${{ format('https://{0}', steps.vercel_preview_url.outputs.preview_url) }}
      	timeout: 420
      	poll-interval: 15

There are a few things to take note of here. Firstly, some variables need to be set that will differ from project to project. vercel_app in the zentered/vercel-preview-url step needs to be set to the name of your project in Vercel that was created earlier.

The other variable that you need is the VERCEL_TOKEN environment variable. You can get this by going to Vercel > Account Settings > Tokens and creating a token in the form that appears. For the scope, select the account that has your project.

To put VERCEL_TOKEN into GitHub, navigate to your repo, go to Settings > Secrets and variables > Actions and add it to Repository secrets.

We should also add VERCEL_AUTOMATION_BYPASS_SECRETl. In Vercel, go to your project then navigate to Settings > Deployment Protection > Protection Bypass for Automation. From here you can add the secret, copy it to your clipboard, and put it in your GitHub action environment variables just like we did with VERCEL_TOKEN.

With the variables taken care of, let’s take a look at how these two steps work together. You will notice that the zentered/vercel-preview-url step has an ID set to vercel_preview_url. We need this so we can pass the URL we receive to the UnlyEd/github-action-await-vercel action, as it needs a URL to know which deployment to wait on.

Running Playwright

After the last steps we just added, our deployment should be ready to go, and we can run our tests! The following steps will run the Playwright tests against the deployment and save the results to GitHub:

jobs:
  test:
	runs-on: ubuntu-latest
	steps:
    	...

  	- name: Run E2E tests
    	run:
      	npx playwright test
    	env:
      	DEPLOYMENT_URL: ${{ format('https://{0}', steps.vercel_preview_url.outputs.preview_url) }}
      	VERCEL_AUTOMATION_BYPASS_SECRET: ${{ secrets.VERCEL_AUTOMATION_BYPASS_SECRET }}

  	- name: Upload the Playwright report
    	uses: actions/upload-artifact@v4
    	if: always() # Always run regardless if the tests pass or fail
    	with:
      	name: playwright-report
      	path: ${{ format('{0}/playwright-report/', github.workspace) }}
      	retention-days: 30

In the first step, where we run the tests, we pass in the environment variables needed by our Playwright configuration that’s stored in playwright.config.ts. DEPLOYMENT_URL uses the Vercel deployment URL we got in an earlier step, and VERCEL_AUTOMATION_BYPASS_SECRET gets passed the secret with the same name directly from the GitHub secret store.

The second step uploads a report of how the tests did to GitHub, regardless of whether they’ve passed or failed. If you need to access these reports, you can find them in the GitHub action log. There will be a link in the last step that will allow you to download a zip file.

Once this workflow is in the default branch, it should start working for all new PRs! It’s important to note that this won’t work for forked PRs unless they are explicitly approved, as that’s a potential security hazard that can lead to secrets being leaked. You can read more about this in the GitHub documentation.

One Caveat

There’s one caveat that is worth mentioning with this approach, which is latency. Since your application is being served by Vercel and not locally on the GitHub action instance itself, there will be longer round-trips to it. This could result in your tests taking longer to execute. How much latency there is can vary based on what region your runner ends up being hosted in and whether the pages you’re loading are served from the edge or not.

Conclusion

Running your Playwright tests against Vercel preview deployments provides a robust way of running your tests against new code in an environment that more closely aligns with production. Doing this also eliminates the need to create and maintain a 2nd test environment under which your project needs to work.

About the author

Jamie Kuppens

Jamie Kuppens

Senior Software Engineer

I’m a software engineer with an interest in web development and some more esoteric things like emulator development.

Keep reading

View all posts →

Vercel BotID: The Invisible Bot Protection You Needed

Discover what BotID is, why it matters, and how to integrate it with your app....

Jesús Padrón5 mins
VercelNextJS

The simplicity of deploying an MCP server on Vercel

This post explores how to deploy a lightweight, stateless Model Context Protocol (MCP) server using Vercel’s infrastructure. ...

Coston Perkins3 mins
VercelMCP

Introduction to Vercel’s Flags SDK

You'll also understand why you might prefer this tool over other feature flag solutions out there....

Jesús Padrón5 mins
Vercel

“We were seen as amplifiers, not collaborators,” Ashley Willis, Sr. Director of Developer Relations at GitHub, on How DevRel has Changed, Open Source, and Holding Space as a Leader

Ashley Willis has seen Developer Relations evolve from being on the sidelines of the tech team to having a seat at the strategy table. In her ten years in the space, she’s done more than give great conference talks or build community—she’s helped shape what the DevRel role looks like for software providers. Now as the Senior Director of Developer Relations at GitHub, Ashley is focused on building spaces where developers feel heard, seen, and supported. “A decade ago, we were seen as amplifiers, not collaborators,” she says. “Now we’re influencing product roadmaps and shaping developer experience end to end.” DevRel Has Changed For Ashley, the biggest shift hasn’t been the work itself—but how it’s understood. “The work is still outward facing, but it’s backed by real strategic weight,” she explains. “We’re showing up in research calls and incident reviews, not just keynotes.” That shift matters, but it’s not the finish line. Ashley is still pushing for change when it comes to burnout, representation, and sustainable metrics that go beyond conference ROI. “We’re no longer fighting to be taken seriously. That’s a win. But there’s more work to do.” Talking Less as a Leader When we asked what the best advice Ashley ever received, she shared an early lesson she received from a mentor: “Your presence should create safety, not pressure.” “It reframed how I saw my role,” she says. “Not as the one with answers, but the one who holds the space.” Ashley knows what it’s like to be in rooms where it’s hard to speak up. She leads with that memory in mind, and by listening more than talking, normalizing breaks, and creating environments where others can lead too. “Leadership is emotional labor. It’s not about being in control. It’s about making it safe for others to lead, too.” Scaling More Than Just Tech Having worked inside high growth companies, Ashley knows firsthand: scaling tech is one thing. Scaling trust is another. “Tech will break. Roadmaps will shift. But if there’s trust between product and engineering, between company and community—you can adapt.” And she’s learned not to fall for premature optimization. Scale what you have. Don’t over design for problems you don’t have yet. Free Open Source Isn’t Free There’s one myth Ashley is eager to debunk: that open source is “free.” “Open source isn’t free labor. It’s labor that’s freely given,” she says. “And it includes more than just code. There’s documentation, moderation, mentoring, emotional care. None of it is effortless.” Open source runs on human energy. And when we treat contributors like an infinite resource, we risk burning them out, and breaking the ecosystem we all rely on. “We talk a lot about open source as the foundation of innovation. But we rarely talk about sustaining the people who maintain that foundation.” Burnout is Not Admirable Early in her career, Ashley wore burnout like a badge of honor. She doesn’t anymore. “Burnout doesn’t prove commitment,” she says. “It just dulls your spark.” Now, she treats rest as productive. And she’s learned that clarity is kindness—especially when giving feedback. “I thought being liked was the same as being kind. It’s not. Kindness is honesty with empathy.” The Most Underrated GitHub Feature? Ashley’s pick: personal instructions in GitHub Copilot. Most users don’t realize they can shape how Copilot writes, like its tone, assumptions, and context awareness. Her own instructions are specific: empathetic, plainspoken, technical without being condescending. For Ashley, that helps reduce cognitive load and makes the tool feel more human. “Most people skip over this setting. But it’s one of the best ways to make Copilot more useful—and more humane.” Connect with Ashley Willis She has been building better systems for over a decade. Whether it’s shaping Copilot UX, creating safer teams, or speaking truth about the labor behind open source, she’s doing the quiet work that drives sustainable change. Follow Ashley on BlueSky to learn more about her work, her maker projects, and the small things that keep her grounded in a fast moving industry. Sticker Illustration by Jacob Ashley....

3 mins
Engineering LeadershipGitHub