Reputation: 2268
I am writing a page object for a non-Angular page that I need to use to get to the Angular app I am testing.
I just want some methods that provide information about the state of components on the page: is a menu expanded or collapsed? When I call these accessor methods, I want them to return true
or false
. The problem is that 'isDisplayed()
' doesn't just return a boolean
value. And it seems that when I call these accessor methods from other code, they don't 'wait' for the value to be returned. They just go on executing. How do I prevent that?
"use strict";
function Page () {
this.menuAccessor = element(by.css("blah"));
this.menuContainer = element(by.css("blahblah"));
}
Page.prototype.expandMenu = function () {
if(!this.isMenuExpanded()) {
this.menuAccessor.click();
}
};
Page.prototype.collapseMenu = function () {
if(this.isMenuExpanded()) {
this.menuAccessor.click();
}
};
Page.prototype.isMenuExpanded = function () {
return this.menuContainer.isDisplayed().then(
function(isVisible) {
if(isVisible) {
console.log("Menu is expanded");
} else {
console.log("Menu is not expanded");
}
return isVisible
},
function (err) {
console.log("Menu is not expanded");
return false;
}
)
};
module.exports = Page;
So, I was trying to test this out:
var Page = require('./../blahblah/Page.js');
describe('Test page object',function(){
//Page is non-Angular
browser.ignoreSynchronization=true;
var p = new Page();
var isExpanded = p.isMenuExpanded();
console.log("State of menu: " + isExpanded);
console.log("Logging something else");
});
When I execute this, I get this output:
/blahblah;bah/node_modules/protractor/built/cli.js /Users/someperson/blalbahlbah/config.js
[14:46:20] I/local - Starting selenium standalone server...
[14:46:20] I/launcher - Running 1 instances of WebDriver
[14:46:21] I/local - Selenium standalone server started at http://192.168.2.4:59574/wd/hub
State of menu: ManagedPromise::464 {[[PromiseStatus]]: "pending"}
Logging something else <== Test method goes on executing before state of menu is known.
Started
No specs found
Finished in 0.001 seconds
chrome
Menu is not expanded <== The state of the menu is determined after the test method finishes executing.
[15:05:14] I/local - Shutting down selenium standalone server.
[15:05:14] I/launcher - 0 instance(s) of WebDriver still running
[15:05:14] I/launcher - chrome #01 passed
Process finished with exit code 0
How do I accomplish what I want? I can't find a good example online for how to develop these kinds of accessor methods for providing information about the state of UI components in JavaScript.
Upvotes: 1
Views: 1070
Reputation: 474161
The usual way to solve this problem is to pass around promises and resolve them once you need an actual value from the promise:
Page.prototype.expandMenu = function () {
var self = this;
this.isMenuExpanded().then(function (isExpanded) {
if (!isExpanded) {
self.menuAccessor.click();
}
});
};
Page.prototype.collapseMenu = function () {
var self = this;
this.isMenuExpanded().then(function (isExpanded) {
if (isExpanded) {
self.menuAccessor.click();
}
});
};
Page.prototype.isMenuExpanded = function () {
return this.menuContainer.isDisplayed();
};
Upvotes: 2