Авто-ожидания: почему не нужны sleep
Главное преимущество Playwright: он сам ждёт нужного момента, а ручные паузы — антипаттерн.
Авто-ожидание — встроенный механизм: перед каждым действием Playwright проверяет ряд условий готовности элемента и ждёт, пока они выполнятся, прежде чем выполнить действие.
Почему веб асинхронен
Современные сайты подгружают данные на лету: вы кликнули — пошёл запрос — через 300 мс появился результат. Если тест попытается кликнуть по кнопке, которой ещё нет на странице, он упадёт. Старый подход боролся с этим грубо — вставляли паузы.
// АНТИПАТТЕРН: фиксированная пауза
await page.waitForTimeout(3000); // ждём «на всякий случай» 3 секунды
await page.getByRole('button', { name: 'Готово' }).click();Это плохо по двум причинам. Если сеть быстрая — вы зря потеряли 3 секунды на каждом шаге, а в большом наборе такие потери складываются в минуты. Если медленная — 3 секунд не хватит, и тест всё равно упадёт. Фиксированные паузы делают тесты одновременно медленными и ненадёжными.
Как работают авто-ожидания
Playwright решает проблему иначе. Перед действием он автоматически ждёт, пока элемент пройдёт проверки готовности (actionability):
- элемент прикреплён к DOM;
- видим (не
display:none, не нулевого размера); - стабилен — не анимируется, не двигается;
- включён — не
disabled; - не перекрыт другим элементом (например, всплывающим окном).
Поэтому код без всяких пауз просто работает:
// Playwright сам дождётся, пока кнопка появится и станет кликабельной
await page.getByRole('button', { name: 'Готово' }).click();Если кнопка появится через 300 мс — клик произойдёт через 300 мс. Если через 2 секунды — через 2 секунды. Тест подстраивается под реальность, а не под угаданное число. Это и есть причина, по которой Playwright-тесты в среднем стабильнее: они не «угадывают» тайминги, а наблюдают за состоянием страницы.
Сравнение подходов
| Подход | Быстрая сеть | Медленная сеть |
waitForTimeout(3000) | теряем 3 с впустую | может не хватить — падение |
| авто-ожидание | ждём ровно сколько нужно | ждём до таймаута, успеваем |
Когда ожидание нужно явно
Иногда нужно дождаться не элемента, а события — навигации или сетевого ответа. Для этого есть явные ожидания вроде waitForURL или waitForResponse (разберём в отдельном уроке). А вот waitForTimeout в рабочих тестах — почти всегда признак проблемы. Если очень хочется его поставить, спросите себя: «чего именно я жду?» — и дождитесь именно этого условия.
// правильно: ждём конкретное событие, а не «время вообще»
await page.getByRole('button', { name: 'Сохранить' }).click();
await page.waitForURL('**/success');Итог
- Веб асинхронен: элементы появляются не сразу.
- Фиксированные паузы (
waitForTimeout) — антипаттерн: медленно и ненадёжно. - Playwright перед действием сам ждёт готовности элемента (видим, стабилен, включён, не перекрыт).
- Если нужно явное ожидание — ждите события (URL, ответ), а не абстрактное время.