Skip to contentPlayForge

What is expect.soft in Playwright?

Written by Jatin Thacker, Automation Architect · Updated

A soft assertion records a failure and lets the test carry on, instead of stopping at the first failed check. The test is still marked as failed at the end, and every soft failure appears in the report.

This answer is one piece of Chapter 11: Assertions.

  • Web-First Assertions Cookbook
  • Retry & Polling Patterns
  • Visual Regression Testing
  • Making a Failure Explain Itself

By default, a failed assertion ends the test straight away. That is usually what you want: once a step has gone wrong, later steps tend to fail for the same reason. Sometimes, though, you are checking several independent things on one screen, such as the badge, the total and a message, and you want to see every mismatch from a single run. expect.soft() does that. It works with any assertion, including web-first ones, and only inside the Playwright test runner.

In the example, the test adds the grinder to the cart, then soft-asserts that the cart badge reads 2. That is wrong on purpose, because one item was added. The soft check fails after its 2-second timeout, but the test does not stop. The next assertion, on the cart total, still runs and passes. test.info().errors.length then shows one error collected so far.

The output shows the test failing with the soft error, and the console.log line proving the code after it ran. Use soft assertions for groups of independent checks. Use ordinary ones where a later step depends on an earlier one.

soft.spec.js(https://practice.learnplayforge.com)
import { test, expect } from '@playwright/test'; test('a soft failure does not stop the test', async ({ page }) => { await page.goto('/catalog.html?mock=static&seed=42&autologin=1'); await page.locator('article[data-sku="MRD-1003"]') .getByRole('button', { name: 'Add to cart' }).click(); // Wrong on purpose: one item was added, not two await expect.soft(page.getByTestId('cart-count')).toHaveText('2', { timeout: 2000 }); // These lines still run await expect(page.getByTestId('cart-total')).toHaveText('₹11,900'); console.log('still running; errors so far:', test.info().errors.length); });
Output
still running; errors so far: 1

    Error: expect(locator).toHaveText(expected) failed

    Locator:  getByTestId('cart-count')
    Expected: "2"
    Received: "1"
    Timeout:  2000ms

  1 failed
Test yourself
A test has three expect.soft checks. The first one fails and the other two pass. What is the result?

AI can write the test now. The job is knowing whether it checks anything. That's what the course teaches, one chapter at a time.

163 lessons · 226 drills · start free

← All questions

Training a team? Talk to us.