DEV Community

Cover image for My First Playwright Tests
Corina: Web for Everyone
Corina: Web for Everyone

Posted on • Edited on

My First Playwright Tests

A blog series about playing and writing in 🎭


I'm a developer learning about web accessibility, and I would like to add Playwright to my toolset for testing web accessibility compliance.

So far, I've found that it offers straightforward syntax and excellent automation capabilities. Plus, the best documentation in the universe. (Yes, I believe aliens would use Playwright for some of their testing needs!)

This post is about the first three tests I wrote and how I applied them to my portfolio site.


Getting Started with 🎭

First, to get started (i.e., installation, how to run tests, etc.), I highly recommend Debbie O’Brien’s series of articles published on dev.to. I've included the link below in the Resources section.

Once installed, Playwright comes with example tests to help you get started. I adapted some of these examples to create three tests specifically for my portfolio site:

✔️ To navigate to the home page of my portfolio site and check if the title matches an expected string.
✔️ To check for the visibility of the home page’s heading.
✔️ To check whether the “My Projects” link is functional.

Note: My site is still in construction, so expect to find errors beyond those tested here.

Here are all three of the tests:

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

test('has title', async ({ page }) => {
    await page.goto('https://corinamurg.netlify.app/');

    await expect(page).toHaveTitle(/Corina's Portfolio/);
});


test('has heading', async ({ page }) => {
    await page.goto('https://mywebsite.com/');

    await expect(page.getByRole('heading', {name: 'HELLO, I’m CORINA!'})).toBeVisible();
});


test('My Projects link', async ({ page }) => {
    await page.goto('https://corinamurg.netlify.app/');

    await page.getByRole('link', {name: 'My Projects'}).click();
});

Enter fullscreen mode Exit fullscreen mode

Understanding the Code for Test 1

Let's break the code down into smaller steps and analyze them!

Step 1: We have to import two functions from Playwright: test and expect:

import { test, expect } from '@playwright/test';
Enter fullscreen mode Exit fullscreen mode
  • the test function is used to define an individual test.
  • expect is an assertion function that checks whether a certain condition is met.

Heads up: the term assertion frequently appears in Playwright. An assertion is a check within a test that verifies whether certain conditions are met. So it basically evaluates a specific condition and passes or fails the test based on the result.

Step 2: Define a test named has title

test('has title', async ({ page }) => {
Enter fullscreen mode Exit fullscreen mode

Step 3: Navigate to my website

 await page.goto('https://corinamurg.netlify.app/');
Enter fullscreen mode Exit fullscreen mode

Step 4: Add an assertion to check if the webpage's title contains the text "Corina's Portfolio"

await expect(page).toHaveTitle(/Corina's Portfolio/);
Enter fullscreen mode Exit fullscreen mode

A few important notes

  • the test function requires a string as its first argument to name the test, and a function as its second argument. This function is where you write the actual test code. It’s an asynchronous function that receives a page object.
  • a test interacts with web pages through this page object, which is an instance of the Page class. The Page class provides a wide range of methods that allows us to simulate any possible user interactions and scenario. For example, use .goto() to navigate to URLs, page.click() or page.fill() to interact with elements, page.locator() to query the DOM. I highly recommend checking out the documentation on the Page class and its methods.
  • await is necessary because Playwright operates asynchronously. It performs actions in a browser environment that requires waiting for the actions to complete before moving to the next step.

Now let’s look briefly at the other two tests as well.

Test 2

// Define a test named 'has heading' 
test('has heading', async ({ page }) => {
    await page.goto('https://corinamurg.netlify.app/')
    // Expect page to have a heading with name of 'HELLO, I’m CORINA!'
    await expect(page.getByRole('heading', { name: 'HELLO, I’m CORINA!' })).toBeVisible();
});

Enter fullscreen mode Exit fullscreen mode

Test 3

// Define a test named 'My Projects link'
test('My Projects link', async ({ page }) => {
    await page.goto('https://corinamurg.netlify.app/')

    // simulate a user clicking on the 'My Projects' link
    await page.getByRole('link', { name: 'My Projects' }).click();
});

Enter fullscreen mode Exit fullscreen mode

Playing with Errors

As an experiment, I modified the has title test with a different expected title, which, as anticipated, led to a failed test due to the mismatch.

Here is the (quite long) error log:

Error: Timed out 5000ms waiting for expect(locator).toHaveTitle(expected) 
Locator: locator(':root') 
Expected pattern: /My site/ 
Received string: "Corina's Portfolio" 
Call log: - expect.toHaveTitle with timeout 5000ms 
- waiting for locator(':root') 
- locator resolved to <html lang="en"></html> 
- unexpected value "Corina's Portfolio" 
- locator resolved to <html lang="en"></html> 
- unexpected value "Corina's Portfolio" 
- locator resolved to <html lang="en"></html> 
- unexpected value "Corina's Portfolio" 
- locator resolved to <html lang="en"></html> 
- unexpected value "Corina's Portfolio" 
- locator resolved to <html lang="en"></html> 
- unexpected value "Corina's Portfolio" 
- locator resolved to <html lang="en"></html> 
- unexpected value "Corina's Portfolio
- locator resolved to <html lang="en">…</html> 
- unexpected value "Corina's Portfolio" 
- locator resolved to <html lang="en">…</html> 
- unexpected value "Corina's Portfolio"
Enter fullscreen mode Exit fullscreen mode

The expect function was waiting for the page title to match "My site", but instead found "Corina's Portfolio". This mismatch between expected and actual results caused the test to fail.

The repeated lines like -unexpected value 'Corina's Portfolio' and -locator resolved to <html lang='en'>…</html> show that Playwright was continually checking the page title within the specified timeout period (5000ms). Each line likely represents an attempt to recheck the title against the expected value. Of course, it consistently found a value that did not match the expected pattern.

Conclusion 😊

I'm thrilled that my first three tests were successful! To create these tests I adapted the example tests that Playwright adds at installation. In the next post I will talk about another test that I created with just a click of a button! Seriously!

Resources

Debbie O’Brien’s Playwright Series on dev.to

Playwright Documentation

Image credit: Photo by Alex Kondratiev

Description: The image shows a hand pouring a blue liquid from a glass test tube into a flask with red liquid, and another hand pouring a green liquid into the flask. The background is plain white.

Top comments (0)