In my index.html, I explicitly say:
window.myAppInstance = new MyApp.myAppConstructor();
In my todo-spec.js, I have the following setup:
describe('my web page', function() {
it('should have a "myAppInstance" object on the window', function() {
browser.get('https://my.web.page.com');
function myTest() {
return Object.keys(window.myAppInstance).sort();
};
var p = browser.driver.executeScript(myTest);
p.then(function(ret) {
console.log("yay");
console.log(ret);
}, function() {
console.log("error");
console.log(arguments);
});
});
});
But protractor doesn't find my app. Instead it finds null or undefined:
error
{ '0':
{ [WebDriverError: unknown error: Cannot convert undefined or null to object
(Session info: chrome=50.0.2661.102)
... and more garbage
But from Chrome's console, I can run
window.myAppInstance
just fine, and it prints out the object properly.
How can I access this window object from my protractor test?
Edit 1: More explicit about the constructors.
Edit 2: In my app, I'm using angular's manual bootstrapping. Upon further investigation, I can add this line to my test:
<snip>
browser.get('https://my.web.page.com');
**browser.pause()**
<snip>
My steps now: 1) Hit F12 to bring up Chrome's developer tools 2) Look in the console. Note an error. My app has crashed. 3) Manually hit the refresh button on the browser. 4) Note how the app refreshes and everything loads beautifully. Scratch my head in puzzlement. Conclude that it's probably that somehow, launching the page programmatically with
browser.get('https://my.web.page.com');
is different enough from opening the browser up and typing in that URL to break it.
I'm wondering now, What about running the tests with protractor would cause my app to fail?
There could be a timing issue - the value is not yet available and you might need to wait for it:
function waitForKey() {
return browser.executeScript("return window.myAppXXXXXXXXXXXXX");
}
browser.wait(waitForKey, 5000);
var p = browser.executeScript(myTest);
// ...
Your object myAppXXXXXXXXXXXXX
is probably not yet instantiated at the time myTest
is executed. If that's the case, then one solution is to call executeAsyncScript
instead to return the keys of your object once the object is present:
function myTest(callback){
if (window.myAppXXXXXXXXXXXXX) {
callback(Object.keys(window.myAppXXXXXXXXXXXXX).sort());
} else {
setTimeout(myTest, 30); // try again in 30ms
}
}
browser.driver.executeAsyncScript(myTest)
.then(function(ret) {
console.log("yay");
console.log(ret);
}, function() {
console.log("error");
console.log(arguments);
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With