Выделите элемент с помощью Selenium


208

Есть ли способ в Selenium 1.x или 2.x прокрутить окно браузера так, чтобы определенный элемент, идентифицированный XPath, был виден браузеру? В Selenium есть метод фокусировки, но он не выполняет физическую прокрутку в FireFox. У кого-нибудь есть предложения как это сделать?

Мне нужно это потому, что я проверяю щелчок элемента на странице. К сожалению, событие не работает, если элемент не виден. У меня нет контроля над кодом, который срабатывает при щелчке элемента, поэтому я не могу отлаживать или вносить в него изменения, поэтому самое простое решение - прокрутить элемент в поле зрения.


Вы можете попробовать этот хакерский, если у вас ничего не работает : stackoverflow.com/a/53771434/7093031
YB Причина

Ответы:


215

Пробовал много вещей в отношении прокрутки, но приведенный ниже код дал лучшие результаты.

Это будет прокручиваться, пока элемент не будет виден:

WebElement element = driver.findElement(By.id("id_of_element"));
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", element);
Thread.sleep(500); 

//do anything you want with the element

6
Это отличное решение для случая, когда position: fixedна вашей странице есть элемент, который скрывает элемент, на который Selenium хочет щелкнуть. Довольно часто эти фиксированные элементы располагаются внизу, поэтому настройка scrollIntoView(true)перемещает их в верхнюю часть области просмотра.
Mandible79

3
Основанный на новейшей версии селена (2.53), теперь это отличное вспомогательное решение. Селен не всегда прокручивает элемент в поле зрения, так что это определенно пригодится.
Зойдберг

20
Передайте , trueчтобы , scrollIntoViewесли объект вы прокрутки находится под где вы сейчас находитесь, falseесли объект вы прокрутки выше , где вы сейчас находитесь. Мне было трудно понять это.
Большие деньги

2
Зачем тебе нить спать? executeScript должен быть синхронным
riccardo.tasso

1
@ riccardo.tasso, возможно, был реализован режим сна, чтобы справиться с неизвестным целевого приложения. Если он имеет динамическую прокрутку, или одностраничное приложение, которое загружает следующий бит страницы после прокрутки, среди других возможностей. Исходя из опыта, Selenium часто ломал сайт моей компании, потому что автоматизированное действие происходило быстрее, чем мог завершить Javascript, и, таким образом, передавало неполную модель данных. В некоторых местах это может показаться ошибкой, но мне сказали: «Ни один человек не может вызвать такой сценарий, поэтому это не настоящая ошибка». Такова жизнь.
Солонотикс

157

Вы можете использовать org.openqa.selenium.interactions.Actionsкласс, чтобы перейти к элементу.

Ява:

WebElement element = driver.findElement(By.id("my-id"));
Actions actions = new Actions(driver);
actions.moveToElement(element);
actions.perform();

Python:

from selenium.webdriver.common.action_chains import ActionChains
ActionChains(driver).move_to_element(driver.sl.find_element_by_id('my-id')).perform()

7
Будет ли это работать, если WebElement нет в View Port?
virusrocks

9
@Dominik: Как Selenium переместит мышь к элементу, который находится за пределами экрана? Ясно, что он должен сначала прокрутить элемент в поле зрения, а затем навести на него мышь. Я проверял это. Этот код работает на Firefox Webdriver 2.48, но есть ошибка: если у вас есть iframe на странице, прокрутка не работает правильно в iframe, в то время как element.LocationOnScreenOnceScrolledIntoView прокручивает правильно. (Хотя в документации сказано, что эта команда возвращает только местоположение, она также прокручивается!)
Elmue

8
Документы по адресу seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/… теперь четко заявляют "Перемещает мышь к центру элемента. Элемент прокручивается в поле зрения, и его местоположение вычисляется с использованием getBoundingClientRect «.
Джордж Пантазес

5
Приведенный выше код является «официальным способом», поэтому Java Selenium хочет, чтобы вы прокручивали элемент в область просмотра, однако после многих попыток реализация JS показалась мне более надежной. Этот метод в частности.
Кендзи Мива

2
Не работал для меня: - | Вместо этого использовал stackoverflow.com/a/23902068/661414 .
Лейкипп

28
JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("javascript:window.scrollBy(250,350)");

Вы можете попробовать это.


1
Спасибо. Мне нужно было использовать этот метод в случае, когда автопрокрутка Selenium заставляла другой элемент скрывать элемент, на котором мне нужно было щелкнуть. Мне удалось прокрутить произвольную сумму, чтобы сделать элемент видимым в области просмотра, не будучи скрытым.
Даниэль Ричнак

Это будет работать только в FIrefox, Chrome и IE, не поддерживают этот метод
virusrocks

Вот почему вы используете js.ExecuteScript("arguments[0].scrollIntoView(true);" + "window.scrollBy(0,-100);", e);для IE и Firefox и js.ExecuteScript("arguments[0].scrollIntoViewIfNeeded(true);", e);для Chrome. Просто.
IamBatman

((JavascriptExecutor) driver).executeScript("javascript:window.scrollBy(0,250)");Это работало в Chrome. И единственное решение, которое действительно сработало для меня. Та же ситуация, что и у первого комментатора, у меня был фиксированный элемент внизу, который затемнял тот элемент, который мне нужно было щелкнуть.
серебро


15

Если вы хотите прокрутить окно Firefox с помощью веб-драйвера Selenium, одним из способов является использование JavaScript в коде Java. Код JavaScript для прокрутки вниз (до нижней части веб-страницы) выглядит следующим образом:

JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("window.scrollTo(0, Math.max(document.documentElement.scrollHeight, document.body.scrollHeight, document.documentElement.clientHeight));");

10

Ориентация на любой элемент и отправка клавиш вниз (или вверх / влево / вправо), кажется, также работает. Я знаю, что это что-то вроде хака, но мне не очень нравится идея использовать JavaScript для решения проблемы с прокруткой.

Например:

WebElement.sendKeys(Keys.DOWN);

Это не меньший взлом, чем использование js, и это действительно самая простая вещь. Я обнаружил, что это в первую очередь проблема с IE, когда щелчок пытается прокрутить элемент в поле зрения, но не совсем это делает. Решение столь же элегантно, если использовать {PGUP}, если оно выполнено с правильным сценарием try / catch / loop.
jibbs

Вы спасли мой день! Спасибо
Йеско Р.

В моем случае сработала страница вниз. Это хороший хак (против всех хаков JS).
Акостадинов

Спасибо @DevDave! Эквивалент в C #:var elem = driver.FindElement(By.Id("element_id")); elem.SendKeys(Keys.PageDown);
Watth

9
webElement = driver.findElement(By.xpath("bla-bla-bla"));
((JavascriptExecutor)driver).executeScript("arguments[0].scrollIntoView();", webElement);

Для большего количества примеров, перейдите сюда . Все на русском, но Java-код кросс-культурный :)


Могу ли я понять, почему есть -1 для этого решения?
josephnvu

Потому что это работает только в Firefox. Другие браузеры не поддерживают этот метод.
Уэйн Аллен

Если кому-то понадобится перевод с русского на вышеупомянутый документ, будем рады помочь.
monkrus

8

В Selenium нам нужна помощь исполнителя JavaScript для прокрутки до элемента или прокрутки страницы:

je.executeScript("arguments[0].scrollIntoView(true);", element);

В приведенном выше утверждении elementявляется точным элементом, где нам нужно прокручивать. Я попробовал приведенный выше код, и он работал для меня.

У меня есть полный пост и видео об этом:

http://learn-automation.com/how-to-scroll-into-view-in-selenium-webdriver/


@Mukesh otwani приведенный выше код будет прокручиваться вниз, но как abt прокручиваться вверх без использования определенных в нем пикселей.
хан

6

Вы можете использовать этот фрагмент кода для прокрутки:

C #

var element = Driver.FindElement(By.Id("element-id"));
Actions actions = new Actions(Driver);
actions.MoveToElement(element).Perform();

Там у вас есть это


6

Это сработало для меня:

IWebElement element = driver.FindElements(getApplicationObject(currentObjectName, currentObjectType, currentObjectUniqueId))[0];
 ((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].scrollIntoView(true);", element);

5

Selenium 2 пытается прокрутить до элемента и затем нажать на него. Это потому, что Selenium 2 не будет взаимодействовать с элементом, если он не думает, что он видим.

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


19
Как это ответ на вопрос?
reinierpost

57
похоже, не работает для меня так. Я получаю ошибки «элемент не активен» для элементов, которые находятся вне поля зрения
DevDave

5
@DevDave У меня та же проблема, за исключением того, что в моем случае селен не выполняет щелчок по элементу и исключений нет. У меня не было проблемы раньше, и я не знаю, что вызвало это.
Зейнаб Аббасимазар

5
Неявная прокрутка варьируется между браузерами. У меня есть тест элемента во всплывающем меню на пол страницы вниз. В Ruby gem selenium_webdriver 2.43 я обнаружил, что браузер chromium 37 (и я считаю, что Internet Explorer) действительно прокручивает элемент меню и щелкает по нему. Но Firefox 32, кажется, не прокручивается вообще, а затем завершается ошибкой с «Элемент в настоящее время не виден и поэтому может не взаимодействовать с».
skierpage

9
Этот ответ неверен. В соответствии со спецификацией для Selenium 2.0 WebElement.click()требуется, чтобы элемент был виден, чтобы щелкнуть по нему. Он не будет прокручиваться от вашего имени.
Гили

5

Используйте драйвер для отправки ключей, таких как pagedownили, downarrowчтобы отобразить элемент. Я знаю, что это слишком простое решение и может быть применимо не во всех случаях.


1
Это нонсенс. Возможно, вам придется отправить дюжину страниц вниз на большую страницу. Это медленно и не надежно.
Эльмуэ

2
Да. Я согласен. Но я сказал: «Не применимо во всех случаях»
Ганеш С.

Поиск некоторых известных elementна просматриваемой странице и отправка PageDown element.SendKeys(Keys.PageDown);работали для меня.
Гокул

Я бы посоветовал использовать клавишу Alt, чтобы вы не прокручивали страницу и использовали предложение try / исключением (Python) для обработки ошибок, которые могут возникнуть при попытке отправить ключи некоторым элементам.
Алекс К.

4

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

Я использую Ruby, и для моего AUT мне пришлось обезьяна исправить метод click следующим образом;

class Element

      #
      # Alias the original click method to use later on
      #
      alias_method :base_click, :click

      # Override the base click method to scroll into view if the element is not visible
      # and then retry click
      #
      def click
        begin
          base_click
        rescue Selenium::WebDriver::Error::ElementNotVisibleError
          location_once_scrolled_into_view
          base_click
        end
      end

Метод location_once_scrolled_into_view является существующим методом в классе WebElement.

Я ценю, что вы, возможно, не используете Ruby, но он должен дать вам некоторые идеи.


Я объявил выше module Capybara :: module Node, и мне нужно было позвонить, native.location_once_scrolled_into_viewа не просто location_once_scrolled_into_view. Я также спас ::Selenium::WebDriver::Error::UnknownError, что я часто получаю в Firefox 44.0.2. Но я считаю, что это решение недостаточно гибкое и, в конечном счете, помещает <Element>.native.location_once_scrolled_into_viewвызовы в сам приемочный тест, а затем сразу же по мере page.execute_script('window.scrollByPages(-1)')необходимости.
Аль Чоу

У Ватира есть метод, Element#scroll_into_viewкоторый делегирует Селену location_once_scrolled_into_view. Но оба они ничем не отличаются от поведения по умолчанию в Selenium, поэтому элементы переполнения могут мешать тому, что мы пытаемся щелкнуть.
Акостадинов

3

Сценарий Ruby для прокрутки элемента в представлении приведен ниже.

$driver.execute_script("arguments[0].scrollIntoView(true);", element)
sleep(3)
element.click

2

Иногда я также сталкивался с проблемой прокрутки с помощью Selenium. Поэтому я использовал javaScriptExecuter для достижения этой цели.

Для прокрутки вниз:

WebDriver driver = new ChromeDriver();
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("window.scrollBy(0, 250)", "");

Или также

js.executeScript("scroll(0, 250);");

Для прокрутки вверх:

js.executeScript("window.scrollBy(0,-250)", "");

Или,

js.executeScript("scroll(0, -250);");

2

Если вы думаете, что другие ответы были слишком хакерскими, то это тоже самое, но в JavaScript не используется инъекция.

Когда кнопка находится за пределами экрана, она ломается и прокручивается к ней, поэтому повторите ее ... ¯ \ _ (ツ) _ / ¯

try
{
    element.Click();
}
catch {
    element.Click();
}

2

Это повторное решение с JavaScript, но с добавленным элементом ожидания.

В противном случае ElementNotVisibleExceptionможет появиться, если выполняется какое-либо действие над элементом.

this.executeJavaScriptFunction("arguments[0].scrollIntoView(true);", elementToBeViewable);
WebDriverWait wait = new WebDriverWait(getDriver(), 5);
wait.until(ExpectedConditions.visibilityOf(elementToBeViewable));

?? <- что это значит?
Чой

1

Я использовал этот способ для прокрутки элемента и нажмите:

List<WebElement> image = state.getDriver().findElements(By.xpath("//*[contains(@src,'image/plus_btn.jpg')]"));

for (WebElement clickimg : image)
{
  ((JavascriptExecutor) state.getDriver()).executeScript("arguments[0].scrollIntoView(false);", clickimg);
  clickimg.click();
}

В моем случае scrollIntoView(false)сработало, но scrollIntoView(true)нет. Либо может работать , это зависит от вашего сценария.
Ренна

Мой случай противоположен - истина работает, ложь не срабатывает, но только до щелчка. Он прокручивает правильно на ложь, и это то, что я предпочитаю, но по какой-то причине Selenium все еще не может увидеть его на предмет щелчка. Используя настоящие свитки, все слишком высоко, но, по крайней мере, это работает.
Билл Хилман

Пользовательские кнопки ввода вводят вместо щелчка, когда это возможно, - это позволяет избежать проблем, если браузер не имеет 100% -ного увеличения.
Zunair

1
def scrollToElement(element: WebElement) = {
  val location = element.getLocation
  driver.asInstanceOf[JavascriptExecutor].executeScript(s"window.scrollTo(${location.getX},${location.getY});")
}

1

Возможно, вы захотите посетить страницу веб-элементов прокрутки и веб- страницу Selenium WebDriver, используя Javascript :

public static void main(String[] args) throws Exception {

    // TODO Auto-generated method stub
    FirefoxDriver ff = new FirefoxDriver();
    ff.get("http://toolsqa.com");
    Thread.sleep(5000);
    ff.executeScript("document.getElementById('text-8').scrollIntoView(true);");
}

@AbhishekBedi Я помню, что он поддерживается и в Chrome. С какой-то конкретной проблемой вы могли столкнуться?
virusrocks

1

В большинстве случаев для прокрутки этот код будет работать.

WebElement element = driver.findElement(By.xpath("xpath_Of_Element"));                 
js.executeScript("arguments[0].click();",element);

1

ЯВА

Попробуйте прокрутки для элемента использовать x yположение, и использование JavascriptExecutorс этим аргументом: "window.scrollBy(x, y)".

Следующий импорт:

import org.openqa.selenium.WebElement;
import org.openqa.selenium.JavascriptExecutor;

Сначала вам нужно найти x yместоположение элемента.

//initialize element
WebElement element = driver.findElement(By.id("..."));

//get position
int x = element.getLocation().getX();
int y = element.getLocation().getY();

//scroll to x y 
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("window.scrollBy(" +x +", " +y +")");

1

Я не уверен, что вопрос по-прежнему актуален, но после обращения к документации scrollIntoView по адресу https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView .

Самое простое решение было бы

executor.executeScript("arguments[0].scrollIntoView({block: \"center\",inline: \"center\",behavior: \"smooth\"});",element);

Это прокручивает элемент в центр страницы.


0

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

Вот мое решение для Java:

public List<String> getBoundedRectangleOfElement(WebElement we)
{
    JavascriptExecutor je = (JavascriptExecutor) driver;
    List<String> bounds = (ArrayList<String>) je.executeScript(
            "var rect = arguments[0].getBoundingClientRect();" +
                    "return [ '' + parseInt(rect.left), '' + parseInt(rect.top), '' + parseInt(rect.width), '' + parseInt(rect.height) ]", we);
    System.out.println("top: " + bounds.get(1));
    return bounds;
}

И затем, чтобы прокрутить, вы называете это так:

public void scrollToElementAndCenterVertically(WebElement we)
{
    List<String> bounds = getBoundedRectangleOfElement(we);
    Long totalInnerPageHeight = getViewPortHeight(driver);
    JavascriptExecutor je = (JavascriptExecutor) driver;
    je.executeScript("window.scrollTo(0, " + (Integer.parseInt(bounds.get(1)) - (totalInnerPageHeight/2)) + ");");
    je.executeScript("arguments[0].style.outline = \"thick solid #0000FF\";", we);
}

Функция getViewPortHeight отсутствует ... Предполагается, что вы берете высоту целевого элемента
Shubham Jain

0

Вот как я это делаю с PHP webDriver для Selenium. Это работает для автономного сервера Selenium 2.39.0 + https://github.com/Element-34/php-webdriver + Firefox 25.0

$element=$session->welement("xpath", "//input[@value='my val']");
$element->click();
$element=$session->welement("xpath", "//input[@value='ma val2']");
$element->location_in_view(); // < -- this is the candy
$element->click();

Примечание: я использую настроенную версию PHP-веб-драйвера Element34. Но в ядре нет никаких изменений. Я просто использую свой «welement» вместо «element». Но это не влияет на рассматриваемый случай. Автор драйвера говорит, что «позволить почти всем вызовам API быть прямым преобразованием того, что определено в самом протоколе WebDriver». Так что у вас не должно быть проблем с другими языками программирования.

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

Примечание. Этот метод работает для элементов, которые можно просматривать, например, для ввода кнопки типа.

Посмотрите: http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/element/:id/location

Описание для JsonWireProtocol # предлагает использовать location + moveto, потому что location _in_view - это внутренний метод.


0

Что-то, что работало для меня, было использовать метод Browser.MoveMouseToElement для элемента в нижней части окна браузера. Чудесно это сработало в Internet Explorer, Firefox и Chrome.

Я выбрал это вместо техники внедрения JavaScript только потому, что это было менее хакерским.


Какой это язык программирования?
Акостадинов

0

Я проводил тестирование с компонентами ADF, и у вас должна быть отдельная команда для прокрутки, если используется отложенная загрузка. Если объект не загружен и вы пытаетесь найти его с помощью Selenium, Selenium выдаст исключение «элемент не найден».


0

Если ничего не работает, попробуйте это, прежде чем нажать:

public void mouseHoverJScript(WebElement HoverElement) {

    String mouseOverScript = "if(document.createEvent){var evObj = document.createEvent('MouseEvents');evObj.initEvent('mouseover', true, false); arguments[0].dispatchEvent(evObj);} else if(document.createEventObject) { arguments[0].fireEvent('onmouseover');}";
    ((JavascriptExecutor) driver).executeScript(mouseOverScript, HoverElement);
}

0

В Java мы можем прокрутить с помощью JavaScript, как в следующем коде:

driver.getEval("var elm = window.document.getElementById('scrollDiv'); if (elm.scrollHeight > elm.clientHeight){elm.scrollTop = elm.scrollHeight;}");

Вы можете присвоить желаемое значение переменной "elm.scrollTop".


0

Решение:

public void javascriptclick(String element)
{
    WebElement webElement = driver.findElement(By.xpath(element));
    JavascriptExecutor js = (JavascriptExecutor) driver;

    js.executeScript("arguments[0].click();", webElement);
    System.out.println("javascriptclick" + " " + element);
}

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.