Selenium Java为element.isDisplayed返回错误结果

时间:2018-09-04 10:40:54

标签: java selenium

我正在使用Java,Selenium和TestNG运行测试。 (selenium-server-standalone.3.8.3,Java 8 Update 151)

我正在使用Firefox Quantum 61.0.2(64位)作为浏览器。

我有一个问题,我需要单击的元素消失了,并且想在发生这种情况时记录错误。

不幸的是,当元素明显不存在时,element.isDisplayed返回true。

诊断此问题很困难的原因是,单击“不可见”元素实际上是有效的,但仍会导致不可预测的结果。

如何获得正确答案?

这是使用的代码示例:

public static boolean isElementDisplayed(String className, String textToFind, String htmlElement,
        WebDriver driver) {

    // String className = "map-popup-button";
    // String textToFind = "icon-structure-tree";
    // String htmlElement = "button";

    List<WebElement> elements = Common.findElementsUsingHtmlXpathClass(driver, htmlElement, className);
    Common.myPrint(thisClass + " elements count: " + elements.size());
    String text = "";
    String attr = "";
    for (WebElement element : elements) {
        // select an element
        if(!Common.retryingIsElementDisplayed(element)) {
            Common.scrollIntoView(element, driver);
        }
        if (Common.retryingIsElementDisplayed(element)) {
            text = element.getAttribute("innerHTML");
            if (text != "") {
                text = text.trim();
                if (text.contains(textToFind)) {
                    Common.myPrint(thisClass + " innerHTML: " + text);
                    return true;
                }
            }
            attr = Common.getAllAttributes(element, driver);
            if (attr.contains(textToFind)) {
                Common.myPrint(thisClass + " attr: " + text);
                return true;
            }
        }
    }
    return false;
}

和那个retryingIsElementDisplayed函数:

public static boolean retryingIsElementDisplayed(WebElement element) {
    // myPrint(thisClass + " retryingIsElementDisplayed...");
    boolean result = false;
    int attempts = 0;
    while (attempts < 2) {
        try {
            result = element.isDisplayed();

            break;
        } catch (StaleElementReferenceException e) {
            int errorCode = 1533564891;
            Common.myPrint(thisClass + " error code: " + errorCode +" Exception: " + e.getMessage());
            Common.myPrint(thisClass + " *** INFO ONLY *** ");
        }
        attempts++;
    }
    return result;
}

测试表明,使用javascriptExecutor.executeScript(“ arguments [0] .scrollIntoView(true);”,element);之后会发生此问题。在不同的元素上。这将我的徽标向上滚动到视线之外。当我手动向下滚动时,该元素不再可见(但仍然-大概-存在于DOM中)

这是我正在寻找的元素的HTML:

<svg version="1.1" id="Vector_Smart_Object_xA0_Image_1_" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 300 50" style="enable-background:new 0 0 300 50;" xml:space="preserve">

 .st0{fill:#FFF;}
</style>
<g>
    <polygon class="st0" points="119.2,12.4 126.3,12.4 126.3,31.3 138.4,31.3 138.4,37.5 119.2,37.5  "></polygon>
    <polygon class="st0" points="140.3,12.4 147.3,12.4 147.3,31.3 159.4,31.3 159.4,37.5 140.3,37.5  "></polygon>
    <polygon class="st0" points="202.1,12.4 197.1,21.5 192,12.4 184,12.4 193.6,28.3 193.6,37.4 200.7,37.4 200.7,28.3 210.2,12.4     "></polygon>
    <path class="st0" d="M172.7,11.7c-7.4,0-13.5,6-13.5,13.3s6.2,13.3,13.5,13.3c7.4,0,13.3-6,13.3-13.3s-6.2-13.3-13.5-13.3    M172.6,31.6c-3.5,0-6.3-3-6.3-6.7s2.8-6.7,6.3-6.7c3.5,0,6.3,3,6.3,6.7S176.1,31.6,172.6,31.6"></path>
    <path class="st0" d="M107.2,12.2h-6.7L89.8,37.5h7.3l2-4.6l9.4,0.1l1.8,4.5h7.4L107.2,12.2z M101.3,27.1l2.6-6.5l2.6,6.5H101.3z"></path>
</g>
</svg>

2 个答案:

答案 0 :(得分:0)

您可以将相同的网络元素存储在列表中。

演示代码如下:

List<WebElement> errorMsg = driver.findElements(By.xpath("xpath for error msg"));
            if(errorMsg.size()>0) {
                //do something when error occurs 
            }
            else {
                //your script knows , that there is no error msg.
            } 

答案 1 :(得分:0)

您正在使这种方式变得比所需的更加困难。您正在传递用于定位元素的String,而不是使用Selenium提供的By定位器类。

给出要查找的HTML元素的简单示例。

<svg version="1.1" id="Vector_Smart_Object_xA0_Image_1_" ...>

我们可以使用简单的By.id()定位器来找到此元素,例如

By svgElementLocator = By.id("Vector_Smart_Object_xA0_Image_1_");

现在,您可以将其传递给检查其是否显示的函数。

public static boolean isElementDisplayed(WebDriver driver, By locator) {
    try {
        return driver.findElement(locator).isDisplayed();
        break;
    } catch {
        return false;
    }
}

因为您不再绕过WebElement,所以不必担心StaleElementExceptions等问题,并且您的代码更加简单。您可以这样称呼

bool result = isElementDisplayed(driver, svgElementLocator);

请清楚一点,.isDisplayed()与元素是否在屏幕上无关...与元素是否不可见有关,例如显示:无,等等。请参见the docs

  

此元素是否显示?这种方法避免了必须解析元素的“样式”属性的问题。