Python: Selenium
Теория: Продвинутые пользовательские действия
Класс ActionChains: hover, double-click, drag and drop
В браузере не все действия сводятся к простому click(). Бывают всплывающие меню по наведению, двойной клик, перетаскивание карточек. Для таких случаев в Selenium есть ActionChains. Этот класс строит цепочку низкоуровневых событий мыши и клавиатуры и проигрывает их единым жестом. Создание начинается с chain = ActionChains(driver). Наведение курсора делается через move_to_element(elem), после чего .perform() отправляет реальные события в браузер. Пример раскрытия меню по hover:
Двойной клик использует double_click(element). Браузер отличает его от двух обычных кликов таймингом, поэтому важно вызывать именно метод двойного клика. Пример редактирования по дабл-клику:
Перетаскивание совмещает захват, перемещение и отпускание. В простом варианте достаточно drag_and_drop(source, target), но в интерфейсах с точной геометрией надёжнее управлять оффсетами и шагами. Базовый перенос карточки в другую колонку выглядит так:
Когда целевой контейнер имеет «горячую» точку не по центру, помогает смещение. Вначале выполняется захват click_and_hold, затем курсор сдвигается и отпускается. Такой жест стабильнее на канбан-досках:
Если элемент вне вьюпорта, браузер может игнорировать события. Перед жестом стоит прокрутить его в область видимости вызовом element.location_once_scrolled_into_view или driver.execute_script("arguments[0].scrollIntoView({block:'center'})", elem). Это снимает проблемы «элемент вне экрана» и «клик перехвачен шапкой».
Клавиатурные взаимодействия
Клавиатура управляется через send_keys и константы Keys. Прямой ввод в поле:
Модификаторы удерживаются явным нажатием и отпусканием. В ActionChains это последовательность key_down → действия → key_up. Создание горячих клавиш без фокуса поля удобно выполнять на уровне документа:
Комбинации вроде Ctrl+A, Ctrl+C в одном фокусе работают надёжно, если фокус заранее помещён в нужное поле. Пример полного цикла «выделить всё → копировать → очистить → вставить»:
Системные клавиши Enter, Escape и Tab управляют формами и модалками без мыши. Закрытие диалога выполняется одной строкой:
Переход по таб-порядку помогает в интерфейсах, где кнопка недоступна обычным локатором, но присутствует в последовательности фокуса. Ввод по шагам выглядит наглядно:
Симуляция сложных пользовательских сценариев
Сложный сценарий складывается из нескольких жестов мыши и клавиатуры с паузами. ActionChains поддерживает pause(seconds), что помогает синхронизировать наведение и появление всплывающих подсказок, если в UI заложена анимация. Пример: сначала раскрывается подменю по hover, затем выбирается пункт, потом подтверждение горячей клавишей.
Имитировать «рисование» на канве или слайдер можно послойным перемещением с малыми оффсетами. Это надёжнее, чем один большой скачок, особенно когда скрипты на странице проверяют траекторию.
Для HTML5 drag-and-drop встречаются приложения, где нативные события Selenium не триггерят пользовательские обработчики. В таких случаях помогает скрипт с созданием DataTransfer и генерацией dragstart/dragover/drop. Этот приём включает бизнес-логику, которая «слушает» именно HTML5-события.
Контекстное меню требует «долгого» клика правой кнопкой. Для этого есть context_click(element). Дальше можно выбрать пункт стрелками или кликом, если меню рендерится в DOM.
Комбинация мыши и клавиатуры помогает тестировать мультивыбор в таблицах. Удержание Ctrl добавляет элементы в выделение, Shift формирует диапазон.
При сценариях с подсказками и ленивыми панелями стоит закладывать явные ожидания между шагами. Паузы в ActionChains пригодны для анимаций, но появление элементов лучше подтверждать WebDriverWait и expected_conditions, чтобы не зависеть от таймингов фронтенда. Пример: наведение, ожидание появления поповера, клик по кнопке внутри.
Если курсор должен попасть не в центр, а в конкретную точку, используется move_to_element_with_offset(elem, x, y). Это важно для небольших хэндлов, слайдеров и графиков, где активная зона узкая.
Стабильность сложных жестов повышают три простых шага: прокрутка элемента в центр вьюпорта скриптом scrollIntoView, подтверждение видимости и кликабельности через WebDriverWait, а также минимизация лишних действий в цепочке. Чем короче и точнее цепочка ActionChains, тем предсказуемее результат и тем меньше флаков при рефакторингах фронтенда.
Shadow DOM и «упрямые» элементы
Современные UI-компоненты нередко инкапсулируют верстку внутри shadow root. Обычные локаторы туда не заглядывают, поэтому сначала нужно получить shadowRoot, а потом искать элементы уже внутри него:
Shadow DOM любит динамические подгрузки, поэтому лучше комбинировать этот подход с WebDriverWait и проверками visibility_of_element_located.
Иногда элемент остаётся нечувствительным ни к клику Selenium, ни к execute_script. Причины бывают разные: перекрывающий слой, нестандартный обработчик событий, баг браузера. В крайнем случае можно задействовать OS-level инструменты вроде pyautogui: навести курсор, кликнуть или отправить клавиши напрямую в операционную систему. Такой подход стоит применять только там, где нет другого выхода — он требует реального экрана и делает запуск более хрупким. Сначала нужно исключить ошибки локаторов, добавить явные ожидания и попробовать JavaScript-клик, и лишь потом прибегать к «тяжёлой артиллерии».


