All challenges · Expert & Verification
Challenge 28 of 29 · Expert authoring · Verification
Debug the Broken Test (Full Authoring)
You get a broken test with several bugs. Find and fix them, then write the assertions yourself: this is one of two challenges where you author the checks.
Skills you will practise
- debugging
- full test authoring
- writing assertions
The concept
Most real automation work is not writing new tests; it is fixing ones that fail, flake or pass for the wrong reason. Debugging is a skill, and it follows a pattern: read the error, reproduce the failure, find the first wrong assumption, fix it, then make sure the test can actually fail.
Common culprits in broken Playwright tests are a missing await, a selector tied to markup that changed, a strict-mode violation, a fixed sleep that is too short in CI, a listener registered too late, and assertions that do not retry. Tools help: the HTML report, trace viewer, --debug mode, page.pause() and video of the run.
In this challenge you also write the assertions. A test without good assertions is not a test; it is a script that clicks things.
The fragile version
test('adds to basket', async ({ page }) => {
page.goto('/shop');
await page.locator('div > button:nth-child(3)').click();
await page.waitForTimeout(1000);
expect(await page.locator('.count').textContent()).toBe('1');
});Why it breaks: A missing await on goto, a positional selector, a fixed sleep and a non-retrying read: four bugs that may pass locally and fail in CI.
A robust Playwright version
test('adds to basket', async ({ page }) => {
await page.goto('/shop');
await page.getByRole('listitem')
.filter({ hasText: 'Mechanical keyboard' })
.getByRole('button', { name: 'Add to basket' })
.click();
await expect(page.getByRole('status', { name: 'Basket' })).toHaveText('1');
});Every step is awaited, the locator describes the product and button, and the assertion retries.
This is a general example on a made-up page, not the challenge’s reference solution.
Common mistakes
- Fixing the symptom (raising a timeout) instead of the cause.
- Not checking the test fails when it should, for example by breaking the expected value temporarily.
- Fixing one bug and stopping; broken tests rarely have just one.
FAQ
How do I debug a Playwright test?
Run with --debug or --ui, add page.pause(), and open the trace viewer for failed runs.
Why does my test pass locally but fail in CI?
Usually timing: fixed sleeps, missing awaits or non-retrying checks. CI machines are slower.
What makes a good assertion?
It checks the user-visible outcome, retries (web-first), and would fail if the feature broke.
Try it
Practise this in Challenge 28. You write the code in the browser editor with no setup. It runs in a fresh Chromium, a hidden validator checks what actually happened, and you get pass or fail, the logs and a video of the run. Create a free account to open the practice page and its hints. The reference solution and the hidden validator are shown only after you pass. We never publish solutions here.