protractor e2e testing Returning Promises from utility steps

775 Views Asked by At

I'm fairly new to protractor and promises in general. I've had a look around, and although there's many posts out there about returning promises, or the results from queued actions none of them make much sense to me, so i'm after a fairly easily described answer to what I hope is a simple question!

I am trying to write some protractor tests for my angularjs website.

I am using bootstrap and angular mainly, no other third party libraries, other than the occasional angular add-on such as toaster, and bootstrap modal.

I have several 'arrangement steps' before I get to the assertion part of my test. Let's say :

  • a) Person logs in
  • b) Person accesses options form ( which may or may not be displayed already on the screen depending on some external factors, but if it's not present they can open it with a button press ).
  • c) Person performs an action on the options form.
  • d) assert that the text box on the form now contains the correct value.

I can get my test to pass quite easily when the form is already on the screen, but the bit that's getting me stuck is step b) where I need to check first if the form is active and click a button if it's not pefore proceeding to step c.

I've tried to return the promise from isDisplayed like so :

//
// Is the user settings form active at the mo?
//
function _isUserSettingsFormActive()
{
    var result = element(by.id(logoutFormID)).isDisplayed;
    return result;
}

But if I call .then on _isUserSettingsFormActive() I get the following error :

[31mTypeError: undefined is not a function[0m

However if I output the results of _isUserSettinsFormActive() I see the below, so I know it's returning something :

function () {
return self.elementArrayFinder_[fnName].
apply(self.elementArrayFinder_, arguments).toElementFinder_();
}

All I want to do is check if an item exists and act on that before performing my assert.

It needs to be in a function, as this code will be used in many places throughout my test suit. It's not the 'expect' itself, more a step that may or may not need an action to set up the browser for my test to pass.

2

There are 2 best solutions below

2
On BEST ANSWER

isDisplayed is a function, so it should be called like that:

function _isUserSettingsFormActive()
{
    var result = element(by.id(logoutFormID)).isDisplayed();
    return result;
}
0
On

Protractor does not work like the Java or C# bindings of Selenium would (it's funner but more work to achieve what would be simple actions in Java or C#). It would be safer to return a count promise if the options form is also not in the DOM but if it is in the DOM and just hidden you could use isDisplayed(). I wrote two examples below for both situation including clicking the button depending on the condition.

Option 1 (Not present in DOM and not displayed):

function _isUserSettingsFormActive() {
    //$$('#logoutFormId') is the equivalent of element.all(by.id('logoutFormId'))
    $$('#logoutFormId').count().then(function(num){
         if(num < 1) {
            element(by.id('openLogoutButton').click();
         }
    });
};

OR

Option 2 (Present in DOM but not displayed):

function _isUserSettingsFormActive() {
    //$('#logoutFormId') is the equivalent of element(by.id('logoutFormId'))
    $('#logoutFormId').isDisplayed().then(function(visible){
         if(!visible) {
                element(by.id('openLogoutButton').click();
         }
    });
};