使用Selenium将元素滚动到视图中

时间:2010-08-03 22:54:12

标签: selenium scroll automated-tests

在Selenium 1.x或2.x中是否有任何方法可以滚动浏览器窗口,以便XPath识别的特定元素可以在浏览器中查看? Selenium中有一个焦点方法,但它似乎没有在FireFox中物理滚动视图。有没有人对如何做到这一点有任何建议?

我需要这个的原因是我正在测试页面上元素的点击。不幸的是,除非元素可见,否则事件似乎不起作用。我无法控制单击该元素时触发的代码,因此我无法对其进行调试或修改,因此,最简单的解决方案是将项目滚动到视图中。

36 个答案:

答案 0 :(得分:168)

在滚动方面尝试了很多方面,但下面的代码提供了更好的结果。

这将滚动直到元素在视图中:

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

答案 1 :(得分:125)

您可以使用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()

答案 2 :(得分:26)

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

您可能想尝试一下。

答案 3 :(得分:14)

如果您想使用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));");

答案 4 :(得分:8)

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

更多示例,go here。全部用俄语,但Java代码是跨文化的:)

答案 5 :(得分:8)

Selenium 2尝试滚动到该元素,然后单击它。这是因为Selenium 2不会与元素交互,除非它认为它是可见的。

向元素滚动隐式发生,因此您只需找到该项目然后使用它。

答案 6 :(得分:8)

定位任何元素,sending down keys(或上/左/右)似乎也有效。我知道这有点像黑客,但我并不是真的想用JavaScript来解决滚动问题。

答案 7 :(得分:4)

根据我的经验,当页面上有多个可滚动部分时,Selenium Webdriver不会自动滚动到点击元素(这很常见)。

我正在使用Ruby,而对于我的AUT,我不得不修改点击方法,如下所示;

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' method是WebElement类上的现有方法。

我认为你可能没有使用Ruby,但它应该给你一些想法。

答案 8 :(得分:4)

这对我有用:

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

答案 9 :(得分:4)

您可以使用此代码段滚动:

<强> C#

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

你有它

答案 10 :(得分:4)

使用驱动程序发送 pagedown downarrow 键等密钥,以便将元素置于视图中。我知道这个解决方案太简单了,可能并不适用于所有情况。

答案 11 :(得分:3)

在Selenium中,我们需要借助JavaScript执行器来滚动到元素或滚动页面:

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

在上面的语句中,element是我们需要滚动的确切元素。

我尝试了上面的代码,它对我有用。

我有一个完整的帖子和视频:

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

答案 12 :(得分:3)

用于将元素滚动到视图中的Ruby脚本如下所示。

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

答案 13 :(得分: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);");

答案 14 :(得分:2)

如果您认为其他答案太过苛刻,那么这个答案也是如此,但是没有涉及JavaScript注入。

当按钮离开屏幕时,它会断开并滚动到它,所以重试它...¯\ _ _(ツ)_ /¯

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

答案 15 :(得分:1)

您可以访问 Scroll Web elements and Web page- Selenium WebDriver using 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);");
}

答案 16 :(得分:1)

在大多数情况下,滚动此代码都可以使用。

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

答案 17 :(得分:1)

JAVA

尝试滚动到元素以利用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 +")");

答案 18 :(得分:1)

我不确定问题是否仍然存在,但是请参考https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView中的scrollIntoView文档。

最简单的解决方案是

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

这会将元素滚动到页面中心。

答案 19 :(得分:1)

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

答案 20 :(得分: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();
}

答案 21 :(得分: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);
}

答案 22 :(得分: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);
}

答案 23 :(得分:0)

这是一个使用JavaScript的重复解决方案,但添加了等待元素。

如果正在对元素执行某些操作,则可能会出现ElementNotVisibleException

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

答案 24 :(得分:0)

如果该对象传递无效:

await browser.executeScript( "arguments[0].scrollIntoView()", await browser.wait( until.elementLocated( By.xpath( "//div[@jscontroller='MC8mtf']" ) ), 1000 ) );

在Google页面上有一个滚动到麦克风按钮的演示。 javascript xpath使用chromedriver和selenium-webdriver找到了它。

start1()在狭窄的窗口中启动浏览器,麦克风按钮不显示。

start2()在狭窄的窗口中启动浏览器,然后滚动到麦克风按钮。

require('chromedriver');
const { Builder, 
        By, 
        Key, 
        until
      }                = require('selenium-webdriver');

async function start1()  {

  var browser = new Builder()
                    .forBrowser( 'chrome' )
                    .build();
  await browser
        .manage()
        .window()
        .setRect( { width: 80, 
                    height: 1040, 
                    x:-10, 
                    y:0} 
                );
  await browser.navigate().to( "https://www.google.com/" );
}

async function start2()  {

  var browser = new Builder()
                    .forBrowser( 'chrome' )
                    .build();
  await browser
        .manage()
        .window()
        .setRect( { width: 80, 
                    height: 1040, 
                    x:-10, 
                    y:0} 
                );
  await browser.navigate().to( "https://www.google.com/" );
  await browser.executeScript( "document.evaluate(\"//div[@jscontroller='MC8mtf']\", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.scrollIntoView(true);");
}

start1();
start2();

答案 25 :(得分:0)

对于C#中的OpenQA.Selenium:

WebDriver.ExecuteJavaScript("arguments[0].scrollIntoView({block: \"center\", inline: \"center\"});", Element);

WebDrivernew ChromeDriver(options)或相似的地方。

答案 26 :(得分:0)

Javascript

解决方案很简单:

const element = await driver.findElement(...)
await driver.executeScript("arguments[0].scrollIntoView(true);", element)
await driver.sleep(500);

答案 27 :(得分: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);
}

答案 28 :(得分:0)

此代码对我有用:

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

答案 29 :(得分:0)

在Java中,我们可以使用JavaScript滚动,如下面的代码所示:

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

您可以为“elm.scrollTop”变量指定所需的值。

答案 30 :(得分:0)

我一直在使用ADF组件进行测试,如果使用延迟加载,则必须有一个单独的滚动命令。如果未加载对象并且您尝试使用Selenium查找它,则Selenium将抛出元素未找到的异常。

答案 31 :(得分:0)

对于一些简单的UI,Selenium可以自动滚动到滚动条中的某个元素,但对于延迟加载的UI,仍然需要scrollToElement。

这是我使用JavascriptExecutor在Java中的实现。  您可以在Satix源代码中找到更多详细信息: http://www.binpress.com/app/satix-seleniumbased-automation-testing-in-xml/1958

public static void perform(WebDriver driver, String Element, String ElementBy, By by) throws Exception  {
    try{
        //long start_time = System.currentTimeMillis();         
        StringBuilder js = new StringBuilder();
        String browser = "firefox";

        if (ElementBy.equals("id")) {
            js.append("var b = document.getElementById(\""
                    + Element + "\");");
        } else if (ElementBy.equals("xpath")) {
            if (!"IE".equals(browser)) {
                js.append("var b = document.evaluate(\""
                        + Element
                        + "\", document, null, XPathResult.ANY_TYPE, null).iterateNext();");
            } else {
                throw new Exception("Action error: xpath is not supported in scrollToElement Action in IE");
            }
        } else if (ElementBy.equals("cssSelector")) {
            js.append("var b = document.querySelector(\""
                    + Element + "\");");
        } else {
            throw new Exception("Scroll Action error");
        }

        String getScrollHeightScript = js.toString()+ "var o = new Array(); o.push(b.scrollHeight); return o;";

        js.append("b.scrollTop = b.scrollTop + b.clientHeight;");
        js.append("var tmp = b.scrollTop + b.clientHeight;");
        js.append("var o = new Array(); o.push(tmp); return o;");

        int tries = 1;
        String scrollTop = "0";
        while (tries > 0){
        try{                
            String scrollHeight = ((JavascriptExecutor)driver).executeScript(getScrollHeightScript).toString();         
            if (scrollTop.equals(scrollHeight)) {
            break;
            } else if (driver.findElement(by).isDisplayed()) {
                break;
            }
            Object o = ((JavascriptExecutor)driver).executeScript(js.toString());
            scrollTop = o.toString();
            Thread.sleep(interval);
            tries ++;
        }catch(Exception e){
            throw new Exception("Action error:"
                    + " javascript execute error : " + e.getMessage() + ", javascript : " + js.toString());
            }       
        }           

    }catch (Exception e) {
        try {
                ScreenshotCapturerUtil.saveScreenShot(driver, CLASSNAME);
            } catch (IOException e1) {
            throw new Exception("Save screenshot error!", e1);
            }
        throw e;
    }
}

答案 32 :(得分:0)

对我有用的是在浏览器窗口底部的元素上使用Browser.MoveMouseToElement方法。奇迹般地,它在Internet Explorer,Firefox和Chrome中都有效。

我选择这个而不是JavaScript注入技术只是因为它感觉不那么笨拙。

答案 33 :(得分:0)

以下是我使用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的自定义版本。但核心没有任何变化。我只是使用我的“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是一种内部方法。

答案 34 :(得分:-2)

随机点击页面:

driver.findElement(By.id("ID of a web element present below")).click

然后执行你想做的事。

答案 35 :(得分:-2)

我同意这里的每个人,他们说&#34; Selenium有一个隐含的滚动选项&#34;。此外,如果您在Selenium 1中,现在您已将自己升级到Selenium 2并查找以前版本的命令,则可以使用以下命令:

Seleniumbackeddriver.

WebDriver driver = new FirefoxDriver();
public void setUp() throws Exception {

    String baseUrl = "http://www.google.co.in/";
    selenium = new WebDriverBackedSelenium(driver, baseUrl);
}

您可以使用这些并使用两个版本的命令。