Answer
test.step() in Playwright
test.step() is a way to group related actions under a named step, which improves:
- āTest report readability
- āTrace viewer navigation
- āError messages that pinpoint where exactly the test failed
Basic Usage
TypeScript
import { test, expect } from '@playwright/test';
test('complete checkout flow', async ({ page }) => {
await test.step('Navigate to product page', async () => {
await page.goto('/products/laptop');
await expect(page.getByRole('heading', { name: 'Laptop Pro' })).toBeVisible();
});
await test.step('Add product to cart', async () => {
await page.getByRole('button', { name: 'Add to Cart' }).click();
await expect(page.locator('.cart-count')).toHaveText('1');
});
await test.step('Proceed to checkout', async () => {
await page.getByRole('link', { name: 'View Cart' }).click();
await page.getByRole('button', { name: 'Checkout' }).click();
await expect(page).toHaveURL('/checkout');
});
await test.step('Fill shipping details', async () => {
await page.getByLabel('Full Name').fill('John Doe');
await page.getByLabel('Address').fill('123 Main St');
await page.getByLabel('City').fill('New York');
await page.getByLabel('Zip Code').fill('10001');
});
await test.step('Complete payment', async () => {
await page.getByRole('button', { name: 'Place Order' }).click();
await expect(page).toHaveURL('/order-confirmed');
await expect(page.getByRole('heading')).toContainText('Order Confirmed');
});
});
Steps in Reports
When this test runs, the HTML report and Trace Viewer show:
CODE
ā complete checkout flow (4.2s)
ā Navigate to product page (0.8s)
ā Add product to cart (0.5s)
ā Proceed to checkout (0.9s)
ā Fill shipping details (1.2s)
ā Complete payment (0.8s) ā Failure shows exactly here
test.step() Returns a Value
TypeScript
const orderId = await test.step('Place order and get ID', async () => {
await page.getByRole('button', { name: 'Place Order' }).click();
const confirmText = await page.locator('.order-id').textContent();
return confirmText; // Return values work!
});
console.log('Order ID:', orderId);
Steps in Page Objects
TypeScript
// pages/CheckoutPage.ts
import { test } from '@playwright/test';
export class CheckoutPage {
async fillShippingDetails(name: string, address: string) {
return test.step('Fill shipping details', async () => {
await this.nameInput.fill(name);
await this.addressInput.fill(address);
});
}
}
Benefits
- āTrace Viewer shows step boundaries ā click to see the exact DOM state at each step
- āHTML report shows step-level timing and failure location
- āError messages include step names ā "Step: Add product to cart" failed
- āMakes long tests self-documenting
