Answers:
关于滚动已经尝试了很多事情,但是下面的代码提供了更好的结果。
这将滚动直到该元素出现在视图中:
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
position: fixed
的页面上可能有一个元素并且遮盖了Selenium要单击的元素时,这是一个很好的解决方案。这些固定元素通常位于底部,因此设置可以scrollIntoView(true)
将其很好地移动到视口的顶部。
true
给;scrollIntoView
如果要滚动到的对象位于当前位置false
上方,则传递给。我很难弄清楚这一点。
您可以使用org.openqa.selenium.interactions.Actions
该类移动到元素。
Java:
WebElement element = driver.findElement(By.id("my-id"));
Actions actions = new Actions(driver);
actions.moveToElement(element);
actions.perform();
蟒蛇:
from selenium.webdriver.common.action_chains import ActionChains
ActionChains(driver).move_to_element(driver.sl.find_element_by_id('my-id')).perform()
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("javascript:window.scrollBy(250,350)");
您可能想尝试一下。
js.ExecuteScript("arguments[0].scrollIntoView(true);" + "window.scrollBy(0,-100);", e);
用于IE,Firefox和js.ExecuteScript("arguments[0].scrollIntoViewIfNeeded(true);", e);
Chrome。简单。
((JavascriptExecutor) driver).executeScript("javascript:window.scrollBy(0,250)");
这在Chrome中有效。唯一对我有效的解决方案。与第一个评论者相同,我在底部有一个固定的元素,该元素使我需要单击的元素变得晦涩。
如果要使用Selenium Webdriver在Firefox窗口上滚动,一种方法是在Java代码中使用JavaScript。向下滚动到页面底部的JavaScript代码如下:
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("window.scrollTo(0, Math.max(document.documentElement.scrollHeight, document.body.scrollHeight, document.documentElement.clientHeight));");
定位任何元素并发送向下键(或向上/向左/向右)似乎也可以。我知道这有点麻烦,但是我也不是很想使用JavaScript解决滚动问题。
例如:
WebElement.sendKeys(Keys.DOWN);
var elem = driver.FindElement(By.Id("element_id")); elem.SendKeys(Keys.PageDown);
在Selenium中,我们需要借助JavaScript执行程序来滚动到某个元素或滚动页面:
je.executeScript("arguments[0].scrollIntoView(true);", element);
在上面的语句中,element
是我们需要滚动的确切元素。我尝试了上面的代码,它为我工作。
我对此有完整的帖子和视频:
http://learn-automation.com/how-to-scroll-into-view-in-selenium-webdriver/
您可以使用以下代码片段进行滚动:
C#
var element = Driver.FindElement(By.Id("element-id"));
Actions actions = new Actions(Driver);
actions.MoveToElement(element).Perform();
你有它
Selenium 2尝试滚动到该元素,然后单击它。这是因为Selenium 2不会与元素交互,除非它认为它是可见的。
滚动到该元素会隐式发生,因此您只需要找到该项目然后使用它即可。
WebElement.click()
元素必须可见才能单击。它不会代表您滚动。
使用驱动程序发送键,例如pagedown或downarrow键,以使该元素可见。我知道这太简单了,可能无法在所有情况下都适用。
element
在可见页面中找到一些已知内容并发送PageDown element.SendKeys(Keys.PageDown);
对我有用。
根据我的经验,当页面上有多个可滚动部分时,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
委托给Selenium的方法location_once_scrolled_into_view
。但是两者都与Seleniums的默认行为没有什么不同,因此溢出元素仍然会阻碍我们尝试单击的任何内容。
用于将元素滚动到视图中的Ruby脚本如下。
$driver.execute_script("arguments[0].scrollIntoView(true);", element)
sleep(3)
element.click
有时我还遇到了使用硒滚动的问题。因此,我使用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);");
如果您认为其他答案太过分了,那么这个答案也不错,但是不涉及JavaScript注入。
当按钮不在屏幕上时,它会断裂并滚动到它,因此请重试...。
try
{
element.Click();
}
catch {
element.Click();
}
这是JavaScript的重复解决方案,但增加了waiting元素。
否则,ElementNotVisibleException
如果对元素执行了某些操作,则可能会出现。
this.executeJavaScriptFunction("arguments[0].scrollIntoView(true);", elementToBeViewable);
WebDriverWait wait = new WebDriverWait(getDriver(), 5);
wait.until(ExpectedConditions.visibilityOf(elementToBeViewable));
我已经使用这种方式滚动元素并单击:
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();
}
def scrollToElement(element: WebElement) = {
val location = element.getLocation
driver.asInstanceOf[JavascriptExecutor].executeScript(s"window.scrollTo(${location.getX},${location.getY});")
}
您可能要访问页面 使用Javascript Scroll Web元素页面和Selenium WebDriver页面:
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);");
}
爪哇
尝试滚动到元素利用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 +")");
我不确定问题是否仍然存在,但是请参阅https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView中的 scrollIntoView文档。
最简单的解决方案是
executor.executeScript("arguments[0].scrollIntoView({block: \"center\",inline: \"center\",behavior: \"smooth\"});",element);
这会将元素滚动到页面中心。
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);
}
这是我使用PHP webDriver for 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();
注意:我使用Element34 PHP-webdriver的自定义版本。但是核心没有任何变化。我只是使用我的“元素”而不是“元素”。但这对所涉案件没有影响。该驱动程序作者说:“允许几乎所有API调用都是WebDriver协议本身定义的直接转换。” 因此,使用其他编程语言应该没有问题。
在我的设置中,仅单击不起作用。它将进行滚动而不是单击,因此我不得不单击两次而不调用“ location_in_view()”。
注意:此方法适用于可查看的元素,例如类型按钮的输入。
看一眼: http //code.google.com/p/selenium/wiki/JsonWireProtocol#/session/ sessionId/element/ id/location
JsonWireProtocol#的描述建议使用location + moveto,因为location _in_view是内部方法。
对我有用的是在浏览器窗口底部的元素上使用Browser.MoveMouseToElement方法。奇迹般地,它可以在Internet Explorer,Firefox和Chrome中使用。
我选择它而不是JavaScript注入技术,只是因为它的hacky少了。
如果没有任何效果,请在单击之前尝试以下操作:
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);
}
这段代码为我工作:
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("javascript:window.scrollBy(250, 350)");