Testing with Playwright

Watch the whole thing, no account needed. If it clicks, grab The Imposter's Frontend Accelerator for lifetime access to every lesson.
I'm a big fan of testing things - especially end-to-end (e2e). Let's see how Playwright can help us automate our login and video checks.
The focus will be: great, but how do I actually use this thing?
Off Camera
Setup a test user with Supabase and a new login page (I have to) as we have no way to authenticate our user otherwise.
Setting Up Playwright
We'll do the needful and see how Playwright works:
- Install Playwright, showing both ways (VS Code Extension and CLI)
- Look through the config, tweaking to make it a bit more usable
- Have a gander at the examples
- Understand how Locaters work and what makes UI testing so brittle
Authentication Issues
Our tests need to know who the user is, so we'll plug in authentication and discuss how this would work in automated tests (it won't and shouldn't)
Running Tests
Lots of ways to run tests:
- VS Code Extension (don't like)
- The CLI (it's OK)
- The UI tool (it's great)
Rob's Opinion
I have lots of opinions on tests and testing, and I'm happy to share
Snippets
I have a number of snippets I like to use because I like to write tests by hand. Hope you find them useful!
<span class="hljs-attr">"Playwright"</span><span class="hljs-punctuation">:</span><span class="hljs-punctuation">{</span>
<span class="hljs-attr">"prefix"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"pw"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"body"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
<span class="hljs-string">"const { test, expect } = require('@playwright/test');\r\n"</span><span class="hljs-punctuation">,</span>
<span class="hljs-string">"test.describe(\"$1\", () => {"</span><span class="hljs-punctuation">,</span>
<span class="hljs-string">"\ttest.beforeEach(async ({page}) => {"</span><span class="hljs-punctuation">,</span>
<span class="hljs-string">"\t\tawait page.goto('')"</span><span class="hljs-punctuation">,</span>
<span class="hljs-string">"\t});"</span><span class="hljs-punctuation">,</span>
<span class="hljs-string">"\ttest(\"$2\", async ({page}) => {"</span><span class="hljs-punctuation">,</span>
<span class="hljs-string">"\t\t$0"</span><span class="hljs-punctuation">,</span>
<span class="hljs-string">"\t});"</span><span class="hljs-punctuation">,</span>
<span class="hljs-string">"});"</span>
<span class="hljs-punctuation">]</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"Playwright describe"</span> <span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">"prefix"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"pwd"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"body"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
<span class="hljs-string">"test.describe(\"$1\", () => {"</span><span class="hljs-punctuation">,</span>
<span class="hljs-string">" $0"</span><span class="hljs-punctuation">,</span>
<span class="hljs-string">"});"</span>
<span class="hljs-punctuation">]</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"Playwright label"</span> <span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">"prefix"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"pwlbl"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"body"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
<span class="hljs-string">"const $0 = await page.getByLabel(\"$1\");"</span>
<span class="hljs-punctuation">]</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"Playwright id"</span> <span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">"prefix"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"pwid"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"body"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
<span class="hljs-string">"const $0 = await page.locator(\"#$1\");"</span>
<span class="hljs-punctuation">]</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"Playwright test id"</span> <span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">"prefix"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"pwtid"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"body"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
<span class="hljs-string">"const $0 = await page.getByTestId(\"$1\");"</span>
<span class="hljs-punctuation">]</span>
<span class="hljs-punctuation">}</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"Playwright role"</span> <span class="hljs-punctuation">:</span> <span class="hljs-punctuation">{</span>
<span class="hljs-attr">"prefix"</span><span class="hljs-punctuation">:</span> <span class="hljs-string">"pwrole"</span><span class="hljs-punctuation">,</span>
<span class="hljs-attr">"body"</span><span class="hljs-punctuation">:</span> <span class="hljs-punctuation">[</span>
<span class="hljs-string">"const $0 = await page.getByRole('$1', { name: '$2' });"</span>
<span class="hljs-punctuation">]</span>
<span class="hljs-punctuation">}</span>