Навигации
Полный справочник по навигации в Playwright Python: goto, reload, go_back, go_forward, ожидание загрузки, wait_for_url, wait_for_navigation и обработка ошибок.
Обзор навигации в Playwright
Playwright предоставляет полный набор методов для управления навигацией в браузере: переход по URL, перезагрузка, работа с историей браузера и ожидание завершения загрузки. Все методы навигации поддерживают тонкую настройку через параметр wait_until, который определяет, какое событие считать завершением навигации.
Важно: Методы навигации в Playwright автоматически ожидают завершения загрузки страницы. Это значит, что после page.goto() не нужно добавлять дополнительные ожидания — Playwright дождётся стабилизации страницы.
page.goto() — Основной метод навигации
Метод page.goto() выполняет переход по указанному URL. Возвращает объект Response или None (если страница загрузилась из кеша или произошла ошибка).
response = page.goto("https://example.com") assert response.status == 200 assert response.ok # Переход с таймаутом (30 секунд по умолчанию) page.goto("https://example.com", timeout=60000)
waitUntil — стратегии ожидания загрузки
Параметр wait_until определяет, какое событие считать моментом завершения навигации. Доступны четыре стратегии:
| Значение | Описание | Скорость |
|---|---|---|
"load" | Событие load — вся страница загружена (изображения, стили, скрипты) | Средняя |
"domcontentloaded" | DOM полностью загружен и разобран, без ожидания стилей и изображений | Быстрая |
"networkidle" | Сеть простаивает — нет активных сетевых запросов в течение 500 мс | Медленная |
"commit" | Сервер ответил и началась загрузка документа | Максимально быстрая |
# Стратегия "load" (по умолчанию) page.goto("https://example.com", wait_until="load") # Только DOM (быстро, но без изображений и стилей) page.goto("https://example.com", wait_until="domcontentloaded") # Ожидание полной стабилизации сети page.goto("https://example.com", wait_until="networkidle") # Минимальное ожидание (только начало загрузки) page.goto("https://example.com", wait_until="commit")
Совет: Для большинства тестов достаточно стратегии "load" (по умолчанию). Используйте "networkidle", если страница выполняет много асинхронных запросов после загрузки. "domcontentloaded" ускоряет тесты, когда важна только структура DOM. "commit" используйте, когда нужно как можно быстрее начать взаимодействие.
Дополнительные параметры goto()
# Переход с кастомными заголовками HTTP page.goto("https://example.com", headers={ "Authorization": "Bearer token123", "X-Custom": "value" }) # Переход с указанием реферера page.goto("https://example.com", referer="https://google.com") # Переход с кастомным таймаутом page.goto("https://example.com", timeout=10000) # Переход без ожидания навигации (полезно для скачивания файлов) page.goto("https://example.com/download", no_wait_after=True)
page.reload() — Перезагрузка страницы
Метод page.reload() перезагружает текущую страницу. Поддерживает те же опции, что и goto().
# Простая перезагрузка page.reload() # Перезагрузка с ожиданием стабилизации сети page.reload(wait_until="networkidle") # Перезагрузка с кастомным таймаутом page.reload(timeout=15000) # Проверка, что перезагрузка прошла успешно response = page.reload() assert response.status == 200
page.go_back() / page.go_forward() — История браузера
Методы для навигации по истории браузера (как кнопки «Назад» и «Вперёд»).
# Навигация назад page.go_back() # Навигация назад с ожиданием response = page.go_back(wait_until="domcontentloaded") if response: assert response.ok # Навигация вперёд page.go_forward() # Навигация вперёд с таймаутом page.go_forward(timeout=10000) # Полный сценарий: переход туда и обратно page.goto("https://example.com/page1") page.goto("https://example.com/page2") page.go_back() # возврат на page1 expect(page).to_have_url(re.compile(r".*page1$")) page.go_forward() # снова на page2 expect(page).to_have_url(re.compile(r".*page2$"))
page.wait_for_url() — Ожидание URL
Метод page.wait_for_url() приостанавливает выполнение до тех пор, пока текущий URL не совпадёт с указанным паттерном. Поддерживает строки, регулярные выражения и glob-паттерны.
# Ожидание точного URL page.wait_for_url("https://example.com/dashboard") # Ожидание по glob-паттерну page.wait_for_url("**/dashboard") page.wait_for_url("https://example.com/**") # Ожидание по регулярному выражению page.wait_for_url(re.compile(r"example\.com/order/\d+")) # Ожидание с таймаутом page.wait_for_url("**/success", timeout=10000) # После клика ждём определённый URL page.get_by_role("button", name="Оплатить").click() page.wait_for_url("**/payment/success")
page.wait_for_load_state() — Ожидание состояния загрузки
Метод page.wait_for_load_state() ожидает определённого состояния загрузки страницы. Это полезно, когда нужно дождаться, например, полной стабилизации сети после выполнения действий.
# Ожидание полной загрузки страницы page.wait_for_load_state() # по умолчанию "load" # Ожидание состояния "domcontentloaded" page.wait_for_load_state("domcontentloaded") # Ожидание стабилизации сети (нет запросов в течение 500 мс) page.wait_for_load_state("networkidle") # После клика, который вызывает множество запросов page.get_by_role("button", name="Загрузить данные").click() page.wait_for_load_state("networkidle", timeout=15000)
page.wait_for_navigation() — Ожидание после действия
Метод page.wait_for_navigation() используется в паре с действием, которое инициирует навигацию. Это наиболее надёжный способ дождаться завершения перехода. Рекомендуется использовать контекстный менеджер.
# Контекстный менеджер (рекомендуемый способ) with page.expect_navigation() as nav_info: page.get_by_role("link", name="О нас").click() response = nav_info.value assert response.status == 200 # Ожидание навигации с указанием URL with page.expect_navigation(url="https://example.com/about") as nav_info: page.get_by_role("link", name="О нас").click() # Ожидание навигации по glob-паттерну with page.expect_navigation(url=re.compile(r"example\.com/profile/\d+")): page.get_by_test_id("view-profile").click() # Ожидание навигации с кастомным таймаутом with page.expect_navigation(timeout=15000): page.get_by_role("button", name="Подтвердить").click() # Ожидание навигации для формы with page.expect_navigation(): page.get_by_role("button", name="Войти").click() expect(page).to_have_url("https://example.com/dashboard")
Важно: Используйте expect_navigation() вместо wait_for_load_state() после кликов, которые вызывают переход на другую страницу. expect_navigation() начинает ожидание ДО выполнения действия и точно «ловит» навигацию, в то время как wait_for_load_state() может пропустить момент перехода.
page.wait_for_function() — Ожидание JS-условия
Метод page.wait_for_function() ожидает, когда JavaScript-выражение на странице вернёт truthy-значение. Это полезно для ожидания произвольных условий, не покрытых стандартными методами.
# Ожидание появления элемента через JS page.wait_for_function("window.loadingComplete === true") # Ожидание, пока счётчик не станет больше 100 page.wait_for_function("document.querySelector('.counter').textContent >= '100'") # Ожидание с аргументом page.wait_for_function( "(max) => document.querySelectorAll('.item').length > max", arg=5 ) # Ожидание с таймаутом и интервалом проверки page.wait_for_function( "typeof window.apiData !== 'undefined'", timeout=10000, polling=200 # проверка каждые 200 мс ) # Ожидание изменения заголовка страницы page.wait_for_function( "document.title.includes('Готово')", timeout=5000 ) # Ожидание, пока элемент не станет видимым (JS-способ) page.wait_for_function( "document.querySelector('.spinner') === null" )
Обработка ошибочных навигаций: crash, download, popup
Playwright позволяет обрабатывать особые случаи навигации: краш страницы, скачивание файлов и открытие новых окон (popup).
page.on("crash") — Обработка краша страницы
Событие crash возникает, когда страница неожиданно завершает работу (например, из-за фатальной ошибки или нехватки памяти).
def handle_crash(page): print("Страница упала с ошибкой!") page.on("crash", handle_crash) page.goto("https://example.com") assert not page.is_closed() # Проверка после сложной операции try: page.goto("https://example.com/heavy-page", timeout=30000) except Error as e: if "crash" in str(e).lower(): print("Страница упала, продолжаем тест")
page.on("download") — Обработка скачивания файлов
Событие download возникает при скачивании файла. Позволяет получить доступ к файлу, его имени и пути.
with page.expect_download() as download_info: page.get_by_role("button", name="Скачать отчёт").click() download = download_info.value print(download.suggested_filename) # "report.pdf" print(download.url) # URL файла # Сохранение файла в нужную директорию download.save_as("./downloads/report.pdf") # Чтение файла как байты (без сохранения) content = download.read() assert len(content) > 0
page.on("popup") — Обработка новых окон
Событие popup возникает при открытии новой вкладки или окна (например, при клике на ссылку с target="_blank").
# Обработка всплывающего окна через контекстный менеджер with page.expect_popup() as popup_info: page.get_by_role("link", name="Открыть в новом окне").click() popup = popup_info.value popup.wait_for_load_state() expect(popup).to_have_title("Новое окно") # Работа с popup после открытия popup.get_by_role("button", name="Закрыть").click() popup.close() # Множественные popup with page.expect_popup() as popup_info: page.get_by_text("Открыть все окна").click() # Ожидание нескольких popup за раз for i in range(3): with page.expect_popup() as popup_info: page.get_by_test_id(f"open-window-{i}").click() popup = popup_info.value print(popup.title())
Таймауты навигации
Все методы навигации поддерживают настройку таймаута. По умолчанию таймаут навигации составляет 30 секунд. Его можно изменить глобально, для конкретного метода или через конфигурацию.
# Таймаут для конкретного перехода page.goto("https://example.com", timeout=60000) # Глобальная настройка таймаута навигации page.set_default_navigation_timeout(45000) # Таймаут для expect_navigation with page.expect_navigation(timeout=30000): page.get_by_role("link", name="Далее").click() # Таймаут для wait_for_url page.wait_for_url("**/success", timeout=15000) # Таймаут для wait_for_load_state page.wait_for_load_state("networkidle", timeout=20000) # Обработка превышения таймаута from playwright.sync_api import TimeoutError try: page.goto("https://example.com/slow", timeout=5000) except TimeoutError: print("Страница не загрузилась вовремя") page.reload()
Примечание: Таймауты навигации и таймауты утверждений — это разные настройки. Таймаут навигации (30 с по умолчанию) контролирует, сколько ждать загрузки страницы. Таймаут утверждений (5 с по умолчанию) контролирует, сколько ждать выполнения условия. Настраиваются они независимо.
Практические примеры
Пример: Полный сценарий навигации
def test_navigation_scenario(page): # Шаг 1: переход на главную страницу page.goto("https://example.com", wait_until="networkidle") expect(page).to_have_title("Главная") # Шаг 2: клик по ссылке и ожидание навигации with page.expect_navigation(url=re.compile(r".*/about$")): page.get_by_role("link", name="О компании").click() expect(page).to_have_url("https://example.com/about") # Шаг 3: возврат назад page.go_back() expect(page).to_have_url("https://example.com") # Шаг 4: переход вперёд page.go_forward() expect(page).to_have_url("https://example.com/about") # Шаг 5: открытие popup with page.expect_popup() as popup_info: page.get_by_text("Чат поддержки").click() popup = popup_info.value popup.wait_for_load_state() expect(popup).to_have_title("Чат") # Шаг 6: перезагрузка page.reload() expect(page).to_have_url("https://example.com/about")
Пример: Ожидание сложных условий
def test_advanced_waiting(page): page.goto("https://example.com/data") # Запуск загрузки данных page.get_by_role("button", name="Загрузить данные").click() # Ожидание стабилизации сети page.wait_for_load_state("networkidle") # Ожидание появления индикатора expect(page.get_by_test_id("data-loaded")).to_be_visible() # Дополнительное ожидание через JS-условие page.wait_for_function( "window.dataLoaded === true", timeout=10000 ) # Ожидание изменения URL page.wait_for_url("**/data/complete")
Заключение
Навигация в Playwright — это мощный и гибкий инструмент, который покрывает все сценарии: от простого перехода по URL до сложных сценариев с ожиданием асинхронных загрузок. Ключевые возможности:
- page.goto() — переход с гибкими стратегиями ожидания (load, domcontentloaded, networkidle, commit)
- page.reload(), go_back(), go_forward() — управление историей браузера
- wait_for_url(), wait_for_load_state() — ожидание конкретных состояний
- expect_navigation() — надёжное ожидание навигации после действий
- wait_for_function() — ожидание произвольных JavaScript-условий
- expect_popup(), expect_download() — обработка popup и скачиваний
- Настройка таймаутов — гибкое управление временем ожидания