Перетаскивание элемента представляет из себя комплексное действие, которое состоит из следующих шагов: нажатие кнопки мыши (обычно левой), удержание кнопки нажатой и перемещение курсора в заданную позицию, отпускание кнопки. Drag-and-drop в Selenium реализовано с помощью Advanced User Interactions API, а именно, класса
Actions
. Сразу хочу напомнить, что для использования Actions
нативные события в браузере должны быть включены:
FirefoxProfile profile = new FirefoxProfile(); profile.setEnableNativeEvents(true); WebDriver driver = new FirefoxDriver(profile);
Actions
предоставляет два готовых метода для перетаскивания элементов:
- dragAndDrop(WebElement source, WebElement target) — выполняет нажатие и удерживание левой кнопки мыши на месте исходного элемента, перемещается к месту целевого элемента, а затем отпускает кнопку мыши. Метод применяется для перемещения элемента из одного контейнера в другой.
Пример использования:
WebElement draggable = driver.findElement(By.id("element")); WebElement target = driver.findElement(By.id("container")); new Actions(driver).dragAndDrop(draggable, target).perform();
В частном случае, метод
dragAndDrop
может быть заменен серией других методовActions
, например:WebElement draggable = driver.findElement(By.id("element")); WebElement target = driver.findElement(By.id("container")); new Actions(driver).clickAndHold(draggable).moveToElement(target) .release().perform();
- dragAndDropBy(WebElement source, int xOffset, int yOffset) — выполняет нажатие и удерживание левой кнопки мыши на месте исходного элемента, перемещается в позицию с заданным смещением, а затем отпускает кнопку мыши. xOffset и yOffset — смещение, которое задается относительно текущего положения объекта.
Этим методом удобно пользоваться для изменения расположения элемента внутри его родителя. Рассмотрим использование этого метода на примере jqSlider:
Для изменения значения слайдера нужно передвинуть ползунок в заданную позицию. Получается, что drag and drop элемента
a class="ui-slider-handle"
будет выполняться в пределах одного контейнераdiv class="ui-slider"
. Достаточно вычислить значение в пикселях внутри слайдера, которое соответствует одному делению и, в зависимости от текущего положения ползунка, рассчитывать смещение вправо или влево:/** * Дорожка слайдера */ @FindBy(className = "ui-slider") private WebElement sliderTrack; /** * Ползунок */ @FindBy(className = "ui-slider-handle") private WebElement slider; /** * Получить шаг в слайдбаре в пикселях */ public Integer getStep() { return sliderTrack.getSize().width / 4; } /** * Получить текущую позицию слайдера * * @return значение от 1-го до 5-ти */ public Integer getCurrentPosition() { // Позицию можно получить по значению атрибута left // getCssValue("left") возвращает абсолютное значение в px, Integer sliderCenterPx = Integer.parseInt(slider.getCssValue("left") .replaceAll("px", "")) + slider.getSize().width / 2; return sliderCenterPx / getStep() + 1; } /** * Установить слайдер в позицию * * @param position * - значение от 1-го до 5-ти */ public void setSliderPosition(Integer position) { if (position < 1 || position > 5) { throw new AssertionError( "Slider position value should be in the range of 1 to 5"); } Integer xOffset = (position - getCurrentPosition()) * getStep(); Actions actions = new Actions(driver); actions.dragAndDropBy(slider, xOffset, 0).perform(); }