Selenium 单击一个元素 'successfully',但实际上并没有单击它

Selenium clicks an element 'successfully', yet, it is not actually clicked

我有一个点击按钮的方法,但是,当它是 运行 时,selenium returns 结果点击成功,而实际上,按钮并没有被点击。如果我 运行 多次测试,偶尔会按预期点击。我将我的测试框架设置为隐式等待大约 15 秒,我已经设置了一个显式等待这个元素,但仍然看到同样的问题。当我执行 <element>.isDisplayed() 时,总能找到该元素。我将 .click 放在一个 while 循环中以单击它几次,这在大多数情况下都有效,但是,有时测试仍然会失败。是否可以使用 if 语句在单击按钮之前检查元素是否实际显示?

我试过:

if(!element.isDisplayed){
    element.click
}

这是我遇到问题的按钮:

<button class="notkoButton listNew">
<div class="l6e iconAdd">New List</div>
</button>

这是我的方法:

public marketing_lists_page navigateToNewListPage() throws Throwable {
    try {
        int x = 0;
        while(x < 5) {
            newListBtn.click();
            x++;
        }
       //newListPageHeader.isDisplayed();
    } catch (NoSuchElementException e){
        logs.errorDetails("Could not navigate to New List Page");
        Assert.fail();
    }
    return this;
}

你说你已经尝试过显式等待,但听起来你所要求的最好通过 fluentWait(这是一种显式等待)来完成:

public WebElement fluentWait(final By locator) {
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
        .withTimeout(30, TimeUnit.SECONDS)
        .pollingEvery(5, TimeUnit.SECONDS)
        .ignoring(NoSuchElementException.class);

WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
    public WebElement apply(WebDriver driver) {
        return driver.findElement(locator);
    }
});

return  foo; };;

此处的 WebElement 将是您尝试单击的按钮。 FluentWait 的妙处在于,如果找到该元素,则会返回该元素本身。来自文档:

Wait 接口的实现,可以动态配置其超时和轮询间隔。每个 FluentWait 实例定义等待条件的最长时间,以及检查条件的频率。此外,用户可以配置等待以在等待时忽略特定类型的异常,例如在页面上搜索元素时出现 NoSuchElementExceptions。

要使用它,只需执行以下操作:

WebElement newListBtn = fluentWait(By.id("button"));

也试试:

Driver.SwitchTo().DefaultContent();

点击之前以防出现框架问题。

尝试滚动到该元素,然后再单击它。这主要发生在您在 chrome 上测试时。您可以使用 JavaScriptExecutor 来滚动。

像这样:

JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("window.scrollTo(0," + element.getLocation().Y + ")"); 

该元素最初似乎未启用或不可点击。为了回答您的问题,是的,您可以使用明确的等待并等待元素可点击:

WebDriverWait wait = new WebDriverWait(driver, timeOut);
wait.until(ExpectedConditions.elementToBeClickable(locator));

试试这个,单击使用 javascript 并根据您的方便随时更改元素的定位:-

WebElement element= driver.findElement(By.xpath("YOUR XPATH"));

JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", element);

希望对您有所帮助:)

Selenium 缺少 GUI "dynamism"。 我建议您在点击后刷新页面。

告诉我发生了什么事。

我遇到了完全相同的问题,但只是在我将 selenium 库从 2.45 更新到 2.48.2 之后。 "Click" 方法调用永远不会失败,这意味着该元素总是由驱动程序找到,我 认为 它没有做的可能是单击正确的位置。我的测试在高分辨率屏幕上会 运行 正常,但在低分辨率屏幕上有时会通过(但大多数情况下由于点击问题而失败)。我尝试了很多方法,但最终对我有用的是 ZOOM。

在 运行 测试之前,我调用了以下方法,现在 "click" 方法在低分辨率屏幕上按预期工作。

public void zoomOut () {
        WebElement html = driver.findElement(By.tagName("html"));
        html.sendKeys(Keys.chord(Keys.CONTROL, Keys.SUBTRACT));
}

我在使用 JavaScript WebDriver 时遇到了表面上看起来类似的问题 - click() promise 已成功解决,但什么也没发生。

在我的例子中,它与页面上无效的图像 src 属性有关(与我点击的按钮无关)。无论出于何种原因,修复图像 link 解决了问题!

我知道 OP 使用的是 Java 而不是 JS,但我自己的搜索将我带到这里,所以其他使用 JavaScript 的人可能也会以同样的方式出现。

我也注意到点击与 Selenium 不一致,这在某种程度上似乎是一个已知问题:

https://github.com/SeleniumHQ/selenium/issues/4075

在我的例子中,几乎没有办法让元素不准备好。我等了一会儿,但更重要的是我的测试用例正在填写一个非常大的表格,要单击以启动 drop-down 的按钮非常简单,我可以看到它在将近半分钟前加载我的测试与它交互,但时不时地它仍然会失败。我写了一个愚蠢的 while 循环,每 100 毫秒点击一次,直到出现预期的下拉菜单。

这都是猜测,但根据个人观察和该线程中其他人的一些评论 - 例如一位用户提到他们在 运行 并行测试时注意到更多类似的问题,似乎表明有可能似乎是一个错过的事件,也许这是由于它的架构引入的滞后。具体来说,我将其与 Cypress 如何在没有中间服务器的情况下直接向浏览器提供本机命令进行比较。