2

I'm trying to use a JavascriptExecutor to open a new tab in IE9 from selenium webdriver:

public void openTab() {
    String url = webDriver.getCurrentUrl();
    String script = "var     a=document.createElement('a');a.target='_blank';a.href='" + url + "';a.innerHTML='open';document.body.appendChild(a);return a";
    Object element = getJSExecutor().executeScript(script);
    if (element instanceof WebElement) {
        WebElement anchor = (WebElement) element;
        anchor.click();
    } else {
        throw new RuntimeException("Unable to open tab: " + url);
    }
}

This works fine in Chrome but on running in IE9, I get the following error:

ElementNotVisibleException: The point at which the driver is attempting to click on the element was not scrolled into the viewport.

I'm using the 2.31 versions of both selenium and IEDriverServer.

Jess
  • 177
  • 3
  • 11
  • It's possible that IE hasn't had time to render the element you're adding to the DOM, so it's coordinates aren't within the browser viewport. You could try waiting a short bit before calling `click()` to see if that works. However, the IE driver probably won't recognize the new tab. Even if it does recognize it, trying to click on any of the elements within the new tab is likely to not work due to focus issues. I fear you may be trying to implement the workaround of [this post](http://stackoverflow.com/questions/6421988/webdriver-open-new-tab), which is the wrong approach altogether. – JimEvans Mar 06 '13 at 22:09
  • I am trying to implement that workaround as I have to use tabs for the tests and this is the only way to do so using webdriver. As I've said, the approach works perfectly well in Chrome and the webdriver getWindowHandles() and switchTo() methods do allow switching between tabs/windows. – Jess Mar 07 '13 at 11:06
  • Ordinarily, I'd just let this go, but "have to use tabs" really rubs me the wrong way. I can't imagine any requirement where opening pages in a new tab is not equivalent to opening in a new window. What if the user has set the browser settings to force pages to open in a new window? – JimEvans Mar 07 '13 at 12:06
  • I have to either open the page in a new tab or window - doesn't matter which. Regardless, I need a way to do this where I can easily switch between them and using the JavascriptExecutor allows me to do so. – Jess Mar 07 '13 at 13:24

2 Answers2

6

I had been having this difficulty in IE9 in a parallels VM. These are the two lines that made the whole thing work...

Actions builder = new Actions(webDriver);
builder.moveToElement(element).click(element).perform();

Scrolls the element into view then clicks it.

Daniele Armanasco
  • 7,289
  • 9
  • 43
  • 55
user2362947
  • 61
  • 1
  • 2
3

Managed to resolve the viewport issue & get the IEDriverServer to interact properly with both windows after a little coaxing so thought I'd post my solution in case anyone else has this problem.

To resolve the viewport problem, I used Actions to do a moveToElement then click:

public void actionsClick(WebElement element){
    Actions builder = new Actions(webDriver);
    builder.moveToElement(element).click(element).perform();
}

The IEDriverServer seems to take a little longer to pick up all the window handles, so I added a 5 second wait into the openTab method after doing the click:

public void openTab() {
    String url = webDriver.getCurrentUrl();
    String script = "var a=document.createElement('a');a.target='_blank';a.href='" + url + "';a.innerHTML='open me in a new tab';document.body.appendChild(a);return a";
    Object element = getJSExecutor().executeScript(script);
    if (element instanceof WebElement) {
        WebElement anchor = (WebElement) element;
        actionsClick(anchor);
        waitFor(5000);
        switchBrowserTab();
        returnToPreviousBrowserTab();
    } else {
        throw new RuntimeException("Unable to open tab: " + url);
    }
}

Then, as shown in the method above, to ensure the IEDriverServer is aware of both windows/tabs and can move between them, I added switchBrowserTab() and returnToPreviousBrowserTab() methods after clicking and waiting. Using the JavascriptExecutor to open a new tab will leave focus in the original tab and this method is set up to end with focus back in there again. In case anyone hasn't used the window handles before, here is the method I'm using for switching to the newly opened tab:

    Set<String> handles = webDriver.getWindowHandles();
    List<String> handlesList = new ArrayList<String>();
    for (String handle : handles) {
        handlesList.add(handle);
    }
    webDriver.switchTo().window(handlesList.get(handlesList.size() - 1));
    webDriver.manage().window().maximize();

A similar approach is used to move back except I get the current handle, then loop through the list to find its position, then move to the handle that is -1 from there.

Hope this is helpful.

Edit: this works in IE9 and Chrome. Not tested in other browsers.

Jess
  • 177
  • 3
  • 11