Java + Selenium : How to know if WebElement is clickable in a way other than isDisplayed, isEnabled 和 findElement?

标签 java html css selenium exception

我知道 WebElement 可点击的测试普遍情况:

用这样的方式测试它:

public static boolean isElementFoundDisplayedEnabled(WebDriver driver, String accessor){

        return driver.findElements(By.xpath(accessor)).size() > 0 && driver.findElement(By.xpath(accessor)).isDisplayed() && driver.findElement(By.xpath(accessor)).isEnabled();
        //isDisplayed(): method avoids the problem of having to parse an element's "style" attribute to check hidden/visible. False when element is not present
        //isEnabled(): generally return true for everything but disabled input elements.
    }

此函数有缺陷,它仅检查元素是否在 DOM 级别可点击,但如果由于某些 css 困惑,元素被隐藏/重叠,则可以得到异常:

org.openqa.selenium.WebDriverException: unknown error: Element is not clickable at point (781, 704). Other element would receive the click:

...

在这种情况下,仍然可以使用以下方法单击该元素:

// Assume driver is a valid WebDriver instance that
// has been properly instantiated elsewhere.
WebElement element = driver.findElement(By.id("gbqfd"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", element);

但是,我很想知道,我们如何在不点击 executor.executeScript 的情况下检查 WebElement 是否被其他元素隐藏/重叠并且完全可点击。

有人可以透露一些信息吗,我已经对这些进行了几个小时的研究,但一无所获。

最佳答案

我不太喜欢创建像这样处理所有点击等的函数,但如果我被迫编写一个函数,它看起来会像这样。里面的评论解释了发生了什么。

public static void clickElement(By locator) throws InterruptedException
{
    try
    {
        // first we try the standard wait for element to be clickable and click it
        new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(locator)).click();
    }
    catch (TimeoutException e)
    {
        // element never becomes present
    }
    catch (WebDriverException e)
    {
        // click is blocked by another element, retry for 10 seconds
        while (true)
        {
            Instant timeOut = Instant.now().plusSeconds(10);
            try
            {
                driver.findElement(locator).click();
                break;
            }
            catch (WebDriverException e2)
            {
                // ignore additional blocked click exceptions
            }

            if (Instant.now().isAfter(timeOut))
            {
                // element is still blocked after retries for 10 seconds, fallback to JSE click
                ((JavascriptExecutor) driver).executeScript("arguments[0].click();", driver.findElement(locator));
            }

            // slight pause between loops
            Thread.sleep(100);
        }
    }
}

关于您的功能的一些反馈... 您应该传递 By 实例而不是字符串,例如

By locator = By.id("myId");

这样您的函数就可以更加灵活,并且不会仅硬编码为 XPath。此外,您正在使用您的功能抓取页面 3 次。抓取页面一次,然后使用存储的元素进行可见和启用的检查,例如

public static boolean isElementFoundDisplayedEnabled(WebDriver driver, By locator)
{
    List<WebElement> e = driver.findElements(locator);

    return !e.isEmpty() && e.get(0).isDisplayed() && e.get(0).isEnabled();
}

关于Java + Selenium : How to know if WebElement is clickable in a way other than isDisplayed, isEnabled 和 findElement?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45962207/

相关文章:

javascript - 在 jwplayer 5 中单击“播放”时打开新窗口

html - 固定页眉、固定页脚、全高多滚动列布局

javascript - 打开内容时如何使按钮不掉落?

javascript - 无法在html中创建列表

java - Swing 计时器与可能的长时间运行的后台任务相结合

java - 需要在按下 Jbutton 时显示 ImageIcon

java - 有人可以帮我这个java代码吗?循环错误

java - 防止同一个对象关联到 hibernate 中的两个不同 session

html - CSS:固定/固定顶部菜单栏

javascript - HTML5 用 Canvas 绘图,旋转线?