有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Selenium FirefoxDriver在动画出现时单击错误的链接

我正在使用Selenium 2.35,在尝试单击firefox中的某个元素时出现了一个不可预测的错误,如下所示:

new Actions(driver).moveToElement(element).click().perform();

我找到的元素是<;span>;元素,并将单击事件绑定到该元素。我偶尔遇到的问题是,当Firefox尝试单击该元素时,会出现未命中和单击完全不同的元素。如果我使用调试器浏览我的代码,问题就永远不会发生,这让我相信FirefoxDriver只是在浏览器上点击了错误的位置,这与时间问题有关。有动态加载的<;部门>;'在我找到元素并发送之前,我要单击该元素的页面上的。单击()命令。我相信这是我的问题的根源。我可以放一根线。sleep(500)可以确保它有足够的时间来完成动画制作和插入动态div,但这对我来说太草率了。有没有一种方法可以让我的FirefoxDriver等到屏幕上的元素移动完毕后再发送消息。单击()事件

此外,我还尝试只发送元素。单击(),但这似乎更容易失败

更新(9/5/13):

借助@MrTi的评论,我找到了以下解决方案:

private void jsClickOnElementById(String id)
{
    WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(By.id(id)));
    JavascriptExecutor js = (JavascriptExecutor)driver;
    StringBuilder sb = new StringBuilder();
    sb.append("var x = $('#" + id + "');");
    sb.append("x.click();");
    js.executeScript(sb.toString());
}

为了确保元素确实在页面上,我添加了初始的“wait”调用,然后使用JavascriptExecutor运行一些jquery并单击页面上的元素。这似乎对我的案子很有效。如果有人对这个解决方案的一些缺点有帮助,他们会非常感激,因为我对JavascriptExecutor类还比较陌生


共 (3) 个答案

  1. # 1 楼答案

    除了确保页面在预期条件下实际可见外,还可以通过处理页面上的动画(过渡)来解决这种情况

    通过执行以下操作,可以禁用页面上的所有动画,直到页面刷新

    (JavascriptExecutor)driver.executeScript("$('body').append('<style> * {transition: none!important;}</style>')")
    

    此外,如果您知道获得动画的特定元素,可以检查它是否已设置动画(JQuery animation selector)

    (Boolean)((JavascriptExecutor)driver).executeScript("return $("#ELEMENT_ID").is(":animated")")
    

    如果特定元素未知,则可以确定是否已完成所有动画:

    (Boolean)((JavascriptExecutor)driver).executeScript("return $(":animated").length == 0 ")
    
  2. # 2 楼答案

    不幸的是,在2018年(五年后),我可以确认这一点。selenium中的click()并不总是单击正确的元素。我仍然需要使用JavascriptExecutor向jquery施压,通过jquery $(selector).click()按ID单击一个元素,以自信地点击该元素

    不仅是由于滚动、动画或屏幕外的原因,Selenium无法找到元素,而且它的木偶内联DOM树包装器似乎与firefox的geckodriver不同步,无法动态加载元素(在本例中为表行)

  3. # 3 楼答案

    我相信正在发生的是,动态加载正在使选择器选择其他内容。如果您发布HTML(尤其是动态加载之前/之后),这将非常有助于编写更好的选择器

    但是,有几种方法可以等待加载完成

    第一个等待(Boolean)((JavascriptExecutor)driver).executeScript("return jQuery.active == 0")返回true的值。这将等待页面上的所有JQuery完成(这可能是导致动态加载的原因)。它很有用,但我建议你等别的东西

    第二个选项是等待动态加载的元素出现:

    wait.until(ExpectedConditions.presenceOfElementSelectedBy(...selector...));
    

    我喜欢这种方法,因为它会等你需要等多久就等多久,不再等了

    最后一个选项是编写一个选择器,该选择器将始终选择元素,即使正在进行其他操作。这可能是您的最佳选择,但也可能会遇到StaleElementReferenceExceptions