page.getByText('Success').isVisible() возвращает булево значение проверяя DOM ровно один раз: если элемент ещё не отрендерился, получаешь false даже если он появится через 200 мс. expect(page.getByText('Success')).toBeVisible() повторяет попытки до 5 секунд перед тем как упасть. Это поведение с повторными попытками и есть основа дизайна ассёртов в Playwright, а большинство ошибок у начинающих происходит из незнания у каких методов оно есть. Гайд охватывает все типы ассёртов, отрицание через not, мягкие ассёрты для сбора всех сбоев, и паттерны которые молча отключают авто-повтор.

Как работают ассёрты в Playwright

Ассёрты Playwright используют функцию expect() из @playwright/test. Это не то же самое что expect в Jest. Версия Playwright асинхронная и имеет встроенную логику повторных попыток.

import { test, expect } from '@playwright/test';

Ключевое отличие от большинства тест-фреймворков: ассёрты Playwright автоматически повторяют проверку. Когда пишешь:

await expect(page.getByText('Welcome')).toBeVisible();

Playwright не проверяет один раз. Он проверяет многократно до 5 секунд (дефолтный expect timeout), ожидая пока условие не станет истинным. Это устраняет необходимость ручных вызовов waitFor в 90% случаев.

Если условие не становится истинным в рамках таймаута, тест падает с понятным сообщением: что ожидалось и что реально существовало.

Ассёрты элементов (на основе локаторов)

Проверяют свойства конкретного элемента на странице.

toBeVisible / toBeHidden

// Элемент отрендерен и виден пользователю
await expect(page.getByText('Dashboard')).toBeVisible();

// Элемент отсутствует или присутствует но скрыт (display:none, visibility:hidden, opacity:0)
await expect(page.getByRole('dialog')).toBeHidden();

toBeHidden() истинен если элемент не существует ИЛИ существует но невидим. Используй not.toBeAttached() если нужно конкретно подтвердить что элемента нет в DOM вообще.

toHaveText / toContainText

// Точное совпадение текста (пробелы обрезаются автоматически)
await expect(page.getByRole('heading', { level: 1 })).toHaveText('My Travel Items');

// Частичное совпадение
await expect(page.getByRole('heading')).toContainText('Travel');

// Массив: проверяем текст нескольких элементов
await expect(page.getByRole('listitem')).toHaveText(['Tokyo', 'Paris', 'London']);

// Regex: совпадение по паттерну
await expect(page.getByTestId('price')).toHaveText(/\$\d+\.\d{2}/);

toHaveText с массивом проверяет полный текст каждого элемента по порядку. Очень полезно для проверки строк таблиц или отсортированных списков.

toHaveValue

Для элементов ,