Selenium IE WebDriver仅在调试时有效 [英] Selenium IE WebDriver only works while debugging

查看:284
本文介绍了Selenium IE WebDriver仅在调试时有效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Java Gradle,Selenium 3.8.0和IEWebDriver 3.8.0。



Chrome和Firefox工作正常,但IE会抛出 org.openqa.selenium.TimeoutException:预期的条件失败异常,虽然IE也可以正常工作,如果我一步一步调试我的源代码。



<因此,我花了很长时间才发现这个问题,我注意到,只要调用 webDriver.get(..),IE就会失去WebDriver和源代码之间的连接,看起来像这样:

  driver.get(url); 
waitForPageLoaded(driver);

因为我认为存在一些时间问题,但我已经尝试过处理这个:

  public void waitForPageLoaded(WebDriver driver){
logger.debug(等到页面加载完毕。);
// IE似乎在这里失败了。
new WebDriverWait(driver,SeleniumConfigurator.TIME_OUT)
.until(d - >((JavascriptExecutor)d).executeScript(return document.readyState)
.equals(complete ));
}

然后我注意到IE需要更多配置设置,但我不允许设置其中一些:IT限制 - >我无法更改regedit条目。



但是,为什么它在调试时工作正常?



这是我的IE设置:

 案例IE:
path =../ ../../../../../resources/driver/win/IEDriverServer_32_v3-8-0.exe;
url = getClass()。getResource(path);
if(url == null){
logger.error(无法在+ path +找到Internet Explorer Web驱动程序二进制文件。+
此浏览器的所有测试都将被忽略。);
currentBrowserType = BrowserType.UNDEFINED;
休息;
}
try {
System.setProperty(webdriver.ie.driver,Paths.get(url.toURI())。toFile()。getAbsolutePath());
} catch(URISyntaxException e){
e.printStackTrace();
}
// https://sqa.stackexchange.com/questions/13077/unable-to-run-selenium-webdriver-script-in-ie11
InternetExplorerOptions optionsIE = new InternetExplorerOptions( );
optionsIE.setCapability(InternetExplorerDriver.IE_ENSURE_CLEAN_SESSION,true);
optionsIE.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS,true);
optionsIE.withAttachTimeout(SeleniumConfigurator.TIME_OUT,TimeUnit.SECONDS);

//optionsIE.setCapability(InternetExplorerDriver.REQUIRE_WINDOW_FOCUS,true);


webDriver = new InternetExplorerDriver(optionsIE);
currentBrowserType = BrowserType.IE;
休息;

我不知道这里出了什么问题..



第一个测试工作正常,之后出现超时异常(看看评论):

  @测试
public void test_Contact(){
Init();

util.logTestStart(索引页面上的测试联系人......);
String xPath =// * [@ id ='contact-link'] / a;
WebElement element = webDriver.findElement(By.xpath(xPath));
Assert.assertEquals(element.getAttribute(href),mailto:what@ever.com);
}


@Test
public void test_LegalInformation(){
Init();

util.logTestStart(测试索引页面上的法律信息......);
String xPath =// * [@ id ='link-highlighted'] / a;
util.aTagClickByXPath(webDriver,xPath);

Assert.assertEquals(webDriver.getCurrentUrl(),http://whatever.com/);
}


private void Init(){
if(configurator == null){
configurator = SeleniumConfigurator.getInstance();
}

if(webDriver!= configurator.getWebDriver()){
webDriver = configurator.getWebDriver();
}

if(util == null){
util = new SeleniumTestUtil();
}

//默认打开localhost
util.goTo(webDriver,http:// localhost:8080 / de / index);
}

public void aTagClickByXPath(WebDriver driver,String xPath){
logger.debug(在a-Tag上执行点击,xPath:+ xPath);
WebElement element = driver.findElement(By.xpath(xPath));
element.click(); //第一次单击工作,第二次失败,导致超时异常
waitForPageLoaded(driver);
}

有人有提示吗?



编辑:



org.openqa.selenium.NoSuchWindowException:无法获取浏览器现在被抛出。超时异常不再出现了。我没有改变任何内容。



EDIT2:



更多信息:



节点:

 < div class =col-xs-12id = 链路容器 > 
< div id =bike-linkclass =pull-right>
< a href =http://whatever.com/?lang=D>
无论
< i class =fa fa-chevron-rightaria-hidden =true>< / i>
< / a>
< / div>
< div id =link-highlightedclass =pull-right>
< a href =http://whatever2.com/> <! - 这一个 - >
Rechtliche Hinweise
< i class =fa fa-chevron-rightaria-hidden =true>< / i>
< / a>
< / div>
< div id =contact-linkclass =pull-right>
< a href =mailto:what@ever.com>
Kontakt
< i class =fa fa-chevron-rightaria-hidden =true>< / i>
< / a>
< / div>
< / div>

超时定义:

  public static final int TIME_OUT = 15; 


解决方案

您可能需要处理几件事考虑如下:




  • 首先函数() public void waitForPageLoaded(WebDriver driver) 看起来像纯粹的开销。基本上没有必要在 WebDriverWait

  • 之上编写单独的包装函数。按 Selenium v​​3.8.1 WebDriverWait 的当前实施情况 构造函数如下:

      WebDriverWait(WebDriver驱动程序,时钟,睡眠卧铺,长timeOutInSeconds,long sleepTimeOut)
    WebDriverWait(WebDriver driver,long timeOutInSeconds)
    WebDriverWait(WebDriver驱动程序,long timeOutInSeconds,long sleepInMillis)




目前还不清楚如何实施 WebDriverWait(驱动程序,SeleniumConfigurator.TIME_OUT) 即可。参数看起来容易出错。



再次,直到条件 d - > ((JavascriptExecutor)d).executeScript(return document.readyState)。equals(complete) 是一种开销,因为客户端(即 Web浏览器)永远不会将控件返回到 WebDriver 实例,除非'document.readyState'等于完成。满足此条件 Selenium 执行下一行代码。因此 布尔org.openqa.selenium.support.ui.FluentWait.until(函数<?super WebDriver,Boolean> arg0) 的这个函数有没有影响。



值得一提的是,虽然客户端(即 Web浏览器)一旦'document.readyState'等于完成,就可以将控件返还给 WebDriver 实例,新的 HTML DOM 上的所有 WebElements 都不是很好的strong> VISIBLE INTERACTABLE CLICKABLE




  • 最后,为了解决您的主要问题,我需要澄清一下节点 xPath =// * [@ id ='link-highlighted'] / a 以确保是否调用 click() 打开一个新标签或网址被重定向。我没有看到你处理任何一种情况。



解决方案




  • 在处理 InternetExplorer 时,请记住 InternetExplorerDriver 在真实的浏览器中运行并支持Javascript。

  • 通过以下方式设置浏览器焦点

      capabilities.setCapability(requireWindowFocus,true); 


  • 如果 点击() 打开一个新窗口,切换 window_handles



I am using Java Gradle, Selenium 3.8.0 and IEWebDriver 3.8.0.

Chrome and Firefox are working fine, but IE throws a org.openqa.selenium.TimeoutException: Expected condition failed Exception, although IE also works fine, if I debug my source code step by step.

Therefore I debuged a long time to find that problem and I noticed that IE looses the connection between WebDriver and Source Code, whenever a webDriver.get(..) is called, whichs looks like that:

driver.get(url);
waitForPageLoaded(driver);

Because of that I assume that there are some timing issues, but I already tried to handle this:

public void waitForPageLoaded(WebDriver driver) {
        logger.debug("Wait until the page was loaded.");
        // IE seems to fail here.
        new WebDriverWait(driver, SeleniumConfigurator.TIME_OUT)
                .until(d -> ((JavascriptExecutor)d).executeScript("return document.readyState")
                        .equals("complete"));
    }

Then I noticed that IE needs some more configuration settings, but I am not allowed to setup some of them: IT restrictions -> I cannot change regedit entries.

BUT, why does it work fine, while debugging?

This is my IE setup:

case IE:
                path = "../../../../../../resources/driver/win/IEDriverServer_32_v3-8-0.exe";
                url = getClass().getResource(path);
                if (url == null) {
                    logger.error("Could not find the Internet Explorer web driver binary at " + path + " ." +
                            "All test for this browser will be ignored.");
                    currentBrowserType = BrowserType.UNDEFINED;
                    break;
                }
                try {
                    System.setProperty("webdriver.ie.driver", Paths.get(url.toURI()).toFile().getAbsolutePath());
                } catch (URISyntaxException e) {
                    e.printStackTrace();
                }
                // https://sqa.stackexchange.com/questions/13077/unable-to-run-selenium-webdriver-script-in-ie11
                InternetExplorerOptions optionsIE = new InternetExplorerOptions();
                optionsIE.setCapability(InternetExplorerDriver.IE_ENSURE_CLEAN_SESSION, true);
                optionsIE.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
                optionsIE.withAttachTimeout(SeleniumConfigurator.TIME_OUT, TimeUnit.SECONDS);

                //optionsIE.setCapability(InternetExplorerDriver.REQUIRE_WINDOW_FOCUS, true);


                webDriver = new InternetExplorerDriver(optionsIE);
                currentBrowserType = BrowserType.IE;
                break;

I have no idea what's going wrong here..

The first test works fine, after that the timeout exception appears (take a look at the comment):

@Test
    public void test_Contact() {
        Init();

        util.logTestStart("Test contact on index page..");
        String xPath = "//*[@id='contact-link']/a";
        WebElement element = webDriver.findElement(By.xpath(xPath));
        Assert.assertEquals(element.getAttribute("href"), "mailto:what@ever.com");
    }


    @Test
    public void test_LegalInformation() {
        Init();

        util.logTestStart("Test legal information on index page..");
        String xPath = "//*[@id='link-highlighted']/a";
        util.aTagClickByXPath(webDriver, xPath);

        Assert.assertEquals(webDriver.getCurrentUrl(), "http://whatever.com/");
    }


private void Init() {
        if (configurator == null) {
            configurator = SeleniumConfigurator.getInstance();
        }

        if (webDriver != configurator.getWebDriver()) {
            webDriver = configurator.getWebDriver();
        }

        if (util == null) {
            util = new SeleniumTestUtil();
        }

        // Open localhost as default
        util.goTo(webDriver, "http://localhost:8080/de/index");
    }

public void aTagClickByXPath(WebDriver driver, String xPath) {
        logger.debug("Performing a click on an a-Tag, xPath: " + xPath);
        WebElement element = driver.findElement(By.xpath(xPath));
        element.click(); // First click works, second one fails, cause of Timeout Exception
        waitForPageLoaded(driver);
    }

Does anyone have a hint?

EDIT:

org.openqa.selenium.NoSuchWindowException: Unable to get browser get thrown for now. Timeout Exception didnt appears anymore. I changed nothing.

EDIT2:

Further information:

Node:

<div class="col-xs-12" id="link-container">
                <div id="bike-link" class="pull-right">
                    <a href="http://whatever.com/?lang=D">
                        whatever
                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
                    </a>
                </div>
                <div id="link-highlighted" class="pull-right">
                    <a href="http://whatever2.com/"> <!-- this one -->
                         Rechtliche Hinweise
                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
                    </a>
                </div>
                <div id="contact-link" class="pull-right">
                    <a href="mailto:what@ever.com">
                        Kontakt
                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
                    </a>
                </div>
            </div>

Timeout definition:

public static final int TIME_OUT = 15;

解决方案

There are a couple of facts which you may have to consider as follows :

  • First of all the function() as public void waitForPageLoaded(WebDriver driver) looks to me as a pure overhead. There is basically no need to write a seperate wrapper function on top of WebDriverWait
  • As per the current implementation of WebDriverWait in Selenium v3.8.1 the Constructors are as follows :

    WebDriverWait(WebDriver driver, Clock clock, Sleeper sleeper, long timeOutInSeconds, long sleepTimeOut) 
    WebDriverWait(WebDriver driver, long timeOutInSeconds)
    WebDriverWait(WebDriver driver, long timeOutInSeconds, long sleepInMillis)
    

It is pretty much unclear how you have implemented WebDriverWait(driver, SeleniumConfigurator.TIME_OUT). The arguments looks error prone.

Again, the until condition d -> ((JavascriptExecutor)d).executeScript("return document.readyState").equals("complete") is a overhead because the Client (i.e. the Web Browser) will never return the control back to the WebDriver instance until and unless 'document.readyState' is equal to "complete". Once this condition is fulfilled Selenium performs the next line of code. Hence this function of Boolean org.openqa.selenium.support.ui.FluentWait.until(Function<? super WebDriver, Boolean> arg0) have no impact.

It's worth to mention that though the Client (i.e. the Web Browser) can return back the control to the WebDriver instance once 'document.readyState' equal to "complete" is achieved, it doesn't garuntees that all the WebElements on the new HTML DOM are VISIBLE, INTERACTABLE and CLICKABLE.

  • Finally, to address your main issue, I needed a clarification about the node xPath = "//*[@id='link-highlighted']/a" to ensure whether invoking click() opens a new tab or url gets redirected. I don't see you handling either of the cases.

Solution

  • While dealing with InternetExplorer, keep in mind InternetExplorerDriver runs in a real browser and supports Javascript.
  • Set the Browser Focus through :

    capabilities.setCapability("requireWindowFocus", true);
    

  • If click() opens a new window, switch the window_handles

这篇关于Selenium IE WebDriver仅在调试时有效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆