whd whd - 4 months ago 103
Javascript Question

Protractor infinite loop

In previous question I have problem with clicking button until it will be disabled answer was:

var nextPage = function () {
if (element(by.css('[ng-click="vm.nextPage()"]')).isEnabled()) {
element(by.css('[ng-click="vm.nextPage()"]')).click();
nextPage(); // next page
}
else {
return; // the element is not enabled, last page
}
}


I had to change it a little so my code looks now like this

var nextPage = function() {
if (element(by.id('next')).isEnabled()) {
element(by.id('next')).click().then(function() {
browser.sleep(1000);
nextPage(); // next page
return;
});
} else {
return; // the element is not enabled, last page
}
return;
}


but now it jumps into infinite recursive calls so next step cant be performed, how couldn't I change it, without using
.then
function does not work at all.

Answer

The problem is that the recursion base case is never met and it never exists the recursion.

Remember that everything in protractor is a promise, isEnabled() in your case is an unresolved promise which is always "truthy". This is why you always go to the next loop regardless of the real isEnabled value and eventually get the maximum recursion depth error.

Resolve the promise explicitly to get the real isEnabled boolean value:

element(by.id('next')).isEnabled().then(function (isEnabled) {
    if (isEnabled) {
        // ...
    } else {
        return; // the element is not enabled, last page
    }
});

As a side note, shameless promotion that could have helped catch this issue earlier - the eslint-plugin-protractor and it's rule to catch when protractor promises are used inside if conditions directly without being explicitly resolved. Here is what it would output if executed against a code like posted in the question:

$ eslint test.js
/path/to/test.js
  2:5   warning  Unexpected "isEnabled()" inside if condition  protractor/no-promise-in-if 
  4:13  warning  Unexpected browser.sleep()                    protractor/no-browser-sleep
Comments