БэкендDevOpsPython

Как управлять браузером через Playwright на Python: форма, клик и скриншот

Запускаем Chromium из Python, заполняем локальную форму, нажимаем кнопку, проверяем результат и сохраняем скриншот через устойчивые локаторы Playwright.

Кодик

Автор

6 мин чтения

Playwright позволяет Python управлять настоящим браузером и одновременно проверять, что пользовательский сценарий завершился правильно. Вместо движения мыши по координатам скрипт находит поле по подписи, кнопку по роли, ждёт результат и сохраняет скриншот. Соберём такой сценарий на локальной странице, чтобы сеть и чужой сайт не мешали понять механику.

Автоматизация браузера часто выглядит как магия: окно само открывается, текст появляется в форме, кнопка нажимается без человека. На деле здесь есть точная цепочка. Python запускает движок Chromium, Playwright создаёт страницу, локаторы находят элементы по смыслу, а ожидания синхронизируют действия с интерфейсом.

1Открываем

Запускаем отдельный Chromium и загружаем локальный demo.html без зависимости от интернета.

2Действуем

Находим поле по label, вводим имя и нажимаем кнопку по доступной роли.

3Доказываем

Проверяем текст результата и сохраняем полноэкранный PNG после успешного сценария.

Как Playwright видит страницу и действия

Проект состоит из двух файлов. demo.html является маленьким приложением: в нём есть связанная с полем подпись, кнопка и область результата с data-testid. main.py запускает Playwright в синхронном режиме и открывает HTML через file URL. Затем сценарий выполняет ровно те действия, которые сделал бы человек.

ЭтапЧто происходитПризнак результата
ЗапускPython создаёт Chromium и новую страницуОкно браузера готово
ПоискЛокатор находит поле и кнопку по смыслуНайден ровно один элемент
Действиеfill и click вызывают события страницыПоявляется приветствие
Проверкаexpect сравнивает текст, screenshot пишет PNGТест завершён без ошибки

У проекта есть один главный маршрут: получить входные данные, проверить их, выполнить действие и показать результат. Если каждый этап можно проверить отдельно, ошибка перестаёт быть загадкой.

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

Не автоматизируйте чужой сайт для первого опыта. Разметка, защита и данные стороннего сервиса могут измениться без предупреждения. Локальная страница даёт контролируемую лабораторию: если тест упал, причина находится в вашем коде, а не в сети или антибот-защите.

Пишем форму и первый Python-сценарий

Создайте каталог и выполните uv init browser-lab, затем uv add playwright и uv run playwright install chromium. Последняя команда загружает совместимый браузер. Положите рядом demo.html из исходников статьи и main.py. Запускайте через uv run python main.py. Значение headless=False оставляет окно видимым; когда сценарий станет стабильным, поменяйте его на True для фонового запуска.

from pathlib import Path
from playwright.sync_api import expect, sync_playwright

page_url = Path("demo.html").resolve().as_uri()

with sync_playwright() as playwright:
    browser = playwright.chromium.launch(headless=False)
    page = browser.new_page(viewport={"width": 1100, "height": 720})

    page.goto(page_url)
    page.get_by_label("Имя").fill("Аня")
    page.get_by_role("button", name="Проверить").click()

    result = page.get_by_test_id("result")
    expect(result).to_have_text("Привет, Аня!")
    page.screenshot(path="result.png", full_page=True)

    print("Готово: приветствие проверено, result.png сохранён")
    browser.close()
Что должно произойти после запуска
  • Открывается отдельное окно Chromium с локальной формой.
  • В поле появляется имя «Аня», после клика выводится «Привет, Аня!».
  • Если текст отличается, expect останавливает сценарий с понятным сравнением.
  • После успеха рядом с main.py появляется полноэкранный result.png.

Сценарий не содержит sleep и координат. Playwright сам ждёт, пока поле станет доступным, кнопка перестанет двигаться и элемент сможет принять действие. Это делает тест быстрее на хорошем компьютере и устойчивее на медленном.

Координаты и смысловые локаторы
Что отличает устойчивый проект от случайного успеха. Хороший локатор описывает назначение, а не положение

Почему локаторы надёжнее координат

Локатор не является найденным DOM-элементом, сохранённым навсегда. Это описание того, как Playwright должен найти элемент в момент действия. get_by_label связывает текст подписи с input через атрибут for, get_by_role использует доступную роль button и имя, а get_by_test_id обращается к стабильному служебному атрибуту.

ЧастьОтветственностьЧто проверить
BrowserОтдельный процесс ChromiumЗакрывается даже после проверки
PageОдна вкладка и её viewportОткрыт правильный URL
LocatorПравило поиска элементаСовпадает ровно один узел
ActionВвод, клик или выборСобытие действительно сработало
AssertionОжидание проверяемого состоянияПолучен ожидаемый текст

CSS-селектор вроде div:nth-child(3) привязан к форме страницы, а роль и подпись описывают назначение элемента. Если дизайнер добавит обёртку, семантический локатор продолжит работать. Если на странице две одинаковые кнопки, Playwright специально сообщит о неоднозначности.

Не маскируйте ошибку force-кликом. Если кнопку перекрывает модальное окно, обычный пользователь тоже не сможет нажать её. force=True скрывает продуктовую проблему. Сначала выясните, почему элемент не проходит проверки доступности и видимости.

Ломаем сценарий и учимся читать ошибку

Запустите готовый сценарий, затем намеренно замените ожидаемое имя на «Борис». Посмотрите, как expect показывает полученный и ожидаемый текст. Верните правильное значение и удалите атрибут for у label в demo.html: теперь get_by_label не должен находить поле. Исправьте связь. После этого добавьте чекбокс «Писать официально» и второй вариант ответа.

Проверка своими руками
  1. Запустите браузер в видимом режиме и убедитесь, что result.png создаётся только после текста.
  2. Поменяйте имя в assert, прочитайте ошибку и верните корректное ожидание.
  3. Добавьте задержку setTimeout на странице и убедитесь, что expect дождался результата без sleep.
  4. Создайте вторую кнопку с тем же именем и разберите ошибку strict mode.
  5. Уточните локатор через область формы, а не через .first().
  6. Переключите headless=True и повторите запуск из терминала.
Готово, если выполняются все пункты
  • Скрипт стабильно проходит два запуска подряд.
  • Локаторы используют label, role и test id.
  • Неверное ожидание даёт читаемую ошибку.
  • После изменения формы вы можете поправить тест сами.

Главный результат этой практики не скриншот, а воспроизводимый сценарий. Он либо подтверждает нужное состояние, либо останавливается в точной строке. Теперь браузерная автоматизация стала проверкой, а не записью движений мыши.

Четыре проверки Playwright
Четыре проверки перед следующим шагом. Падение должно объяснять, какой шаг не выполнен

Куда развивать браузерную автоматизацию

Следующий шаг зависит от задачи. Для тестирования оформите сценарий как pytest-тест и создавайте новую страницу для каждого случая. Для рутинной автоматизации добавьте входные данные из JSON и отчёт, но не храните пароли в коде. Секреты передавайте через переменные окружения, а чувствительные поля маскируйте на скриншотах.

Как изучить тему в Кодике

В Кодике начните с функций, путей к файлам и контекстных менеджеров Python. Затем закрепите HTML-формы и события на простом примере. После этого API Playwright читается естественно: объект page получает команды, локатор описывает элемент, а expect проверяет состояние.

ШагЧто изучить в КодикеМини-проверка
1Функции и with в курсе PythonОткрыть и гарантированно закрыть ресурс
2HTML-форма и labelСвязать подпись с полем через for и id
3Локаторы PlaywrightНайти элементы тремя семантическими способами
4Ожидания и assertНамеренно получить и объяснить падение
5Структура автотестаРазделить подготовку, действие и проверку

После статьи повторите только demo.html и первые четыре действия main.py в тренажёре Кодика. На следующий день соберите их по памяти и добавьте второй сценарий. Так вы учите не список методов, а модель: найти элемент, выполнить действие, дождаться состояния, доказать результат.

Забыли установить браузер

Пакет Python и бинарник Chromium устанавливаются отдельно. Выполните playwright install chromium в том же окружении.

Используются координаты

Размер окна или новая плашка сдвинут кнопку. Ищите элемент по роли, подписи или стабильному test id.

Везде стоит time.sleep

Фиксированная пауза либо замедляет тест, либо оказывается слишком короткой. Используйте ожидания Playwright.

Браузер не закрывается

Контекст with и явный browser.close помогают не оставлять процессы после локального запуска.

Сверьтесь с первичным источником. Команды, версии и ограничения примера проверяйте по официальной документации Playwright Python. Если интерфейс изменился, первичная документация важнее старого скриншота.

Что получится в итоге

Готовый результат: Как управлять браузером через Playwright на Python: форма, клик и скриншот
Python открывает локальную форму, вводит имя, проверяет приветствие и сохраняет PNG только после успешного сценария.

Короткие ответы
Почему get_by_role лучше случайного CSS-пути?

Роль и доступное имя описывают назначение элемента и меньше зависят от вложенности разметки.

Зачем нужен expect, если можно сразу прочитать inner_text?

expect повторяет проверку до тайм-аута и учитывает асинхронное обновление интерфейса.

Когда включать headless=True?

После отладки, когда сценарий стабилен и его нужно запускать без видимого окна.

Как понять, что проект действительно работает?

Проверьте основной сценарий, неверный ввод, повторный запуск и один граничный случай. Затем объясните путь данных своими словами.

Можно ли начать с готового кода из статьи?

Да. Добейтесь результата, измените одно правило и соберите ключевой файл заново без копирования.

Превратите один сценарий в навык автоматизации

Основы функций, файлов и обработки ошибок закрепите в курсе Python. Работу с терминалом освежите в статье про терминал VS Code.

Затем сравните окружения в материале про uv и сохраните проект по инструкции про GitHub.