首页 文章

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

提问于
浏览
148

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

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

30 回答

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

    你可能想试试这个 .

  • 10

    在滚动方面尝试过很多东西,但是下面的代码提供了更好的结果 .

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

    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
    
  • 0

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

    如果要使用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));");
    
  • 152

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

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

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

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

  • 3

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

  • 3

    根据我的经验,当页面上有多个可滚动部分时,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,但它应该给你一些想法 .

  • 2

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

    C#

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

    你有它

  • 1

    使用驱动程序发送诸如pagedown或downarrow键之类的键,以使元素进入视图 . 我知道这个解决方案太简单了,可能并不适用于所有情况 .

  • 0

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

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

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

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

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

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

  • 0

    这对我有用:

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

    有时我也遇到了使用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);");
    
  • 1

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

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

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

    我用这种方式滚动元素并单击:

    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();
    }
    
  • 117
    def scrollToElement(element: WebElement) = {
      val location = element.getLocation
      driver.asInstanceOf[JavascriptExecutor].executeScript(s"window.scrollTo(${location.getX},${location.getY});")
    }
    
  • 26

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

    $driver.execute_script("arguments[0].scrollIntoView(true);", element)
    sleep(3)
    element.click
    
  • 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);");
    }
    
  • 8

    对于一些简单的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;
        }
    }
    
  • 8

    Selenium的默认行为是滚动,因此该元素几乎不在视口顶部的视图中 . 此外,并非所有浏览器都具有完全相同的行为 . 这令人非常不满意 . 如果你像我一样录制浏览器测试的视频,你想要的是元素 to scroll into view and be vertically centered .

    这是我的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);
    }
    
  • 4

    以下是我使用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是一个内部方法 .

  • 1

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

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

  • 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);
    }
    
  • 0

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

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

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

    这段代码对我有用:

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

    我同意这里的每个人,他们说“Selenium有一个隐含的滚动选项” . 此外,如果您在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);
    }
    

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

  • 4

    随机点击页面:

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

    然后执行你想做的事情 .

相关问题