Playwright, didn't know I missed it
Introduction
For a recent project I was introduced to Playwright. It promises reliable end-to-end testing for web applications. After initially being skeptical (due to experiences with other test automation tools), I was soon amazed by the ease of use and stability.
In a nutshell
The installation worked flawlessly and the interactive running mode (playwright test --ui
) provides immediate insight into how a test runs. The interactive
generation of code for tests (playwright codegen
) also works very well without generating bloat.
A little caveat
At first, I didn't realize that:
- actions are async (and must therefore be
await
ed) - locators are not async
- locators are lazy
- expectations are async or sync
This implies that the following assertions can both be true if you are testing a dynamic page:1
await page.goto('/')
const sections = page.locator('section')
await expect(sections).toHaveCount(1)
await expect(sections).toHaveCount(0)
The above test will pass if there is initially a single section on the page, and it is later removed by the tested application. I was surprised!
Using Arrange-Act-Assert (AAA)
Works nicely because the locators are lazy. You can set them up while the elements do not exist. Also note the inexact match for the message.
import { test, expect } from '@playwright/test'
test('sign in unhappy path', async ({ page }) => {
// arrange
const email = page.getByLabel('Email')
const password = page.getByLabel('Password', { exact: true })
const button = page.getByRole('button', { name: 'Sign in' })
const message = page.getByText('Sign in failed. Check your')
// act
await page.goto('/')
await email.fill('hacker@example.org')
await password.fill('123')
await button.click()
// assert
await expect(message).toBeVisible()
})
You can see the laziness of the locators here; before the goto the inputs and buttons do not exist, but the tests succeed.
Conclusion
All in all, Playwright is a pleasant discovery for me!
Notes
-
I used TypeScript here, but Playwright supports multiple languages. ↩