В тестировании веб-приложений с использованием Playwright одной из ключевых задач является корректная синхронизация с асинхронными процессами, такими как загрузка новых страниц, редиректы или динамическая подгрузка контента. В этих случаях важно правильно ожидать наступление событий навигации, чтобы тесты выполнялись стабильно и не приводили к ошибкам из-за незавершенных процессов.
waitForNavigation() и
waitForLoadState()Playwright предоставляет несколько методов для ожидания событий, связанных с навигацией. Каждый из них имеет свои особенности и применяется в зависимости от ситуации.
waitForNavigation()Этот метод используется для того, чтобы дождаться завершения перехода
на другую страницу, например, после того как пользователь кликнул по
ссылке или отправил форму. waitForNavigation() можно
использовать в связке с действиями, которые вызывают навигацию.
Пример:
const [newPage] = await Promise.all([
page.waitForNavigation({ waitUntil: 'load' }),
page.click('button#submit')
]);
В этом примере:
waitForNavigation() ожидает завершения загрузки
страницы.page.click() имитируется клик
по кнопке, которая инициирует навигацию.Promise.all() используется для одновременного
выполнения этих двух операций, чтобы гарантировать, что навигация
завершится до того, как выполнится следующий шаг теста.Метод waitForNavigation() имеет несколько опций, среди
которых можно выделить:
waitUntil: Указывает момент времени, на который следует ждать. Допустимые значения:
'load' — ожидание полной загрузки страницы (включая
загрузку всех ресурсов, таких как изображения и стили).'domcontentloaded' — ожидание, когда DOM будет
загружен, но другие ресурсы могут быть еще в процессе загрузки.'networkidle' — ожидание, пока не завершится загрузка
всех сетевых запросов (например, когда запросы не отправляются в течение
определенного времени).Пример с опцией waitUntil:
await page.waitForNavigation({ waitUntil: 'domcontentloaded' });
Этот вариант ожидания позволяет ускорить тесты, если достаточно дождаться загрузки DOM, а не всей страницы.
waitForLoadState()Метод waitForLoadState() применяется, когда нужно
подождать, пока страница перейдет в определенное состояние. В отличие от
waitForNavigation(), который используется для ожидания
перехода между страницами, waitForLoadState() позволяет
отслеживать состояние загрузки одной страницы.
Пример:
await page.waitForLoadState('load');
Этот метод позволяет установить ожидание на один из следующих состояний страницы:
Метод waitForLoadState() может быть полезен, если нужно
дождаться завершения асинхронных процессов на одной странице, а не
перехода на другую.
Пример использования:
await page.waitForLoadState('networkidle');
В этом случае тест будет ждать, пока не завершатся все сетевые запросы, что особенно полезно при работе с динамическими веб-приложениями.
При работе с Playwright часто возникает необходимость отслеживания редиректов, которые могут происходить автоматически после отправки формы или выполнения HTTP-запросов. В таких случаях важно правильно настроить обработку редиректов.
Для отслеживания редиректов в Playwright используется метод
waitForNavigation() совместно с параметром
waitUntil: 'load' или
waitUntil: 'networkidle'.
Пример:
await page.goto('https://example.com/login');
await page.fill('input[name="username"]', 'user');
await page.fill('input[name="password"]', 'password');
await Promise.all([
page.waitForNavigation({ waitUntil: 'load' }),
page.click('button[type="submit"]')
]);
В этом примере клик по кнопке “Submit” вызывает редирект на другую
страницу после успешной авторизации. Использование
waitForNavigation() гарантирует, что тест не продолжится до
тех пор, пока новая страница не будет загружена.
Playwright позволяет писать асинхронные тесты с использованием
async/await. Это важно, так как навигация и связанные с ней
процессы загрузки страниц происходят асинхронно.
В случае с асинхронными тестами стоит всегда использовать
await при вызове методов ожидания, чтобы обеспечить
синхронность выполнения теста.
Пример асинхронного теста:
it('should navigate to the next page after form submission', async () => {
await page.goto('https://example.com');
await page.fill('input[name="username"]', 'user');
await page.fill('input[name="password"]', 'password');
await Promise.all([
page.waitForNavigation({ waitUntil: 'load' }),
page.click('button[type="submit"]')
]);
// Дальнейшие шаги теста
});
Во время выполнения тестов на реальных веб-страницах могут возникать непредсказуемые задержки, связанные с загрузкой страниц, запросами к серверу и другими факторами. Поэтому Playwright позволяет настроить таймауты для методов ожидания.
Метод waitForNavigation() принимает параметр
timeout, который определяет максимальное время ожидания
события навигации.
Пример:
await page.waitForNavigation({ timeout: 10000, waitUntil: 'load' });
Этот пример задает таймаут в 10 секунд для завершения навигации. Если в течение этого времени событие не произойдет, тест завершится с ошибкой.
При работе с сложными сценариями, когда на одной странице происходит несколько переходов (например, редиректы или динамическая загрузка данных), необходимо учитывать каждый из этапов навигации.
Пример:
await page.goto('https://example.com');
await page.fill('input[name="search"]', 'Playwright');
await Promise.all([
page.waitForNavigation({ waitUntil: 'load' }),
page.click('button#search')
]);
await Promise.all([
page.waitForNavigation({ waitUntil: 'domcontentloaded' }),
page.click('a#next-page')
]);
В этом примере тест сначала выполняет поиск, затем переходит на страницу с результатами и снова ожидает навигацию при переходе на следующую страницу.
Ожидание событий навигации в Playwright является важным аспектом
тестирования веб-приложений. Правильное использование методов, таких как
waitForNavigation() и waitForLoadState(),
помогает эффективно синхронизировать действия теста с процессами,
происходящими на странице. Важно понимать различия между состояниями
загрузки, использовать таймауты и учитывать сценарии с несколькими
переходами, чтобы добиться максимальной стабильности и надежности
тестов.