DEV Community

Cover image for Getting started with Playwright E2E testing
Giannis Koutsaftakis
Giannis Koutsaftakis

Posted on

Getting started with Playwright E2E testing

Playwright is a cross-browser web automation framework by Microsoft. It is also a powerful E2E testing tool with its integrated test runner Playwright Test.

Some of the highlight features of Playwright:

  • Support for 3 browser engines (Chromium, Firefox and WebKit)
  • Write tests in JavaScript & TypeScript, Python, .NET and, Java
  • Runs tests in parallel using worker processes that run at the same time
  • Support for screenshots and videos snapshots taking
  • Provides a great set of debugging tools
  • Wide range of element selectors (CSS, text, X-path and more)
  • Intercept network activity for stubbing and mocking network requests (e.g API calls)
  • CLI tool to Record user interactions and generate JavaScript code

more...

In this post we' re going to implement two simple E2E test flows for pages that require authentication and look at how we can reuse the login state so that we don't have to repeat the same code across our tests.

We're going to use JavaScript as our language of choice and the beautiful Vuexy admin theme as an example domain for testing.

Let's start!

Install dependencies

Playwright and friends

# install playwright and its test runner
npm i -D @playwright/test

# install browser engines - Chromium, Firefox, and Webkit
npx playwright install

Enter fullscreen mode Exit fullscreen mode

We're also going to need the dotenv package in order to load the login credentials as environment variables from a .env file into our test.

npm i -D dotenv
Enter fullscreen mode Exit fullscreen mode

Let's add some useful commands into the scripts section of our project's package.json

...
"scripts": {
    "test": "npx playwright test",
    "test-debug": "PWDEBUG=1 npx playwright test",
    "test-debug-windows": "set PWDEBUG=1 && npx playwright test"
},
...
Enter fullscreen mode Exit fullscreen mode
  • test runs the tests
  • test-debug runs the tests in debug mode
  • test-debug-windows runs the tests in debug mode on Windows

Configure

Playwright uses a global configuration file to specify common settings for each test.
Create playwright.config.js in your project's root with the contents below

module.exports = {
  globalSetup: require.resolve('./tests/global-setup.js'),
  use: {
    baseURL: 'https://pixinvent.com',
    headless: true,
    viewport: { width: 1280, height: 720 },
    ignoreHTTPSErrors: true,
    screenshot: 'only-on-failure',
    timeout: 30000,
  }
};
Enter fullscreen mode Exit fullscreen mode

These are some commonly used options for various scenarios.

  • baseURL Define a common Base URL, this allows us to navigate by using just the path inside our tests. In our example we set it as https://pixinvent.com
  • globalSetup This file will be required and run before all the tests. We'll use it to setup our login step before every test.
  • headless Playwright runs tests in headless mode by default, change this to false if you want to view the tests in a "live" browser instance.
  • viewport Controls the size of the viewport for the tests.
  • ignoreHTTPSErrors Whether to ignore HTTPS errors during navigation.
  • screenshot Have a screenshot taken when a test fails.
  • timeout Time in milliseconds given to each test.

Create a .env file in the project's root that will hold our login credentials.

LOGIN_USERNAME=admin@demo.com
LOGIN_PASSWORD=admin
Enter fullscreen mode Exit fullscreen mode

We'll also need to insert the .env and tests/state.json files to our project's .gitignore file. The tests/state.json will be used to store the authentication state when our tests run, so we don't want that file to be tracked by Git.

.gitignore

# env file
.env

# Login state file
tests/state.json
Enter fullscreen mode Exit fullscreen mode

Create the tests

The tests directory will contain our tests and the globalSetup file.

tests/globalSetup.js

const config = require('../playwright.config');
const { chromium } = require('@playwright/test');
require('dotenv').config();

module.exports = async () => {
  const browser = await chromium.launch();
  const page = await browser.newPage();

  await page.goto(config.use.baseURL + '/demo/vuexy-vuejs-laravel-admin-template/demo-1/login');

  await page.fill('input[type="text"]', process.env.LOGIN_USERNAME);
  await page.fill('input[type="password"]', process.env.LOGIN_PASSWORD);
  await page.click('button:has-text("Sign in")');

  await page.context().storageState({ path: 'tests/state.json' });
  await browser.close();  
};
Enter fullscreen mode Exit fullscreen mode

Playwright uses the globalSetup.js file to set things up once, before running all tests. In our example we're using it to visit the login page, fill-in the username and password, click on the "Sign in" button and finally, save the authentication state to a state.json file that is going to be used from inside our tests.

Let's add some sample tests

Playwright Test uses the expect library for test assertions, if you have used Jest you will find the syntax familiar.

tests/dashboard.spec.js

const { test, expect } = require('@playwright/test');

test.use({ storageState: 'tests/state.json' });

test('dashboard', async ({ page }) => {
  await page.goto('/demo/vuexy-vuejs-laravel-admin-template/demo-1/dashboard/ecommerce');
  const title = await page.locator('.card.card-congratulation-medal p.card-text.font-small-3');
  await expect(title).toContainText('You have won gold medal');
});
Enter fullscreen mode Exit fullscreen mode

In this test we' re visiting the Dashboard page and we're checking if the medal card contains the text "You have won gold medal".
Playwright provides many ways to select elements, in our case we're using CSS selectors to find the card element in the page.

tests/analytics.spec.js

const { test, expect } = require('@playwright/test');

test.use({ storageState: 'tests/state.json' });

test('analytics', async ({ page }) => {
  await page.goto('https://pixinvent.com/demo/vuexy-vuejs-laravel-admin-template/demo-1/dashboard/analytics');
  await page.click('text=Add Record');

  const title = await page.locator('h4.invoice-title');
  await expect(title).toContainText('Invoice');
});
Enter fullscreen mode Exit fullscreen mode

In our second test we visit the Analytics, click on the "Add Record" button and the check if the text "Invoice" appears inside a h4 element on the next page.
Notice that we don't have to write any specific method call for navigation, Playwright auto-waits for the next page.

Run the tests

In order to tun our tests we can use the commands we added in our package.json

npm run test
Enter fullscreen mode Exit fullscreen mode

Alt Text

We can also run the tests in debug mode. This will open up the browsers in headed mode and also start the Playwright Inspector. Useful when we want to troubleshoot our tests scripts.

# For Linux and MacOS
npm run test-debug

# For Windows
npm run test-debug-windows
Enter fullscreen mode Exit fullscreen mode

Useful commands

Here's a list of commands that can be useful when writing and running/debugging our test scripts

# Run a single test
npx playwright test testName

# Run in headed mode
npx playwright test --headed

# Run tests using a specified browser
npx playwright test --browser=firefox

# Run tests using all three browsers
npx playwright test --browser=all
Enter fullscreen mode Exit fullscreen mode

That's all
Thanks for reading and have fun testing with Playwright!

Discussion (2)

Collapse
alexandlazaris profile image
Alexander Lazaris

Nice read! Have you had any exp running the tests against the 3 browser types (Chrome, ff, safari) on Mac?

Collapse
kouts profile image
Giannis Koutsaftakis Author

Yeap, tried it both on Mac and PC.