Unfortunately IE & Firefox don't ensure the windows handlers order, so we need iterate them. And getting focus on the new browser window/tab can be tricky too.
I've run into these issues so i created:
A helper function to overcome those issues
// Needs an element to make sure we are on the correct popup
var waitForPopUpHandle = function(elm, errorMessage) {
if (errorMessage == null) {
errorMessage = 'Expected a new browser tab or window to pop up';
};
if (elm == null) {
throw 'waitForPopUpHandle needs an element to wait for!';
};
browser.ignoreSynchronization = true; // not a protractor page
// IE & Firefox don't ensure the windows handlers order, so we need iterate them.
// First wait to have more that 1 browser tab
browser.manage().timeouts().implicitlyWait(300); // a reasonable wait-retry time
var i = 0;
var popUpHandle = browser.driver.wait(function() {
return browser.getAllWindowHandles().then(function(handles) {
if (handles.length > 1) {
return browser.switchTo().window(handles[i]).then(function() {
return browser.driver.isElementPresent(elm).then(function(result) {
if (result) {
return handles[i];
} else {
browser.sleep(400); // give it a break
i = i + 1;
if (i >= handles.length) {
i = 0;
};
return false;
};
});
});
} else {
browser.sleep(400); // give it a break
return false;
};
});
}, browser.params.timeouts.pageLoadTimeout, errorMessage);
// restore implicit wait
browser.manage().timeouts().implicitlyWait(0); //restore
return popUpHandle;
};
Sample usage of that helper
var popUpHandle = waitForPopUpHandle(by.css('div.some-element-unique-to-that-popup'));
browser.switchTo().window(popUpHandle).then(function() {
browser.ignoreSynchronization = true; // not an angular page
browser.driver.findElement(by.css('div.some-element-unique-to-that-popup')); // wait for the elm
// your expect()'s go here ...
// ...
browser.close().then(function() {
// This close() promise is necessary on IE and probably on Firefox too
var mainTab = waitForMainWindow();
expect(browser.switchTo().window(mainTab).then(function() {
browser.ignoreSynchronization = false; // restore if main window is an angular page
// Ensure we are back on the main window
// ....
return true;
})).toBe(true);
});
});
And finally waitForMainWindow helper
var waitForMainWindow = function(errorMessage) {
if (errorMessage == null) {
errorMessage = 'Expected main browser window to be available';
};
browser.ignoreSynchronization = true; // not an angular page
return browser.driver.wait(function() {
return browser.getAllWindowHandles().then(function(handles) {
if (handles.length > 1) {
var hnd = handles[handles.length - 1];
return browser.switchTo().window(hnd).then(function() {
return browser.close().then(function() {
browser.sleep(400); // wait for close
return false;
});
});
} else {
return handles[0];
};
});
}, 5000, errorMessage);
};