即使在满足 ExpectedConditions.elementToBeClickable 和 visibilityOfElementLocated 条件后,也会抛出元素不可交互异常

Element not interactable exception is thrown even after ExpectedConditions.elementToBeClickable and visibilityOfElementLocated conditions fulfilled

在我基于 Java 的 Selenium 项目中,我使用以下方法在单击它之前等待元素可用

public void clickVisible(By element){
    wait.until(ExpectedConditions.elementToBeClickable(element));
    wait.until(ExpectedConditions.visibilityOfElementLocated(element));
    driver.findElement(element).click();
}

一般来说,在 99.9% 的情况下它都可以正常工作。但是有时,在某些特定元素上它仍然会抛出异常

org.openqa.selenium.ElementNotInteractableException: element not interactable

因此,即使在 Selenium 检测到该元素可点击和可见之后,我也必须在单击该元素之前添加更多延迟,或者等待其他元素可见性,然后才验证该元素可见性,然后单击就可以了。
这实际上意味着 Selenium WebDriverWait ExpectedConditions.elementToBeClickableExpectedConditions.visibilityOfElementLocated 不是 100% 可靠的。
这里处理 ElementNotInteractableException or this 的问题的所有答案都建议使用 ExpectedConditions.visibilityOfElementLocated WebDriver 等待,但同样,它仍然不是 100% 可靠。
所以我的问题是:是否有一些更可靠的方法来确保元素的可点击性?

我同意这很烦人。我用过几次的一个“解决方案”是改用动作,在你的代码中它会是这样的

public void clickVisible(By element){
    wait.until(ExpectedConditions.elementToBeClickable(element));
    wait.until(ExpectedConditions.visibilityOfElementLocated(element));
    final Actions actions = new Actions(driver);
    actions.moveToElement(driver.findElement(element)).click().perform();
}

它点击元素的位置,不考虑它是否可交互。也许会有帮助。

在使用 selenium 进行测试时,我经常遇到内置等待时间不够用的问题,我花了很多时间来研究原因,并且有几种方法可以尝试解决这个问题并进行测试稳定的。但首先,让我指出,等待一个元素成为 clickable 与 Selenium 是 最强的条件 一个人可以使用,换句话说,它将导致最长的等待欧共体

所有功能 from the docs 甚至是等待元素成为 visibleenabled。 (如果您查看源代码,我想我没有记错,visible 表示该元素没有属性 value='hidden',而 enabled 表示它没有任何属性叫 disabled.) 无论如何,这一切都是为了说你的行

    wait.until(ExpectedConditions.elementToBeClickable(element));

已经检查了可见性,因此后面的行是多余的。

现在回答你的实际问题。我通常通过以下方式之一解决这样的问题。主要的想法是在继续测试之前弄清楚您实际上需要等待什么,显然,要适当地等待。

  1. 由于它抛出 ElementNotInteractableException,我认为您必须尝试找出发生这种情况时应用程序中实际发生的情况。尝试在这一步截取屏幕截图,and/or 记录全部或部分页面源代码以弄清楚:运行 代码工作的地方和失败的地方有什么不同?是否有一个元素掩盖了你的目标?如果是这样,也许你可以执行一些 javascript 来摆脱那个元素。或者,您可以等待该元素不可见。或者,您可能会在页面源代码中找到一些其他条件,您可以等待这些条件在您的测试中考虑到这种明显的边缘情况。

  2. 如果上述方法不起作用,请查看您应用中的网络流量,再次寻找测试通过和失败之间的差异。也许有些事情你可以等待;某些请求以某种状态发出或完成?

  3. 如果以上都不管用,我就开始进入“认输”阶段。看看是否有任何合理短的硬编码等待,也许结合其他技术,可以使您的测试可靠地通过。

  4. 如果上面的方法不起作用,实施重试逻辑,表面上只是针对这个单一测试或失败,以减少它影响您的整体的机会 运行

  5. 最后,如果我不能使任何一个工作,测试是无法忍受的不稳定,它需要 运行,只是 运行 手动测试。有些工作流程几乎或实际上不可能使用 Selenium 实现自动化,并且在某个时候,编写和维护代码所花费的精力超过了 运行 手动测试所需的精力。您还必须接受 some flakiness 是大量 Selenium 测试 运行ning 所固有的(无论如何对于大多数应用程序),但是当然这不应该阻止您显然努力编写最可靠的测试。

ElementNotInteractableException 表示元素出现在 HTML DOM 上,但它不处于可以交互的状态。 ElementNotInteractableException 的发生是由于众多原因之一:

另一个 WebElement 可能会覆盖我们想要的 WebElement。 Web 元素的覆盖可以是临时的;如果是这样,那么我们可以使用 WebDriverWait

遵循以下策略
new WebDriverWait(driver, 10).until(ExpectedConditions
.invisibilityOfElementLocated(By.xpath("element_xpath")));
driver.findElement(By.xpath("element_xpath"))
.click();

new WebDriverWait(driver,10).until(ExpectedConditions
.elementToBeClicable("WebElement xpath")).click();

如果所需的网络元素被另一个永久覆盖 web 元素然后我们用
投射 WebDriver 实例 JavaScriptExecutor 使用它

((JavaScriptExecutor)driver).executeScript("argument[0]
.click();",element)