Search code examples
javaseleniumselenium-webdriverinternet-explorer-11

Selenium IE WebDriver only works while debugging


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:[email protected]");
    }


    @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:[email protected]">
                        Kontakt
                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
                    </a>
                </div>
            </div>

Timeout definition:

public static final int TIME_OUT = 15;

Solution

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

    • First of all:

      public void waitForPageLoaded(WebDriver driver)
      

      looks to me as a pure overhead. There is basically no need to write a separate 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 the function

      Boolean org.openqa.selenium.support.ui.FluentWait.until(Function<? super WebDriver, Boolean> arg0)
      

      will 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 guarantees 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() through the window_handles


    References

    You can find a couple of relevant detailed discussions in: