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/)
Are you ready to build something brilliant? We're ready to help.