I have a non angular page that I open and then click a link, which changes pages and I fill out a form with some information and then click a button. Upon clicking that button another browser window is loaded. I need to switch over to the newly open page and work with some elements on that page and then return to the first window (the main page). I have the following code below:
describe('Test', function () {
beforeEach(function () {
browser.ignoreSynchronization = true;
});
it('Do authentication of session', function () {
session.goToCommandPage().then(function () {
browser.driver.manage().timeouts().implicitlyWait(12000);
}).then(function () {
browser.driver.wait(function () {
return browser.findElement(by.cssContainingText('#content > span:nth-child(3) > ul > li:nth-child(5) > a', 'AuthenticateUser'))
.then(function (elem) {
elem.click();
return true;
});
}, 12000, 'Waited for the AuthenticateUser link to load');
}).then(function () {
browser.driver.wait(function () {
return browser.driver.findElement(by.css('#content > span > form > table > tbody > tr:nth-child(3) > td:nth-child(2) > input'))
.then(function (elem) {
elem.sendKeys(COMPANY_ID);
return true;
});
}, 12000, 'Waited for the Company ID field to load');
}).then(function () {
browser.driver.wait(function () {
return browser.driver.findElement(by.css('#content > span > form > table > tbody > tr:nth-child(4) > td:nth-child(2) > input'))
.then(function (elem) {
elem.sendKeys('user');
return true;
});
}, 12000, 'Waited for the User field to load');
}).then(function () {
browser.driver.wait(function () {
return browser.driver.findElement(by.css('#content > span > form > table > tbody > tr:nth-child(6) > td:nth-child(2) > input'))
.then(function (elem) {
elem.click();
return true;
});
}, 12000, 'Waited for the Invoke button to load');
}).then(function () {
browser.driver.manage().timeouts().pageLoadTimeout(18000);
}).then(function () {
browser.driver.wait(function () {
return browser.getAllWindowHandles().then(function (handles) {
if (handles.length > 1) {
return true;
}
});
}, 12000, 'Waited for window count to be greater than 1');
});
});
it('Switch to the results tab', function () {
browser.getAllWindowHandles().then(function (handles) {
if (handles.length > 1) {
handles.forEach(function (wndw) {
browser.driver.switchTo().window(wndw).then(function () {
browser.driver.manage().timeouts().pageLoadTimeout(7000);
}).then(function () {
browser.driver.getTitle().then(function (title) {
console.log('Title now: ' + title);
if(title == 'localhost/Service/WebService.asmx/AuthenticateUser') {
browser.driver.wait(function () {
return browser.driver.findElement(by.css('.collapsible .expanded .text'))
.then(function (elem) {
elem.getText().then(function (textProduced) {
console.log('Text printed: ' + textProduced);
});
return true;
});
}, 12000, 'Waited for the output text to load');
}
});
});
});
}
browser.driver.switchTo().window(handles[0]).then(function () {
browser.driver.wait(function () {
return browser.driver.findElement(by.css('#content > span > form > table > tbody > tr:nth-child(3) > td:nth-child(2) > input'))
}, 12000, 'Waited for the Company ID field to load');
})
});
});
});
I use the various browser.driver.wait's because I wanted to make sure I was waiting for the element to be present before interacting with it. I also use browser.driver.findElement actions instead of browser.findElement because they are non-angular pages.
The output looks like this:
Title now: WebService Web Service
But then I get the following error:
ScriptTimeoutError: timeout: Timed out receiving message from renderer: 10.000 (Session info: chrome=49.0.2623.110) (Driver info: chromedriver=2.19.346078 (6f1f0cde889532d48ce8242342d0b84f94b114a1),platform=Windows NT 6.1 SP1 x86_64) (WARNING: The server did not provide any stacktrace information) Command duration or timeout: 17.02 seconds"
I thought maybe it was because the new window wasn't ready to be interacted with but I check to see that their are more than 1 window open before going on to the second it. I see both tabs loaded before it fails but it stays on the first tab. I am writing this using Protractor using JavaScript because I usually interact with angular pages, and will in future test, but I need to do these actions first.
EDIT: I tried the below code, but still got:
Failed: timeout: Timed out receiving message from renderer: 10.000 (Session info: chrome=49.0.2623.110) (Driver info: chromedriver=2.21.371459 (36d3d07f660ff2bc1bf28a75d1cdabed0983e7c4),platform=Windows NT 6.1 SP1 x86_64) (WARNING: The server did not provide any stacktrace information) Command duration or timeout: 22.02 seconds Build info: version: '2.52.0', revision: '4c2593c', time: '2016-02-11 19:06:42'
browser.driver.getAllWindowHandles().then(function (handles) {
var popUpHandle = handles[1];
browser.driver.switchTo().window(popUpHandle).then(function (handle) {
browser.sleep(12000);
handle = browser.driver.getWindowHandle();
expect(handle).toEqual(popUpHandle);
browser.driver.executeScript('window.focus();');
})
});
2 Answers 2
You'll need to turn browser.ignoreSynchronization = true
on when you are accessing a non-angular page.
If It's pop up then, just as information for other possible users, I modified a bit the promise handle:
var handles = handlePromise.then(function (handles) {
popUpHandle = handles[1];
var handle = browser.switchTo().window(popUpHandle);
handle = browser.getWindowHandle();
expect(handle).toEqual(popUpHandle);
browser.driver.executeScript('window.focus();');
});
And it worked beautifully. After this point I could send the data to the inputs in the window and do whatever I wanted with it. Pretty.
You may check this site- http://engineering.wingify.com/posts/angularapp-e2e-testing-with-protractor/
-
I have browser.ignoreSyncronization = true in a beforeEach (see above). Do you think I should move it elsewhere? Both the starting page and new page are non-angular. Also, would handlePromise in the code you be browser.driver.getAllWindowHandles().then(function (handles { ?unknownletter– unknownletter2016年03月30日 13:08:29 +00:00Commented Mar 30, 2016 at 13:08
browser.ignoreSynchronisation is deprecated now.
For switching between Angular & Non-angular pages ,Use waitForAngularEnabled().
If set to false, Protractor will not wait for Angular $http and $timeout tasks to complete before interacting with the browser. This can cause flaky tests, but should be used if, for instance, your app continuously polls an API with $timeout.
Call waitForAngularEnabled() without passing a value to read the current state without changing it.
Explore related questions
See similar questions with these tags.