0

I am writing a selenium test using javascript in Jmeter. When I click on a link on the site, it opens in a new tab by default. The automated browser even switches to this new tab. But, it seems selenium is not switching to the new tab. When I print the inner HTML for the body element (obtained by xpath //body) after clicking on the link, I get back the source for the first tab, not the second.

When I try to wait for any element at all on the next page (waiting for //div[@id="my-div-on-second-page-only"], for example), I get a timeout saying the element was never located (long after I can see the page has finished loading).

I did happen upon this question, but it's for python, and I am also struggling to understand the accepted answer.

Update

My code for switching the tabs currently looks like this:

// Switch tabs
var tabs = WDS.browser.getWindowHandles();
var tab = WDS.browser.getWindowHandle();
WDS.log.info("Tabs: " + tabs + " current: " + tab); // Output below

// Assume always there are only two tabs
for (t in tabs)
{
    WDS.log.info("Checking tab " + t);
    if (t != tab)
    {
        WDS.log.info("Switching to " + t);
        WDS.browser.switchTo().window(t);
        break;
    }
}

The output for the line marked with // Output below is:

Tabs: [CDwindow-A83928D86BA4F6F46C5D7F4B63B674A5, CDwindow-177CF406C98C28DF4AF5E7EC3228B896] current: CDwindow-A83928D86BA4F6F46C5D7F4B63B674A5

I am not even entering the for/in loop. I have tried switching using tabs[index], tabs.get(0);, and tabs.iterator.next();, but none have worked. I've been scouring the internet all day for some information on the data type returned by WDS.browser.getWindowHandles();, but just can't seem to find it.

Update 2

I ultimately switched to the Java interpreter. None of the proposed solutions, even the ones in javascript, worked. I suspect there is an issue with the javascript interpreter itself. I'm going to leave the question open in case anyone would like to offer a solution that is tested and works in the Jmeter webdriver extension for future knowledge.

Below is my working Java code. It uses Matias Dominguez's example, which makes the assumption that the last entry in tabs is the new tab. Although I find Mike Cook's solution seems to be the best in terms of a general solution, Matias' was good enough for my problem.

// Switch tabs
ArrayList tabs = new ArrayList(); // Jmeter interpreter uses <String> by default
tabs.addAll(WDS.browser.getWindowHandles());
String tab = WDS.browser.getWindowHandle();
WDS.log.info("Tabs: " + tabs + " current: " + tab + " Size of tabs: " + tabs.size());
WDS.browser.switchTo().window(tabs.get(tabs.size() - 1));
WDS.log.info("Tabs switched successfully");
jaredad7
  • 998
  • 2
  • 11
  • 33
  • I found this on google: http://www.softpost.org/selenium-with-node-js/working-with-multiple-browser-windows-or-tabs-in-selenium-in-node-js/ –  Mar 20 '18 at 16:24
  • 1
    While the window may be *focused* on the new tab visually, your driver is still working in the context of the original window handle. This may vary by browser, but you usually have to explicitly instruct the driver to switch window handles any time you want to interact with a new handle. – sytech Mar 20 '18 at 16:30
  • Can you update the question with your code trials? – undetected Selenium Mar 20 '18 at 17:33
  • Possible duplicate https://stackoverflow.com/questions/9588827/how-to-switch-to-the-new-browser-window-which-opens-after-click-on-the-button – Alexey Dolgopolov Mar 20 '18 at 20:50
  • Not a duplicate. This is specifically about javascript. That is about java. – jaredad7 Mar 20 '18 at 21:04

4 Answers4

2

I would load up a list with all the window handles before the click action. Then after clicking the new window would not be equal to any of the saved window handle values.

List<String> tabs = new ArrayList<>();
tabs.addAll(driver().getWindowHandles());
String newTab = null;

targetElement.click();

for (String currentWindow: driver().getWindowHandles()) {
    if (!tabs.contains(currentWindow)) {
        newTab = currentWindow;
        break;
    }
}
Mike Cook
  • 99
  • 5
1

When you click a link and its open a new tab the driver still focus on the first tab, so you have to move to it:

List<String> tabs = new ArrayList<>();
tabs.addAll(driver().getWindowHandles());
driver().switchTo().window(tabs.size() - 1);

This get all windows handles and move to the last tab opened, then you can find(theElement).

  • 1
    Assuming the newly opened tab is on the place with index 1 in the ArrayList is dangerous. If the driver already contains more than 2 WindowHandles (windows/tabs) the new tab would be placed for example on index 2. Get the last element from the ArrayList instead. – S. Van den Wyngaert Mar 20 '18 at 17:05
  • 1
    Good point, but I did not want to give a full explanation, another way is iterate over all handles and match the driver().getTitle() (in case you know it). – Matias Dominguez Mar 20 '18 at 17:12
  • I'm using javascript for this test, and having a bit of trouble extracting the window from whatever kind of object `getWindowHandles()` is returning. I've tried `tabs[0]`, `tabs.get(0)`, and `tabs.iterator.next()`, but nothing seems to work. – jaredad7 Mar 20 '18 at 18:43
1

You can do something like below.

var full_tabs = WDS.browser.getWindowHandles();
var x = full_tabs.toString();
var arr = x.split(',');
var newtab = arr[arr.length-1].split(']').toString().replace(',','').replace(' ','');

It is not best solution but it will work. You can combine it into 2 line.

0

You can switch between tabs calling the below method:

public void setMainWindow() {
    try{
        int numberOfWindow = driver.getWindowHandles().size();
        boolean tmpIndex = true;

        String mainWindowHandler = driver.getWindowHandle();        // Store the current window handle
        if (numberOfWindow > 1) {
            for(String winHandle : driver.getWindowHandles()){
                driver.switchTo().window(winHandle);                // Switch to new window opened
                if (tmpIndex) {
                    mainWindowHandler = winHandle;
                }
                tmpIndex = false;
            }

                                                                    // Perform the necessary actions on new window          
            driver.close();                                         // Close the new window, if that window no more required
            driver.switchTo().window(mainWindowHandler);            // Switch back to original browser (first window)
        }
    } catch (Exception e) {}
}

// Continue with original browser (first window)...
Ali Azam
  • 2,047
  • 1
  • 16
  • 25