При выполнении действий с элементами, Selenium старается автоматически выполнить прокрутку страницы так, чтобы элемент стал видимым в окне браузера. Однако в некоторых случаях, конечный результат может быть не точным, особенно часто это встречается на динамически меняющихся страницах, использующих JavaScript и Ajax. В итоге некоторые действия с WebElement-ами могут выполняться неудачно из-за того, что элемент не находился в области видимости браузера.
Частным случаем для применения прокрутки страницы может быть следующий сценарий:
- Выполняете нажатие на элемент.
- Selenium прокручивает страницу к элементу (чаще всего элемент при этом оказывается в самом верху экрана).
- После этого элемент перекрывается динамически выводимой на экране панелью инструментов или другим элементом.
- Selenium пытается выполнить нажатие, которое, естественно, не происходит.
Если в веб-приложении содержатся подобные панели, выводимые поверх остальных веб-элементов, то оптимальным решением будет выполнить прокрутку страницы самостоятельно перед выполнением каких-либо действий. Если Вы правильно проскроллите страницу к элементу и расположите его в области видимости, то Selenium, выполняя заданное действие, уже не будет ничего скроллить:
- Самостоятельно прокручиваете страницу к элементу (возможно со смещением, в случае ожидания вывода перекрывающих панелей).
- Выполняете нажатие на элемент.
- Selenium успешно выполняет нажатие (без прокрутки страницы).
Не редки случаи, когда нужно проскроллить страницу просто так, без выполнения каких-либо действий над элементами, например, для того чтобы сделать скриншот части страницы.
Теперь, когда понятно для чего это можно использовать, рассмотрим, как это можно выполнить. К сожалению, WebDriver не предоставляет никаких явных функций для работы с прокруткой. Тем не менее, есть несколько способов, с помощью которых можно расположить веб-элемент в области видимости окна браузера:
1. Попытаться получить координаты объекта:
((Locatable)webElement).getLocationOnScreenOnceScrolledIntoView();
Вызов метода getLocationOnScreenOnceScrolledIntoView()
автоматически вызовет прокрутку страницы к элементу.
2. Проскроллить страницу к элементу с помощью Javascript:
((JavascriptExecutor)driver).executeScript("arguments[0].scrollIntoView();" ,webElement);
3. Проскроллить страницу из текущего положения с заданным смещением:
((JavascriptExecutor)driver).executeScript("window.scrollBy(" + x + "," + y + ");");
4. Проскроллить страницу с заданным смещением от элемента:
public void scrollWithOffset(WebElement webElement, int x, int y) { String code = "window.scroll(" + (webElement.getLocation().x + x) + "," + (webElement.getLocation().y + y) + ");"; ((JavascriptExecutor)driver).executeScript(code, webElement, x, y); }
I have to confess that i typically get bored learning the entire thing but i believe you can add some value. Bravo !
Татьяна, спасибо за статью, у меня как раз была проблема, что скролировал до нужных мне элементов, благодаря вам проблему решил. Интересные сочетания, автоматизация тестирования и сео 🙂
Чтобы прокрутить страницу до конца, динамически подргужаемую ajax во время прокрутки, можно использовать следующий код:
public void scroll_page_to_the_bottom() {
((JavascriptExecutor)getDriver()).executeScript(«function f() {» +
» window.scrollTo(0, document.body.scrollHeight);» +
» setTimeout(function(){» +
» if ($(window).scrollTop() != $(document).height()-$(window).height()){» +
» f();» +
» }» +
» }» +
» , 500);» +
» }» +
«f()»);
waitABit(5000);
}
Если же страница целиком уже загружена, то просто:
((JavascriptExecutor)getDriver()).executeScript(«window.scrollTo(0, document.body.scrollHeight);»);
String script = «function findPos(obj) {var curtop = 0;if (obj.offsetParent) {do {curtop += obj.offsetTop;} while (obj = obj.offsetParent);return [curtop];}}»
+ «//Get object»
+ «var SupportDiv = document.getElementById(‘domainform_id_listSelectItemsText_14’);»
+ «//Scroll to location of SupportDiv on load» + «window.scroll(0,findPos(SupportDiv));»;
script = «jq(‘#domainform_id_DownList’).scrollTop(jq(
‘#domainform_id_listSelectItemsText_14’).position().top)»;
((JavascriptExecutor) driver).executeScript(script);