【问题标题】:Element is clickable when ran in debug mode, but ran normally throws ElementClickInterceptedException在调试模式下运行时元素是可点击的,但正常运行时会抛出 ElementClickInterceptedException
【发布时间】:2019-11-11 02:50:06
【问题描述】:

我正在尝试进行网络自动化。 我正在定义一个弹出菜单,其中包含一个分别用 xpath 或 css 定义的按钮作为

  • XPath:-->://button[contains(text(), 'Open Door')

  • CSS:-->div.device-item.content.view-content > div.detail > div > button.btn.btn-primary.ng-star-inserted

虽然一切都很好,但它会抛出

org.openqa.selenium.ElementClickInterceptedException: element click intercepted:

当我一次调试测试时,它 单击按钮成功运行,没有任何 问题。但是当我运行测试时,它失败了。我希望这不是等待问题,因为我们申请检查等待 按钮的存在并验证它是否存在且可点击。

我相信很多人会建议使用 JavaScriptExecutor 方法,但是我们的框架存在一个问题,即会将任何 Web 元素作为名为 "Element" 的自定义对象返回,这既不是 Web Element 也不是它的子类,而是扩展了 Object 并实现了一个名为 IElement 的接口,所以 我们不能使用 JavaScriptExecutor 方法,因为它需要 Web Element 形式的按钮,我们想点击。

【问题讨论】:

  • 你可以把 xpath / css 传递给 JavaScriptExecutor 并在 js 中选择它。
  • @pguardiario 你有什么可以推荐的例子吗?我检查了selenium.dev/selenium/docs/api/java/index.html 的 JavaScriptExecutor 页面,但找不到任何采用 xpath 或 css 的方法。
  • 您使用哪种语言的 selenium 库进行脚本开发? (以便我们可以提供示例 JS 执行器)并且您的应用程序中是否有多个带有 Open Door 按钮的选项卡?
  • 你是在 Internet Explorer 浏览器上运行这个吗?
  • 我在 Chrome 浏览器上运行。我正在使用 Java 绑定。没有其他带有“开门”按钮的选项卡。只有一个选项卡和一个 DDO 门实体,单击它会打开一个菜单,其中包含“开门”和“详细信息”菜单项。

标签: java selenium selenium-webdriver webdriver webdriverwait


【解决方案1】:

如果它在调试中工作,则意味着覆盖自动消失。你可以等它消失

WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.cssSelector("[id^='device-card']")));

在任何情况下,您都可以等待按钮可点击

button = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[contains(text(), 'Open Door')")));
button.click();

【讨论】:

  • 我尝试了这种方法,它仍然给我带来了同样的错误。 org.openqa.selenium.ElementClickInterceptedException:元素点击被拦截:元素 在点 (487, 656) 不可点击。其他元素会收到点击:
    ...
    (会话信息:chrome=78.0.3904.87)构建信息:版本:'3.141.59',修订:'e82be7d358',时间:'2018-11-14T08:17:03' 我给了 50 秒的等待时间。
  • ``` private void buttonClick(String action){ WebDriverWait wait = new WebDriverWait(WebDriverSingleton.getWebDriver(), 50); if(action.equalsIgnoreCase("OPEN")) { wait.until(ExpectedConditions.elementToBeClickable(By.xpath(OPEN_DOOR_XPATH))); openDoorBtn.click(); }else if(action.equalsIgnoreCase("CLOSE")) { wait.until(ExpectedConditions.elementToBeClickable(By.xpath(CLOSE_DOOR_XPATH))); closeDoorBtn.click(); } } ```
  • @PraNuta 您是否尝试等待其他元素消失?您还应该单击从wait.until 返回的元素,查看更新的答案。
  • 让我明天更仔细地尝试一下。
【解决方案2】:

它看起来像:

driver.executeScript("document.querySelector('button.btn').click()")

只需调整css

【讨论】:

  • 让我试着告诉你。谢谢。
  • 我也尝试过这种方法。我收到编译时错误,说 driver.executeScript(String) 没有解决。似乎驱动对象没有 executeScript(String) 方法。
  • 您可能需要针对 Java 或您的框架调整该部分
【解决方案3】:

您需要注意以下几点:

  • XPath //button[contains(text(), 'Open Door'):这个xpath 可以进一步优化成以下两种格式:
    • //button[text()='Open Door']
    • //button[contains(., 'Open Door')]
  • CSSdiv.device-item.content.view-content > div.detail > div > button.btn.btn-primary.ng-star-inserted 看起来不错,但我坚信 button.btn.btn-primary.ng-star-inserted 也可以。
  • “...在调试模式下成功执行...”:因为浏览器客户端有足够的时间来解决网页动态并且所需的 WebElement 有足够的时间来获得 交互式 .
  • “...我们充分检查等待按钮的存在并验证它是否存在并且可点击...”:这是一个神话:
    • presenceOfElementLocated():是期望检查一个元素是否存在于页面的 DOM 上。这并不一定意味着该元素是可见的。
  • 其中:
  • 由于您的用例是在元素上调用 click(),因此您需要将 ExpectedConditions 用作 elementToBeClickable()
  • 例子:

    new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("css_element"))).click();
    

您可以在What is the most efficient way to wait for a page element (xpath) to show up in Selenium Webdriver?找到详细讨论


更新

由于您仍然看到错误 ...ElementClickInterceptedException: element click intercepted...,您可以添加一个额外的步骤来为 诱导 WebDriverWait 隐形,您可以使用以下任一选项:

  • invisibilityOf(WebElement element):

    new WebDriverWait(driver, 20).until(ExpectedConditions.invisibilityOf(overlapping_webelement));
    new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("css_clickable_element"))).click();
    
  • invisibilityOfElementLocated(By locator):

    new WebDriverWait(driver, 20).until(ExpectedConditions.invisibilityOfElementLocated(By.cssSelector("css_overlapping_element")));
    new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("css_clickable_element"))).click();
    

您可以在Selenium invisibilityOf(element) method throwing NoSuchElementException + WebDriverWait.ignoring(NoSuchElementException.class) is not working找到相关的详细讨论

【讨论】:

  • 感谢您的精彩解释。几件事。该元素也是可见且可点击的。当我打印到控制台时。我能够打印出它的按钮文本。 OpenDoor Button is present=true; OpenDoor Button Text-Open Door 唯一的问题是 ElementClickInterceptedException: element click intercepted。如何克服“点击拦截”问题。
  • 更新了答案。请让我知道状态。
  • 当然。会尝试让你知道 DebanjanB
  • 从异常堆栈跟踪...org.openqa.selenium.ElementClickInterceptedException: element click intercepted: Element <div class="device-name" mattooltipposition="above" style="touch-action: none; user-select: none; -webkit-user-drag: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);" aria-describedby="cdk-describedby-message-13" cdk-describedby-host="">...</div> is not clickable at point (487, 623). Other element would receive the click: <div class="group-btn-container">...</div>我认为最后一个(div.group-btn-container)是一个容器的重叠元素。
  • 然后我用... new WebDriverWait(driver, 30).until(ExpectedConditions.invisibilityOfElementLocated(By.cssSelector("div.group-btn-container"))); new WebDriverWait(driver, 5).until(ExpectedConditions.elementToBeClickable(By.cssSelector("div.device-item.content.view-content > div.detail > div > button.btn.btn-primary.ng-star-inserted"))).click(); closeDoorBtn.click(); 现在,我得到了这个异常。 TimeoutException:预期条件失败:等待元素不再可见:By.cssSelector:div.group-btn-container(尝试了 30 秒
【解决方案4】:
  1. 您可以将鼠标移动到该元素然后单击它,即使我遇到了这个问题,这个解决方案也解决了它

    Actions clickOnBtn = new Actions(driver);
    clickOnBtn .moveToElement("//button[contains(text(), 'Open Door')").click().build().perform;
    
  2. 即使元素在屏幕上不完全可见也会发生这种情况,在这种情况下,您可以滚动到该元素,然后使用上面的代码,如下所示

    JavascriptExecutor jse2 = (JavascriptExecutor)driver;
    jse2.executeScript("arguments[0].scrollIntoView()", ele); 
    Actions clickOnBtn = new Actions(driver);
    clickOnBtn .moveToElement("//button[contains(text(), 'Open Door')").click().build().perform;
    
  3. 使用javascriptExecutor点击元素

    JavascriptExecutor executor = (JavascriptExecutor)driver;
    executor.executeScript("arguments[0].click();", ele);
    
  4. 有时我们选择元素的方式也会发生这种情况,xpath可以更改,我们可以尝试使用父标签而不是按钮并尝试

【讨论】:

  • 苏海尔;我也尝试过这种方法。结果相同。当我通过调试选项逐步运行时,它可以工作,但是当我直接运行时,它会抛出相同的异常 org.openqa.selenium.ElementClickInterceptedException: element click intercepted:
  • 我已经用另外 2 个解决方案更新了我的答案,你可以看看它并检查一下,即使元素在屏幕上不完全可见也会发生这种情况,在这种情况下,你可以滚动到该元素和单击该元素,否则您可以尝试使用 javascriptexecutor 单击元素一次
  • 有时我们选择元素的方式也会发生这种情况,xpath可以更改,我们可以尝试使用父标签而不是按钮并尝试
【解决方案5】:

您可以通过点击操作定义自己的 ExpectedCondition:

public class SuccessfulClick implements ExpectedCondition<Boolean> {
    private WebElement element;

    public SuccessfulClick(WebElement element) { //WebElement element
        this.element = element;
    }

    @Override
    public Boolean apply(WebDriver driver) {
        try {
            element.click();
            return true;
        } catch (ElementClickInterceptedException | StaleElementReferenceException | NoSuchElementException e) {
            return false;
        }
    }
}

然后使用它:

wait10.until(elementToBeClickable(btn));
wait10.until(new SuccessfulClick(btn));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 2013-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-12
    • 2020-01-02
    相关资源
    最近更新 更多