Here is implementation without using browser.sleep() method.
Function waitForNewWindow()
is created using async and underscorejs.
Where async.until()
method is used for calling getAllWindowHandles()
synchronously.
element(by.id("newPlan")).click()
.then(function () {
return waitForNewWindow();
})
.then(function (newWindowHandle) {
browser.switchTo().window(newWindowHandle).then(function () {
expect(browser.getCurrentUrl()).toMatch(/\/url/);
});
});
/**
* Wait for new window is opened
*
* @param {Object} [params]
* @param {number} [params.runs] - number of tries
* @param {number} [params.interval] - interval for launching getAllWindowHandles()
*
* @returns {webdriver.promise.Promise}
*/
function waitForNewWindow(params) {
var currentHandles = [];
var deferred = protractor.promise.defer();
var finish;
var newHandle;
var numberOfRuns = 0;
params = params ? params : {};
params.runs = params.runs || 10;
params.interval = params.interval || 1000;
browser.driver.getAllWindowHandles()
.then(function (handles) {
currentHandles = handles;
})
.then(function () {
async.until(
// function that tests condition
function () {
return newHandle || finish;
},
// function that is executed until test condition is true
function (callback) {
browser.driver.getAllWindowHandles()
.then(function (newHandles) {
numberOfRuns++;
if (numberOfRuns > params.runs) {
finish = true;
return callback(null, newHandle);
}
if (currentHandles.length < newHandles.length) {
newHandle = _.difference(newHandles, currentHandles);
return callback(null, newHandle);
}
setTimeout(function () {
callback(null, newHandle);
}, params.interval);
});
},
// callback when test condition is true
function (error, result) {
if (!result) {
return deferred.reject('New browser window hasn\'t been opened');
}
if (result.length > 1) {
return deferred.reject('More than one new browser window were opened');
}
deferred.fulfill(result.toString());
}
);
});
return deferred.promise;
};