简体   繁体   中英

How to get a boolean value for element visibility in Protractor and return it before other code executes?

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.

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();
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM