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

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

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

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

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

它看起来像:

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

只需调整CSS

,

您需要注意以下几点:

  • 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 。
  • “ ......我们充分检查按钮的存在,并确认按钮是否存在并且可点击...” :这是一个神话:
    • 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

中找到相关的详细讨论
,
  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,我们可以尝试使用父标签而不是按钮并尝试

,

您可以通过点击操作定义自己的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));
本文链接:https://www.f2er.com/3126766.html

大家都在问