Made in Builder.io

Upcoming webinar with Figma: Design to Code in 80% Less Time

Announcing Visual Copilot - Figma to production in half the time

Builder.io logo
Talk to Us
Platform
Developers
Talk to Us

Blog

Home

Resources

Blog

Forum

Github

Login

Signup

×

Visual CMS

Drag-and-drop visual editor and headless CMS for any tech stack

Theme Studio for Shopify

Build and optimize your Shopify-hosted storefront, no coding required

Resources

Blog

Get StartedLogin

‹ Back to blog

testing

End-to-End Testing With Playwright And Github Actions

December 1, 2022

Written By Adam Bradley

Not only are there many different ways to write software, but there are also many more ways to break it. Now I’m not sure about anyone else, but I know I’ve personally broken production web apps a few times. “Ahhh, I’ll just update this one simple line here, easy-peasy. All unit tests passed so obviously absolutely nothing could possibly go wrong…push to main…time for the weekend!” (we already know how this story ends).

I’m a huge advocate of unit tests and they certainly have their place throughout development. But rather than unit testing one specific function to return a specific value, we’re instead testing the output as a cohesive working webpage by interacting with the page the same users would with their browsers. This includes all JavaScript, CSS, HTML, and events, and how all of this works together to render and handle the expected result.

End-to-end testing is where I’ve found Playwright to be invaluable for many of our projects like Partytown, Qwik, and Mitosis, and its ability to test again and again on each commit. This post is a somewhat beginner's guide and will focus primarily on “why” Playwright, and how to set it up for continuous integration with GitHub Actions.

What is a Headless Browser?

The most common web browsers today include Chrome, Safari, Firefox, and Edge. In fact, it’s a safe bet to say you’re reading this blog right now using a web browser. But what you’re looking at is the browser’s user interface and how it was able to render the given URL.

A headless browser has the same capabilities, except the “headless” part means that it can run without a graphical user interface. The interesting part, however, is that the browser is still rendering the webpage and its HTML elements, and styles, and adding event listeners. But through the magic of an API, you can programmatically read and interact with the headless browser just like a user would interact with a traditional browser.

When choosing a headless browser, a common question that comes up is whether to use Microsoft’s Playwright, or Google’s Puppeteer, and of course, no software question is better answered than with “well, it depends”.

On the surface, the two are quite similar. Both are Node.js libraries for browser automation making it easy to control an actual browser with an API, and both have an extremely similar API, (and both were developed by largely the same core developers).

Between the two of them, Puppeteer was first when it was released in 2017. It shook up the traditional headless browser landscape by providing an API to interact directly with Google Chrome.

Puppeteer is a library that provides a high-level API to control Chrome over the DevTools Protocol. 

Playwright was released next in 2020, except with a slightly different core mission in that it's not aiming to just be a high-level protocol to control Chrome, but rather focusing on “end-to-end” testing across many browsers, not just Chrome.

Playwright enables reliable end-to-end testing for modern web apps.

Having worked a lot with Puppeteer in the past, and manually wiring it up to Jest, this differentiation of having Playwright solely focused on providing end-to-end testing out-of-the-box is what makes it so great to use…for end-to-end testing.

Don’t get me wrong, Puppeteer is a great project; if your use case is to take screenshots or crawl pages, then it’s a good tool. However, if your mission is to develop automated end-to-end testing, and have your specs continually tested on each commit with Continuous Integration (CI), then Playwright is one of the best tools out there.

Instead of repeating the same thing here, it’s best to follow the official installation instructions and how to write your first tests. With this post, I’d like to focus more on configuring the GitHub Actions CI.

But before we move on I’d like to point out some great tools that will help you along the way. Please be sure to check out these too:

Assuming you’re successfully running Playwright locally, and a test or two have been created, let’s get your tests running on every commit to Github.

First, you’ll need a workflow file created if you don’t already have one. A workflow allows us to automate one or more jobs on certain triggers. Let's create an end-to-end.yml file inside of your repo’s .github/workflows directory.

In our example, we want our workflow to trigger whenever there’s a push or a pull_request to the main branch.

name: End-to-end Tests
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

Next, we want to add a job for testing. Note that if you already have a workflow you could add this job to the existing YAML configuration file. In the example below, we’re adding the test job, which:

  1. Will run on an ubuntu machine
  2. Checkout your code from your repository
  3. Setup Nodejs, version 18
  4. NPM install the dependencies of your project
  5. Install the Playwright browsers (like Chrome, Firefox, etc)
  6. Execute the tests
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 18
      - name: Install dependencies
        run: npm ci
      - name: Install Playwright Browsers
        run: npx playwright install --with-deps
      - name: Run Playwright tests
        run: npx playwright test

Next, once this workflow file is committed to your GitHub repository, then every push and pull request to main will kick off the tests.

What’s great about Github Actions worker integration is that a passing test, or failed one, also shows in your GitHub interface. For example, for every commit to Partytown we’ve been able to see if the code committed passed or failed.

In our Partytown repo, we’re actually using two different jobs within the workflow. One is set up to run on a Mac with Safari, and the other is running on Ubuntu to test Chromium.

Playwright certainly met our use cases for each of our projects, but it’s not the only great testing tool in town, and in fact, I encourage you to also do a good review of Cypress and choose what works best for your team. Happy e2e testing!

Introducing Visual Copilot: convert Figma designs to code using your existing components in a single click.

Try Visual Copilot

Share

Twitter
LinkedIn
Facebook
Hand written text that says "A drag and drop headless CMS?"

Introducing Visual Copilot:

A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot
Newsletter

Like our content?

Join Our Newsletter

Continue Reading
AI9 MIN
How to Build AI Products That Don’t Flop
WRITTEN BYSteve Sewell
April 18, 2024
Web Development13 MIN
Convert Figma to Code with AI
WRITTEN BYVishwas Gopinath
April 18, 2024
Web Development8 MIN
Server-only Code in Next.js App Router
WRITTEN BYVishwas Gopinath
April 3, 2024