Действия (Actions)
Полный справочник по всем действиям над элементами: клики, ввод текста, выбор опций, перетаскивание, загрузка файлов и многое другое.
Обзор действий в 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()
| Параметр | Тип | Описание |
|---|---|---|
modifiers | list[str] | Клавиши-модификаторы: "Alt", "Control", "Meta", "Shift" |
position | dict | Координаты внутри элемента {"x": 10, "y": 20} |
delay | int | Задержка между mousedown и mouseup в мс |
button | str | "left", "right", "middle" |
click_count | int | Количество кликов (1, 2, 3...) |
force | bool | Пропустить проверки actionability (по умолчанию False) |
no_wait_after | bool | Не ждать завершения навигации после клика |
timeout | int | Таймаут ожидания в мс (по умолчанию 30000) |
trial | bool | Пробный запуск — проверить, но не кликать |
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() для низкоуровневой отправки событий.