Действия
Введение
Playwright может взаимодействовать с HTML-элементами ввода, такими как текстовые поля, флажки, радиокнопки, опции выбора, щелчки мыши, ввод символов, клавиши и сочетания клавиш, а также загружать файлы и фокусировать элементы.
Текстовый ввод
Использование locator.fill() — это самый простой способ заполнить поля формы. Он фокусирует элемент и вызывает событие input
с введенным текстом. Это работает для элементов <input>
, <textarea>
и [contenteditable]
.
- Sync
- Async
# Текстовый ввод
page.get_by_role("textbox").fill("Peter")
# Ввод даты
page.get_by_label("Birth date").fill("2020-02-02")
# Ввод времени
page.get_by_label("Appointment time").fill("13:15")
# Ввод локальной даты и времени
page.get_by_label("Local time").fill("2020-03-02T05:15")
# Текстовый ввод
await page.get_by_role("textbox").fill("Peter")
# Ввод даты
await page.get_by_label("Birth date").fill("2020-02-02")
# Ввод времени
await page.get_by_label("Appointment time").fill("13:15")
# Ввод локальной даты и времени
await page.get_by_label("Local time").fill("2020-03-02T05:15")
Флажки и радиокнопки
Использование locator.set_checked() — это самый простой способ установить или снять флажок или радиокнопку. Этот метод можно использовать с элементами input[type=checkbox]
, input[type=radio]
и [role=checkbox]
.
- Sync
- Async
# Установить флажок
page.get_by_label('I agree to the terms above').check()
# Проверить состояние флажка
expect(page.get_by_label('Subscribe to newsletter')).to_be_checked()
# Выбрать радиокнопку
page.get_by_label('XL').check()
# Установить флажок
await page.get_by_label('I agree to the terms above').check()
# Проверить состояние флажка
await expect(page.get_by_label('Subscribe to newsletter')).to_be_checked()
# Выбрать радиокнопку
await page.get_by_label('XL').check()
Выбор опций
Выбирает одну или несколько опций в элементе <select>
с помощью locator.select_option(). Вы можете указать value
или label
для выбора. Можно выбрать несколько опций.
- Sync
- Async
# Одинарный выбор по значению или метке
page.get_by_label('Choose a color').select_option('blue')
# Одинарный выбор по метке
page.get_by_label('Choose a color').select_option(label='Blue')
# Несколько выбранных элементов
page.get_by_label('Choose multiple colors').select_option(['red', 'green', 'blue'])
# Одинарный выбор по значению или метке
await page.get_by_label('Choose a color').select_option('blue')
# Одинарный выбор по метке
await page.get_by_label('Choose a color').select_option(label='Blue')
# Несколько выбранных элементов
await page.get_by_label('Choose multiple colors').select_option(['red', 'green', 'blue'])
Щелчок мышью
Выполняет простой человеческий щелчок.
- Sync
- Async
# Обычный щелчок
page.get_by_role("button").click()
# Двойной щелчок
page.get_by_text("Item").dblclick()
# Щелчок правой кнопкой
page.get_by_text("Item").click(button="right")
# Shift + щелчок
page.get_by_text("Item").click(modifiers=["Shift"])
# Наведение на элемент
page.get_by_text("Item").hover()
# Щелчок в верхнем левом углу
page.get_by_text("Item").click(position={ "x": 0, "y": 0})
# Обычный щелчок
await page.get_by_role("button").click()
# Двойной щелчок
await page.get_by_text("Item").dblclick()
# Щелчок правой кнопкой
await page.get_by_text("Item").click(button="right")
# Shift + щелчок
await page.get_by_text("Item").click(modifiers=["Shift"])
# Ctrl + щелчок на Windows и Linux
# Meta + щелчок на macOS
await page.get_by_text("Item").click(modifiers=["ControlOrMeta"])
# Наведение на элемент
await page.get_by_text("Item").hover()
# Щелчок в верхнем левом углу
await page.get_by_text("Item").click(position={ "x": 0, "y": 0})
Под капотом этот и другие методы, связанные с указателем:
- ждут, пока элемент с данным селектором появится в DOM
- ждут, пока он станет видимым, т.е. не пустым, без
display:none
, безvisibility:hidden
- ждут, пока он перестанет двигаться, например, пока не завершится css-переход
- прокручивают элемент в видимую область
- ждут, пока он не начнет получать события указателя в точке действия, например, ждут, пока элемент не станет не закрытым другими элементами
- повторяют попытку, если элемент отсоединяется во время любой из вышеуказанных проверок
Принудительный щелчок
Иногда приложения используют нетривиальную логику, когда при наведении курсора на элемент он перекрывается другим элементом, который перехватывает щелчок. Это поведение неотличимо от ошибки, когда элемент закрывается, и щелчок отправляется в другое место. Если вы знаете, что это происходит, вы можете обойти проверки действительности и принудительно выполнить щелчок:
- Sync
- Async
page.get_by_role("button").click(force=True)
await page.get_by_role("button").click(force=True)
Программный щелчок
Если вы не заинтересованы в тестировании вашего приложения в реальных условиях и хотите симулировать щелчок любыми возможными средствами, вы можете вызвать поведение HTMLElement.click()
просто отправив событие щелчка на элемент с помощью locator.dispatch_event():
- Sync
- Async
page.get_by_role("button").dispatch_event('click')
await page.get_by_role("button").dispatch_event('click')
Ввод символов
В большинстве случаев вам следует вводить текст с помощью locator.fill(). См. раздел Текстовый ввод выше. Вам нужно вводить символы только в том случае, если на странице есть специальная обработка клавиатуры.
Вводите в поле символ за символом, как если бы это был пользователь с настоящей клавиатурой, с помощью locator.press_sequentially().
- Sync
- Async
# Нажимайте клавиши по одной
page.locator('#area').press_sequentially('Hello World!')
# Нажимайте клавиши по одной
await page.locator('#area').press_sequentially('Hello World!')
Этот метод будет генерировать все необходимые события клавиатуры, с учетом всех событий keydown
, keyup
, keypress
. Вы даже можете указать необязательную delay
между нажатиями клавиш, чтобы симулировать поведение реального пользователя.
Клавиши и сочетания клавиш
- Sync
- Async
# Нажать Enter
page.get_by_text("Submit").press("Enter")
# Отправить Control+Right
page.get_by_role("textbox").press("Control+ArrowRight")
# Нажать знак $ на клавиатуре
page.get_by_role("textbox").press("$")
# Нажать Enter
await page.get_by_text("Submit").press("Enter")
# Отправить Control+Right
await page.get_by_role("textbox").press("Control+ArrowRight")
# Нажать знак $ на клавиатуре
await page.get_by_role("textbox").press("$")
Метод locator.press() фокусирует выбранный элемент и производит одно нажатие клавиши. Он принимает логические имена клавиш, которые генерируются в свойстве keyboardEvent.key событий клавиатуры:
Backquote, Minus, Equal, Backslash, Backspace, Tab, Delete, Escape,
ArrowDown, End, Enter, Home, Insert, PageDown, PageUp, ArrowRight,
ArrowUp, F1 - F12, Digit0 - Digit9, KeyA - KeyZ и т.д.
- Вы также можете указать один символ, который хотите сгенерировать, например
"a"
или"#"
. - Также поддерживаются следующие модификационные сочетания:
Shift, Control, Alt, Meta
.
Простая версия генерирует один символ. Этот символ чувствителен к регистру, поэтому "a"
и "A"
дадут разные результаты.
- Sync
- Async
# <input id=name>
page.locator('#name').press('Shift+A')
# <input id=name>
page.locator('#name').press('Shift+ArrowLeft')
# <input id=name>
await page.locator('#name').press('Shift+A')
# <input id=name>
await page.locator('#name').press('Shift+ArrowLeft')
Также поддерживаются сочетания клавиш, такие как "Control+o"
или "Control+Shift+T"
. При указании с модификатором, модификатор нажимается и удерживается, пока не будет нажата последующая клавиша.
Обратите внимание, что вам все равно нужно указать заглавную A
в Shift-A
, чтобы получить заглавный символ. Shift-a
дает строчную букву, как если бы у вас был включен CapsLock
.
Загрузка файлов
Вы можете выбрать файлы для загрузки, используя метод locator.set_input_files(). Он ожидает, что первый аргумент указывает на элемент ввода с типом "file"
. Несколько файлов могут быть переданы в массиве. Если некоторые из путей к файлам являются относительными, они разрешаются относительно текущей рабочей директории. Пустой массив очищает выбранные файлы.
- Sync
- Async
# Выбрать один файл
page.get_by_label("Upload file").set_input_files('myfile.pdf')
# Выбрать несколько файлов
page.get_by_label("Upload files").set_input_files(['file1.txt', 'file2.txt'])
# Выбрать директорию
page.get_by_label("Upload directory").set_input_files('mydir')
# Удалить все выбранные файлы
page.get_by_label("Upload file").set_input_files([])
# Загрузить буфер из памяти
page.get_by_label("Upload file").set_input_files(
files=[
{"name": "test.txt", "mimeType": "text/plain", "buffer": b"this is a test"}
],
)
# Выбрать один файл
await page.get_by_label("Upload file").set_input_files('myfile.pdf')
# Выбрать несколько файлов
await page.get_by_label("Upload files").set_input_files(['file1.txt', 'file2.txt'])
# Выбрать директорию
await page.get_by_label("Upload directory").set_input_files('mydir')
# Удалить все выбранные файлы
await page.get_by_label("Upload file").set_input_files([])
# Загрузить буфер из памяти
await page.get_by_label("Upload file").set_input_files(
files=[
{"name": "test.txt", "mimeType": "text/plain", "buffer": b"this is a test"}
],
)
Если у вас нет элемента ввода под рукой (он создается динамически), вы можете обработать событие page.on("filechooser") или использовать соответствующий метод ожидания после вашего действия:
- Sync
- Async
with page.expect_file_chooser() as fc_info:
page.get_by_label("Upload file").click()
file_chooser = fc_info.value
file_chooser.set_files("myfile.pdf")
async with page.expect_file_chooser() as fc_info:
await page.get_by_label("Upload file").click()
file_chooser = await fc_info.value
await file_chooser.set_files("myfile.pdf")
Фокусировка элемента
Для динамических страниц, которые обрабатывают события фокусировки, вы можете сфокусировать данный элемент с помощью locator.focus().
- Sync
- Async
page.get_by_label('password').focus()
await page.get_by_label('password').focus()
Перетаскивание
Вы можете выполнить операцию перетаскивания с помощью метода locator.drag_to(). Этот метод выполнит следующие действия:
- Наведет курсор на элемент, который будет перетаскиваться.
- Нажмет левую кнопку мыши.
- Переместит курсор мыши к элементу, который будет принимать перетаскиваемый объект.
- Отпустит левую кнопку мыши.
- Синхронный
- Асинхронный
page.locator("#item-to-be-dragged").drag_to(page.locator("#item-to-drop-at"))
await page.locator("#item-to-be-dragged").drag_to(page.locator("#item-to-drop-at"))
Перетаскивание вручную
Если вам нужен точный контроль над операцией перетаскивания, используйте более низкоуровневые методы, такие как locator.hover(), mouse.down(), mouse.move() и mouse.up().
- Синхронный
- Асинхронный
page.locator("#item-to-be-dragged").hover()
page.mouse.down()
page.locator("#item-to-drop-at").hover()
page.mouse.up()
await page.locator("#item-to-be-dragged").hover()
await page.mouse.down()
await page.locator("#item-to-drop-at").hover()
await page.mouse.up()
Если ваша страница зависит от события dragover
, вам нужно как минимум два перемещения мыши, чтобы вызвать его во всех браузерах. Чтобы надежно выполнить второе перемещение мыши, повторите mouse.move() или locator.hover() дважды. Последовательность операций будет следующей: наведите курсор на элемент для перетаскивания, нажмите кнопку мыши, наведите курсор на элемент для сброса, наведите курсор на элемент для сброса второй раз, отпустите кнопку мыши.
Прокрутка
В большинстве случаев Playwright автоматически прокручивает страницу перед выполнением любых действий. Поэтому вам не нужно явно прокручивать страницу.
- Синхронный
- Асинхронный
# Прокручивает автоматически, чтобы кнопка была видна
page.get_by_role("button").click()
# Прокручивает автоматически, чтобы кнопка была видна
await page.get_by_role("button").click()
Однако в редких случаях вам может понадобиться прокрутить страницу вручную. Например, вы можете захотеть заставить "бесконечный список" загрузить больше элементов или позиционировать страницу для определенного скриншота. В таком случае наиболее надежный способ — найти элемент, который вы хотите сделать видимым внизу, и прокрутить его в поле зрения.
- Синхронный
- Асинхронный
# Прокрутите нижний колонтитул в поле зрения, заставляя "бесконечный список" загрузить больше контента
page.get_by_text("Footer text").scroll_into_view_if_needed()
# Прокрутите нижний колонтитул в поле зрения, заставляя "бесконечный список" загрузить больше контента
await page.get_by_text("Footer text").scroll_into_view_if_needed()
Если вы хотите более точно контролировать прокрутку, используйте mouse.wheel() или locator.evaluate():
- Синхронный
- Асинхронный
# Позиционируйте мышь и прокручивайте колесиком мыши
page.get_by_test_id("scrolling-container").hover()
page.mouse.wheel(0, 10)
# Или программно прокрутите конкретный элемент
page.get_by_test_id("scrolling-container").evaluate("e => e.scrollTop += 100")
# Позиционируйте мышь и прокручивайте колесиком мыши
await page.get_by_test_id("scrolling-container").hover()
await page.mouse.wheel(0, 10)
# Или программно прокрутите конкретный элемент
await page.get_by_test_id("scrolling-container").evaluate("e => e.scrollTop += 100")