Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Живое ревью с ИИ
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. Навигация и ожидание
navigation

Навигация и ожидание

Переходы между страницами, вкладки, фреймы, auto-waiting, явные ожидания

Навигация и ожидание

Надёжная навигация и правильные ожидания — фундамент стабильных тестов. Playwright берёт на себя большую часть работы через auto-waiting, но некоторые сценарии требуют ручного управления.

#1. Базовая навигация

page.goto() — основной метод перехода на страницу:

# Переход по URL await page.goto('https://example.com') # Относительный URL (если задан base_url в конфиге) await page.goto('/dashboard') # С настройкой таймаута await page.goto('/reports', timeout=60000)

goto() автоматически ждёт завершения загрузки страницы. По умолчанию — до состояния load (полная загрузка HTML и ресурсов).

#2. Состояния загрузки

Playwright поддерживает три состояния:

# DOM распарсен — HTML загружен, скрипты выполняются await page.goto('/page', wait_until='domcontentloaded') # Полная загрузка — HTML + CSS + JS + изображения await page.goto('/page', wait_until='load') # Сеть в покое — нет активных запросов 500мс await page.goto('/page', wait_until='networkidle')
СостояниеКогда использовать
domcontentloadedБыстрые тесты, когда не нужны стили/изображения
load (по умолчанию)Стандартные тесты
networkidleSPA с асинхронной подгрузкой данных

Важно: networkidle может замедлить тесты, если страница постоянно опрашивает сервер (polling). В таких случаях используйте domcontentloaded + явное ожидание нужного элемента.

#3. Auto-waiting — встроенные ожидания

Playwright автоматически ждёт, прежде чем выполнить действие. Перед кликом он проверяет:

  1. Элемент есть в DOM
  2. Элемент видим (display: none или visibility: hidden — ждёт)
  3. Элемент стабилен (CSS-анимация завершилась)
  4. Элемент не перекрыт другим элементом
  5. Элемент активен (не disabled)
# Playwright ждёт, пока кнопка станет кликабельной await page.get_by_role('button', name='Загрузить').click()

Это означает: вам не нужен time.sleep() в 99% случаев.

#4. Явные ожидания через expect

Когда auto-waiting недостаточен (например, нужно дождаться появления элемента после AJAX), используйте expect:

from playwright.sync_api import expect # Ждём появления элемента (до 5 секунд по умолчанию) expect(page.locator('#result')).to_be_visible() # Ждём конкретного текста expect(page.get_by_role('heading')).to_have_text('Готово!') # Ждём исчезновения элемента expect(page.locator('.spinner')).to_be_hidden() # Кастомный таймаут expect(page.locator('#data')).to_be_visible(timeout=15000)

expect — это polling: Playwright проверяет условие каждые 100мс до наступления таймаута.

#5. Ожидание сетевых запросов

Когда действие вызывает API-запрос, дождитесь именно его:

# Ожидание ответа от API with page.expect_response('**/api/users') as response_info: await page.get_by_role('button', name='Загрузить').click() response = response_info.value assert response.status == 200 body = response.json() assert len(body['users']) > 0

Глоб-паттерн ** совпадает с любым количеством символов. Можно использовать функцию для сложной фильтрации:

def is_user_response(response): return '/api/users' in response.url and response.status == 200 with page.expect_response(is_user_response) as info: await page.get_by_role('button', name='Загрузить').click()

#6. Ожидание навигации

Если клик вызывает переход на другую страницу:

with page.expect_navigation(): await page.get_by_role('link', name='Профиль').click() assert '/profile' in page.url

Можно ждать конкретный URL:

with page.expect_navigation(url='**/dashboard'): await page.get_by_role('button', name='Войти').click()

Важно: если переход происходит не сразу (redirect chain), expect_navigation() дождётся финального URL.

#7. Работа с вкладками

Новая вкладка открывается через expect_popup():

with page.expect_popup() as popup_info: await page.get_by_role('link', name='Открыть').click() new_page = popup_info.value assert 'report' in new_page.url # Работа с новой вкладкой await new_page.wait_for_load_state() title = await new_page.title()

expect_popup() перехватывает и target='_blank', и window.open().

Закрытие вкладки и возврат:

await new_page.close() # page — исходная вкладка, всё ещё активна

Список всех открытых вкладок:

pages = page.context.pages print(f'Открыто вкладок: {len(pages)}')

#8. Работа с фреймами (iframe)

# Получить фрейм по имени frame = page.frame(name='payment-frame') # Получить фрейм по URL frame = page.frame(url='**/payment-provider.com') # Взаимодействие с фреймом await frame.get_by_label('Номер карты').fill('4242 4242 4242 4242') await frame.get_by_role('button', name='Оплатить').click()

Если фрейм динамически загружается:

# Ждём появления фрейма frame = page.wait_for_event('frameattached') await frame.get_by_label('Карта').fill('4242')

#9. История навигации

# Назад await page.go_back() # Вперёд await page.go_forward() # Текущий URL print(page.url) # Обновить страницу await page.reload()

#10. Типичные ошибки

❌ time.sleep() вместо expect. sleep(2) — это гадание на кофейной гуще. Может, элемент появится через 1 секунду, а может через 5. expect ждёт ровно столько, сколько нужно.

❌ networkidle для страниц с polling. Если приложение опрашивает сервер каждые 2 секунды, networkidle никогда не наступит. Используйте domcontentloaded + ожидание конкретного элемента.

❌ Доступ к context.pages[-1] без ожидания. Новая вкладка может ещё не открыться — это race condition. Всегда используйте expect_popup().

✅ Правильный подход: доверяйте auto-waiting, используйте expect для AJAX-контента, expect_response для API, expect_popup для вкладок.


#Упражнения

  1. Напишите тест, который переходит на /dashboard, ждёт загрузки данных через API (перехватите ответ /api/dashboard-data) и проверяет наличие заголовка.
  2. Откройте ссылку с target='_blank', переключитесь на новую вкладку, проверите её URL и закроете её.
  3. Найдите <iframe> на странице, заполните форму внутри него и вернитесь к основной странице.
  4. Сравните производительность wait_until='domcontentloaded' и wait_until='networkidle' на SPA-странице с медленным API.

#Что дальше?

Изучите фикстуры и параметризацию, чтобы научиться организовывать тесты с помощью pytest.

Далее: Фикстуры и параметризация