Selenium : 处理加载屏幕遮挡 web 元素。 (爪哇)

Posted

技术标签:

【中文标题】Selenium : 处理加载屏幕遮挡 web 元素。 (爪哇)【英文标题】:Selenium : Handling Loading screens obscuring the web elements. (Java) 【发布时间】:2013-06-23 09:32:55 【问题描述】:

我正在为网页编写一个自动化测试用例。这是我的场景。 我必须在 html 表单中单击并键入各种 Web 元素。但是,有时在文本字段上键入时,会出现一个 ajax 加载图像,模糊了我想要与之交互的所有元素。所以,我在点击下面的实际元素之前使用 web-driver 等待,

WebdriverWait innerwait=new WebDriverWait(driver,30);
innerwait.until(ExpectedConditions.elementToBeClickable(By.xpath(fieldID)));
driver.findelement(By.xpath(fieldID)).click();

但是等待函数会返回元素,即使它被另一个图像迷雾并且不可点击。但是 click() 会抛出异常

Element is not clickable at point (586.5, 278).
Other element would receive the click: <div>Loading image</div>

在与任何元素交互之前,我是否必须每次检查加载图像是否出现?(我无法预测加载图像何时会出现并使所有元素雾化。) 有没有有效的方法来处理这个? 目前我正在使用以下函数等待加载图像消失,

public void wait_for_ajax_loading() throws Exception

    try
    Thread.sleep(2000);
    if(selenium.isElementPresent("id=loadingPanel"))
    while(selenium.isElementPresent("id=loadingPanel")&&selenium.isVisible("id=loadingPanel"))//wait till the loading screen disappears
    
         Thread.sleep(2000);
         System.out.println("Loading....");

    

    catch(Exception e)
        Logger.logPrint("Exception in wait_for_ajax_loading() "+e);
        Logger.failedReport(report, e);
        driver.quit();
        System.exit(0);
    


但是我不知道具体什么时候调用上面的函数,在错误的时间调用会失败。有没有什么有效的方法来检查一个元素是否真的可以点击?还是存在加载图像?

谢谢..

【问题讨论】:

您是否针对不同的浏览器运行此测试?如果是这样,您是否对所有这些都得到相同的例外?如果您为 Chrome 运行它,异常可能与您的代码无关,而是 Chrome 驱动程序的“click()”方法的错误。 @Sergio 我这样做了,这不是浏览器驱动程序错误,基于来自这个问题 ***.com/questions/9878478/… 的 cmets 以及我了解到的 webdriver wait 返回元素,即使它是不可点击,即如果有多个图层遮挡它。那么有没有等待元素真正可点击的等待方法? 【参考方案1】:

鉴于您描述的情况,您必须验证以下两个条件之一:

    您要点击的元素是否可点击? 阻止点击的原因是否仍然存在?

通常,如果WebDriver 能够找到元素并且它是可见的,那么它也是可点击的。知道可能阻止它的可能原因,我宁愿选择验证这些原因。此外,它会在测试代码中更具表现力:您可以清楚地看到您在等待什么,在单击元素之前检查的是什么,而不是在没有明显原因的情况下检查“可点击性” .我认为它可以让一个(阅读测试的人)更好地了解正在(或可能)实际发生的事情。

尝试使用此方法检查加载图像是否不存在:

// suppose this is your WebDriver instance
WebDriver yourDriver = new RemoteWebDriver(your_hub_url, your_desired_capabilities);

......
// elementId would be 'loadingPanel'
boolean isElementNotDisplayed(final String elementId, final int timeoutInSeconds) 
    try 
        ExpectedCondition condition = new ExpectedCondition<Boolean>() 
            @Override
            public Boolean apply(final WebDriver webDriver) 
                WebElement element = webDriver.findElement(By.id(elementId));
                return !element.isDisplayed();
            
        ;
        Wait w = new WebDriverWait(yourDriver, timeoutInSeconds);
        w.until(condition);
     catch (Exception ex) 
        // if it gets here it is because the element is still displayed after timeoutInSeconds
        // insert code most suitable for you
    
        return true;

也许您必须根据您的代码对其进行一些调整(例如,在页面加载时查找元素一次并仅检查它是否显示)。

如果您不确定加载图像的确切时间(尽管我想您会这样做),您应该在每次单击由于加载图像而变得“不可点击”的元素之前调用此方法。如果加载图像存在,该方法将在它消失后立即返回true;如果它没有在“timeoutInSeconds”时间内消失,该方法将执行您选择的操作(例如,抛出带有特定消息的异常)。

你可以像这样把它包装起来:

void clickSkippingLoadingPanel(final WebElement elementToClick) 
    if (isElementNotDisplayed('loadingPanel', 10)) 
        elementToClick.click();
    

希望对你有帮助。

【讨论】:

以上是关于Selenium : 处理加载屏幕遮挡 web 元素。 (爪哇)的主要内容,如果未能解决你的问题,请参考以下文章

Selenium定位的元素被图层遮挡了的解决办法

停止重新加载从 iPhone 主屏幕启动的 Web 应用程序

View被其它View遮挡显示出来

如何使用给定的屏幕坐标选择元素 - selenium,java

和平精英刘海屏挡住了怎么办

如何在 Selenium 中获取当前页面的 Web 加载 HTML?