Playwright Python — справочник На главный сайт

Обзор действий в Playwright

Playwright предоставляет богатый набор методов для взаимодействия с элементами на странице. Все действия автоматически ожидают, что элемент станет доступным (Auto-Waiting), прежде чем выполнить команду. Это избавляет от необходимости писать явные ожидания в большинстве случаев.

Все действия выполняются через объект Locator, который можно получить методами page.get_by_*() или другими способами поиска элементов.

Важно: Перед каждым действием Playwright проверяет, что элемент привязан к DOM, видим, стабилен (не анимируется), не заблокирован и включён. Если элемент не соответствует этим критериям в течение таймаута (по умолчанию 30 секунд), действие завершится ошибкой.

locator.click() — Клик по элементу

Основной метод для клика. Поддерживает множество опций для точной настройки:

# Простой клик
page.get_by_role("button", name="Submit").click()

# Клик с зажатым Ctrl (для множественного выбора)
page.get_by_text("Item 1").click(modifiers=["Control"])

# Клик в определённой позиции внутри элемента
page.get_by_role("button").click(position={ "x": 10, "y": 20 })

# Клик с задержкой (mousedown и mouseup разделены 500 мс)
page.get_by_text("Slow").click(delay=500)

# Принудительный клик (без проверок actionability)
page.get_by_role("button").click(force=True)

# Клик и не ждать навигации (noWaitAfter)
page.get_by_text("Download").click(no_wait_after=True)

# Клик с кастомным таймаутом
page.get_by_role("link").click(timeout=10000)

# Пробный клик (trial) — выполняет проверки, но не кликает
page.get_by_role("button").click(trial=True)

# Клик правой кнопкой мыши
page.get_by_role("button").click(button="right")

Параметры click()

ПараметрТипОписание
modifierslist[str]Клавиши-модификаторы: "Alt", "Control", "Meta", "Shift"
positiondictКоординаты внутри элемента {"x": 10, "y": 20}
delayintЗадержка между mousedown и mouseup в мс
buttonstr"left", "right", "middle"
click_countintКоличество кликов (1, 2, 3...)
forceboolПропустить проверки actionability (по умолчанию False)
no_wait_afterboolНе ждать завершения навигации после клика
timeoutintТаймаут ожидания в мс (по умолчанию 30000)
trialboolПробный запуск — проверить, но не кликать

locator.dblclick() и click(count=2) — Двойной клик

# Двойной клик через специализированный метод
page.get_by_text("Word").dblclick()

# Двойной клик через параметр click_count
page.get_by_role("button").click(click_count=2)

# Двойной клик с опциями
page.get_by_text("Word").dblclick(delay=300, modifiers=["Shift"])

locator.fill() — Очистка и ввод текста

Метод fill() очищает поле и вводит текст. Это самый быстрый способ заполнить поле ввода, так как Playwright использует внутренние механизмы, а не эмулирует нажатия клавиш.

# Очистка поля и ввод текста
page.get_by_label("Email").fill("user@example.com")

# Передача пустой строки очищает поле
page.get_by_label("Email").fill("")

# Ввод с кастомным таймаутом
page.get_by_placeholder("Введите имя").fill("Анна", timeout=5000)

Совет: Используйте fill() для полей ввода, текстовых областей и contenteditable элементов. Для эмуляции реального ввода с клавиатуры (когда важны события нажатия каждой клавиши) используйте type() или press_sequentially().

locator.type() — Поэтапный ввод текста

Метод type() вводит текст посимвольно, эмулируя реальную печать на клавиатуре. Полезен для тестирования автодополнения и других сценариев, где важны события ввода каждого символа.

# Ввод текста посимвольно (без задержки)
page.get_by_label("Search").type("playwright")

# Ввод с задержкой между символами (100 мс)
page.get_by_label("Slow search").type("playwright", delay=100)

locator.clear() — Очистка поля

# Очистка поля ввода
page.get_by_role("textbox").clear()

# Очистка с опциями
page.get_by_label("Name").clear(timeout=5000, force=True)

locator.check(), locator.uncheck(), locator.set_checked() — Чекбоксы и радиокнопки

# Отметить чекбокс
page.get_by_role("checkbox").check()

# Снять отметку
page.get_by_role("checkbox").uncheck()

# Установить состояние (True / False)
page.get_by_role("checkbox").set_checked(True)

# Радиокнопка (выбор через check)
page.get_by_role("radio", name="Option A").check()

# Принудительная отметка без проверок
page.get_by_label("Agree").check(force=True)

locator.select_option() — Выбор опций из select

Метод для работы с HTML-элементом <select>. Поддерживает выбор по value, по видимому тексту (label) и по индексу.

# Выбор по value
page.get_by_role("combobox").select_option("option-1")

# Выбор по видимому тексту
page.get_by_label("Country").select_option(label="Russia")

# Выбор по индексу (0-based)
page.get_by_role("combobox").select_option(index=2)

# Множественный выбор (для select с multiple)
page.get_by_role("listbox").select_option(["red", "green", "blue"])

# Смешанный выбор
page.get_by_label("Items").select_option(value="a", label="Item B", index=3)

locator.hover(), locator.focus(), locator.tab() — Ховер, фокус, табуляция

# Наведение мыши на элемент
page.get_by_role("link", name="Dropdown").hover()

# Установка фокуса на элементе
page.get_by_role("textbox").focus()

# Табуляция (переход к следующему фокусируемому элементу)
page.get_by_role("textbox").press("Tab")

# Hover с модификатором
page.get_by_text("Tooltip").hover(modifiers=["Shift"])

locator.press() — Нажатие клавиш

Метод для эмуляции нажатия отдельных клавиш или комбинаций. Поддерживает все стандартные клавиатурные сокращения.

# Нажатие Enter
page.get_by_role("textbox").press("Enter")

# Переход на следующий элемент (Tab)
page.get_by_label("Name").press("Tab")

# Комбинация Ctrl+A (выделить всё)
page.get_by_role("textbox").press("Control+A")

# Комбинация Ctrl+C (копировать)
page.get_by_role("textbox").press("Control+C")

# Escape для закрытия модального окна
page.get_by_role("dialog").press("Escape")

# Стрелка вниз (для открытия выпадающего списка)
page.get_by_role("combobox").press("ArrowDown")

# Функциональные клавиши
page.get_by_role("textbox").press("F5")

locator.press_sequentially() — Последовательное нажатие клавиш

Вводит текст по одному символу, эмулируя реальный ввод с клавиатуры. В отличие от type(), этот метод работает через события клавиатуры, а не через вставку текста.

# Последовательный ввод текста с задержкой
page.get_by_label("Search").press_sequentially("playwright", delay=50)

# Быстрый последовательный ввод (без задержки)
page.get_by_placeholder("Введите запрос").press_sequentially("тестовый запрос")

locator.dispatch_event() — Низкоуровневая отправка событий

Позволяет вручную отправить DOM-событие на элемент. Полезно для тестирования обработчиков событий, когда не требуется полная эмуляция пользовательского ввода.

# Отправка кастомного события
page.get_by_role("button").dispatch_event("click")

# Отправка события с произвольными данными
page.get_by_role("button").dispatch_event("custom-event", detail={ "key": "value" })

# Событие change на select
page.get_by_role("combobox").dispatch_event("change")

locator.scroll_into_view_if_needed() — Скролл до элемента

Прокручивает страницу (или родительский контейнер) до тех пор, пока элемент не окажется в видимой области. Полезно для элементов, которые находятся за пределами видимой части страницы.

# Скролл элемента в видимую область
page.get_by_text("Footer content").scroll_into_view_if_needed()

# Скролл с таймаутом
page.get_by_role("heading", name="Section 10").scroll_into_view_if_needed(timeout=10000)

locator.triple_click() — Тройной клик

Тройной клик обычно используется для выделения текста в редакторах и текстовых полях.

# Тройной клик
page.get_by_role("textbox").triple_click()

# Тройной клик с опциями
page.get_by_label("Editor").triple_click(delay=100, timeout=5000)

Drag-and-Drop — Перетаскивание

Playwright поддерживает drag-and-drop как на высоком уровне (через drag_to()), так и на низком уровне (через события мыши).

locator.drag_to()

# Высокоуровневый drag-and-drop
source = page.get_by_text("Drag me")
target = page.get_by_text("Drop here")
source.drag_to(target)

# Drag-and-drop с координатами смещения
source.drag_to(target, source_position={ "x": 0, "y": 0 },
              target_position={ "x": 10, "y": 10 })

Низкоуровневый drag-and-drop

# Ручное управление мышью для сложных сценариев drag-and-drop
page.mouse.move(100, 200)
page.mouse.down()
page.mouse.move(300, 400, steps=10)  # 10 шагов для плавного перемещения
page.mouse.up()

# Пример с локатором
box = page.get_by_text("Draggable").bounding_box()
page.mouse.move(box["x"] + box["width"] / 2, box["y"] + box["height"] / 2)
page.mouse.down()
page.mouse.move(box["x"] + 200, box["y"] + 200, steps=20)
page.mouse.up()

Загрузка файлов

Playwright предлагает несколько способов загрузки файлов — от простого указания пути до перехвата диалога выбора файла.

locator.set_input_files() — Загрузка через input

# Загрузка одного файла
page.get_by_label("Upload file").set_input_files("document.pdf")

# Загрузка нескольких файлов
page.get_by_label("Upload files").set_input_files(["file1.pdf", "file2.jpg"])

# Очистка выбранных файлов (пустой массив)
page.get_by_label("Upload").set_input_files([])

Загрузка с FilePayload

Можно передать файл программно, указав имя, MIME-тип и содержимое в виде байтов:

# Создание файла программно (FilePayload)
page.get_by_label("Upload").set_input_files({
    "name": "test.txt",
    "mimeType": "text/plain",
    "buffer": b"Hello, Playwright!"
})

# Несколько программных файлов
page.get_by_label("Upload").set_input_files([
    { "name": "file1.txt", "mimeType": "text/plain", "buffer": b"Content 1" },
    { "name": "file2.csv", "mimeType": "text/csv", "buffer": b"a,b,c" },
])

Загрузка через page.on("filechooser")

Этот способ используется, когда элемент <input type="file"> скрыт или когда нужно перехватить диалог выбора файла в ответ на клик по произвольному элементу.

# Перехват события filechooser в контекстном менеджере
with page.expect_file_chooser() as fc_info:
    page.get_by_label("Upload area").click()
file_chooser = fc_info.value
file_chooser.set_files("image.png")

# Загрузка нескольких файлов через filechooser
with page.expect_file_chooser() as fc_info:
    page.get_by_role("button", name="Upload").click()
file_chooser = fc_info.value
file_chooser.set_files(["photo1.jpg", "photo2.jpg"])

# FileChooser с программными файлами
with page.expect_file_chooser() as fc_info:
    page.locator(".upload-btn").click()
file_chooser = fc_info.value
file_chooser.set_files([
    { "name": "report.pdf", "mimeType": "application/pdf", "buffer": b"PDF content" }
])

Важно: Метод set_input_files() работает только с элементами <input type="file">. Если загрузка файла инициируется кликом по произвольному элементу (не input), используйте подход с page.expect_file_chooser().

Дополнительные методы действий

Keyboard API

# Глобальные нажатия клавиш через page.keyboard
page.keyboard.press("Control+A")
page.keyboard.type("Hello, World!", delay=50)
page.keyboard.down("Shift")
page.keyboard.press("End")
page.keyboard.up("Shift")

# Вставка текста (аналог fill, но через page)
page.keyboard.insert_text("Вставленный текст")

Mouse API

# Клик через глобальный Mouse API
page.mouse.click(150, 300)
page.mouse.dblclick(150, 300)
page.mouse.down()
page.mouse.move(500, 600)
page.mouse.up()
page.mouse.wheel(0, 500)  # Скролл колёсиком вниз на 500 пикселей

Практические примеры

Полный сценарий регистрации

def test_user_registration(page):
    page.goto("https://example.com/register")

    # Заполнение формы
    page.get_by_label("Имя").fill("Анна")
    page.get_by_label("Email").fill("anna@example.com")
    page.get_by_label("Пароль").fill("SecurePass123!")

    # Выбор страны из выпадающего списка
    page.get_by_role("combobox", name="Страна").select_option(label="Россия")

    # Отметка чекбокса согласия
    page.get_by_role("checkbox", name="Согласен с условиями").check()

    # Отправка формы
    page.get_by_role("button", name="Зарегистрироваться").click()

    # Ожидание перенаправления
    page.wait_for_url("**/dashboard")

Drag-and-drop в интерфейсе канбан-доски

def test_drag_task(page):
    page.goto("https://example.com/board")

    task = page.get_by_text("Задача #42")
    target_column = page.get_by_role("column", name="Готово")

    # Перетаскивание задачи в колонку "Готово"
    task.drag_to(target_column)

    # Проверка, что задача теперь в колонке "Готово"
    assert target_column.get_by_text("Задача #42").is_visible()

Загрузка аватара

def test_upload_avatar(page):
    page.goto("https://example.com/profile")

    # Способ 1: прямая загрузка через input
    page.get_by_label("Аватар").set_input_files("avatar.jpg")

    # Способ 2: через filechooser (если input скрыт)
    with page.expect_file_chooser() as fc_info:
        page.get_by_role("button", name="Загрузить фото").click()
    file_chooser = fc_info.value
    file_chooser.set_files("avatar.jpg")

    # Проверка, что аватар отображается
    assert page.get_by_role("img", name="Аватар пользователя").is_visible()

Совет: При написании тестов используйте fill() вместо type() или press_sequentially() для полей ввода — это быстрее и надёжнее. type() и press_sequentially() используйте только когда важно протестировать поведение, зависящее от событий нажатия клавиш (например, автодополнение).

Заключение

Playwright предоставляет исчерпывающий набор методов для взаимодействия с веб-страницами. Все методы автоматически ожидают готовности элемента, что значительно упрощает написание стабильных тестов. При возникновении необычных ситуаций всегда можно использовать force=True для обхода проверок или dispatch_event() для низкоуровневой отправки событий.