在调试模式下运行时,元素是可单击的,但通常会抛出ElementClickInterceptedException

时间:2019-11-11 02:50:06

标签: java selenium selenium-webdriver webdriver webdriverwait

我正在尝试进行网络自动化。 我正在定义一个弹出菜单,其中包含一个分别用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” 的自定义对象,而这两个都不是< strong> Web元素也不是其子类,但扩展了Object并实现了一个称为IElement的接口,因此我们不能使用 JavaScriptExecutor方法,因为它需要按钮的Web元素形式要点击。

5 个答案:

答案 0 :(得分:2)

如果它在调试中起作用,则表示覆盖层自动消失。您可以等待它消失

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();

答案 1 :(得分:0)

它看起来像:

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

只需调整CSS

答案 2 :(得分:0)

您需要注意以下几点:

  • XPath //button[contains(text(), 'Open Door'):可以使用以下两种格式进一步优化此 xpath
    • //button[text()='Open Door']
    • //button[contains(., 'Open Door')]
  • CSS div.device-item.content.view-content > div.detail > div > button.btn.btn-primary.ng-star-inserted看起来不错,但是我坚信button.btn.btn-primary.ng-star-inserted也可以。
  • “ ...在调试模式下成功执行...” :随着浏览器客户端有足够的时间来稳定网页动态,而所需的WebElement也有足够的时间来获得 interactive < / strong>。
  • “ ......我们充分检查按钮的存在,并确认按钮是否存在并且可点击...” :这是一个神话:
    • 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:元素单击被拦截... ,因此,您可以添加其他步骤来为引入 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

中找到相关的详细讨论

答案 3 :(得分:0)

  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
  4. click元素

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

答案 4 :(得分:0)

您可以通过点击操作定义自己的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));