Back to blog overview

December 14, 2022

How to Playwright

Eddie Gomez

&

Software Engineer
San Diego, CA

Playwright is an end-to-end testing framework that has been gaining popularity. We choose playwright for the ease of use and familiar Javascript syntax.

### Why Playwright over [Cypress](https://docs.cypress.io/guides/overview/why-cypress)?

- Typescript support out of the box.
- Can run on multiple browsers including WebKit (safari).
- Choice of test runner.
- Test readability; less method chaining.
- Multiple page support.

### Installing [Playwright](https://playwright.dev/docs/intro)

Getting started with Playwright couldn't be simpler.

By running the following command with either `npm` or `yarn`

```bash
yarn init playwright@latest
```

The install command will result in a few prompts
For example, choosing between TypeScript or Javascript.
Naming the Test folder.
As well as adding GitHub Actions workflows for running tests.

### Playwright setup with [Redwoodjs](https://redwoodjs.com/)

So, it’s pretty easy to get playwright installed. We have been using Playwright on our most recent RedwoodJS app; our goto full stack Javascript Framework.

Since [Redwoodjs](https://www.notion.so/27e5e697cdde48eba11f6e7a283b7c50) is broken up within a Web directory for the frontend and API directory for the backend. We have added a script in the root `package.json` to run the end-to-end tests.

By doing so, we have to give the script context using the `-c` flag and pass the location of our playwright config.

Thereafter, we can pass any other playwright params.                                            

For example:

```json
"test:e2e": "npx playwright test -c web/playwright.config.ts --trace on --workers 1 --reporter=list"
//or npx playwright test

```

`--trace on`  - A snapshot recording of the test running in the browsers; for debugging purposes.

`--worker 1`  - Disable parallelization (to run test individually and avoid test pollution on the backend/db side)

`--reporter=list` - Command line report output style.

We have also tweaked the `webServer` options in `playwright.config.ts` to launch a local production build of the [Redwoodjs](https://www.notion.so/27e5e697cdde48eba11f6e7a283b7c50) app to test against.

Since, redwood uses `yarn rw serve`  to run both front/back end sides.

```jsx
webServer: {
   reuseExistingServer: true,
   command: 'yarn rw serve',
   port: 8910,
 },
```

### We are all set, Let’s write a test!

Playwright has a pretty useful command to help with writing tests; figuring out which selector methods to use.

Let’s see it in action!

Now let us run the dev server for instance, `yarn rw dev` ([redwoodjs](https://redwoodjs.com/docs/cli-commands)) then, in a new terminal tab run the following command.

```jsx
npx playwright codegen
```

A chromium browser should pop open as well as the playwright inspector window.

Now let’s see if we can test a successful login on the app.
We can just follow the motions by navigating to our app, and login with a user.
Playwright Inspector will be listening for changes and provide the appropriate selectors for us to use.

We can use the Playwright Inspector as a jumping off point for writing our test. Writing tests should look a bit familiar; similar to writing unit test using [react-testing-library](https://testing-library.com/docs/react-testing-library/intro/).

For example

```tsx
import { test, expect } from '@playwright/test'

test.describe('login as a user', () => {

 test('should login user', async ({ page }) => {

await page.goto('<http://localhost:8910/>')

await page.getByRole('link', { name: 'Login' }).click()

await expect(page).toHaveURL('/login')

const userNameInput = page.getByLabel('Username')
await userNameInput.click()
await userNameInput.fill('admin@example.com')

const passwordInput = page.getByLabel('Password')
await passwordInput.click()
await passwordInput.fill('password')

await page.getByRole('button', { name: 'Login' }).click()
await expect(page).toHaveURL('<http://localhost:8910/>')
 })
})

```

We import `test` from playwright/test.

`describe` method is used to define a group of tests.

Thereafter, we use the`test` (similar to `it` ; like in Jest) function with a title and callback function.

For instance,

```jsx
test("title goes here", () => {
thing we want to test; goes in here.
})
```

With typescript support out of the box and `codegen` tool; it is pretty easy to find the appropriate selectors, to grab an input fields or buttons from the DOM.

Now let’s run the test via our script!

```jsx
yarn test:e2e

```

### Boom!

The test pass in all three web browsers Chrome, Firefox, Safari
Easy as that!

### Resources

Want to checkout the repo?

- [Redwood Template App](https://github.com/CodingZeal/redwood-template-app)

Learn RedwoodJS?

- [Learn with Redwood](https://www.learnwithredwood.com/)

Let's Chat

Are you ready to build something brilliant? We're ready to help.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Learn Redwood

Are you ready to future-proof your career? Stay in the loop of our Learn with Redwood Masterclass.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.