A test fails in CI. You open the Playwright HTML report and see 60 lines of code in one giant block. It says "line 47 timed out." You have no idea what the test was actually trying to do. You are left staring at a stack trace guessing which part of the flow broke.
The damage isn't just time. It's clarity. When test results are a pain to decipher, developers stop reading them. Failures get dismissed.
test.step() fixes this.
BEFORE: One giant block. The report just says "X test failed."
test('submit contact form', async ({ page }) => {
await page.goto('/contact');
await page.getByLabel('Name').fill('Jane');
await page.getByLabel('Email').fill('jane@test.com');
await page.getByRole('button', { name: 'Submit' }).click();
await expect(page.getByText('Thank you')).toBeVisible();
});
AFTER: Named steps. The report reads like a story.
test('submit contact form', async ({ page }) => {
await test.step('GIVEN user is on contact page', async () => {
await page.goto('/contact');
});
await test.step('WHEN user fills and submits form', async () => {
await page.getByLabel('Name').fill('Jane');
await page.getByLabel('Email').fill('jane@test.com');
await page.getByRole('button', { name: 'Submit' }).click();
});
await test.step('THEN success message appears', async () => {
await expect(page.getByText('Thank you')).toBeVisible();
});
});
The rule: Wrap your code in named steps using GIVEN, WHEN, and THEN.
Now your report says "WHEN user fills and submits form failed" instead of "line 47 timed out".
You know exactly what broke instantly. Debugging goes from minutes to seconds.
Do you use test.step() to structure your tests, or is your code one giant block? Drop it in the comments.
Top comments (0)