Protractor never-ending cycle

In my previous question, I encountered an issue with clicking a button until it becomes disabled. Initially, the solution was as follows:

var nextPage = function () {
    if (element(by.css('[ng-click="vm.nextPage()"]')).isEnabled()) {
        element(by.css('[ng-click="vm.nextPage()"]')).click();
        nextPage(); // proceed to next page
    }
    else {
        return; // button is disabled, reaching last page
    }
}

However, I had to make some adjustments to the code and now it looks like this:

 var nextPage = function() {
  if (element(by.id('next')).isEnabled()) {
    element(by.id('next')).click().then(function() {
      browser.sleep(1000);
      nextPage(); // proceed to next page
      return;
    });
  } else {
    return; // button is disabled, reaching last page
  }
  return;
}

Unfortunately, this modification resulted in infinite recursive calls, making it impossible to perform the next step. I tried removing the .then function but then the code stopped working altogether. How can I correct this without causing endless recursion?

Answer №1

The issue lies in the fact that the recursion base case is never satisfied, causing the recursion to continue indefinitely.

It is important to keep in mind that every aspect of protractor operates as a promise, and in your specific scenario, isEnabled() is an unresolved promise which always evaluates to "truthy". This results in the loop continuing regardless of the actual value of isEnabled, leading to the error of reaching the maximum recursion depth.

To obtain the true boolean value of isEnabled, you need to explicitly resolve the promise:

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

On a related note, it's worth mentioning the shameless promotion of a tool that could have detected this issue sooner - the eslint-plugin-protractor along with its rule that identifies protractor promises being used directly within if conditions without explicit resolution. The output of this detection tool when applied to code similar to what was included in the original question would look like this:

$ 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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using references to pass variables in TypeScript [Angular 8]

I have several variables within the html of this component that are assigned their values by the typescript file. The declaration in the html is as follows: <h1>{{myproperty1}}<\h1> <h1>{{myproperty2}}<\h1> <h1>{{myp ...

Is there a minimum height restriction for v-select in Vuetify.js?

Looking at the code snippet provided below, I am facing an issue while trying to decrease the height of a v-select element. It seems like there is a minimum limit set for the height, as reducing it beyond height = 40 doesn't have any effect. Is there ...

Information is only displayed within the Node Request function and is not accessible to

I am currently developing a small web scraping tool using Node (Express) to search URLs from a list. However, I'm encountering an issue with accessing the results of the search outside of the request callback function in a forEach loop. Can anyone hel ...

Retrieve the dimensions of an image once rendering is complete, using Angular

I'm currently working on obtaining the rendered size of an image within a component. By utilizing the (load) event, I can capture the size of the image as it appears at that particular moment (pic1), as well as its "final" size after the page has fini ...

Tips for retrieving arguments within a method called from a template in vue.js?

Here is an example where I am attempting to call a method from the template and pass in some arguments. How can I access those arguments from within the method? Snippet from script: methods: { showBinaries(job, id) { let test_url = process.en ...

What is the best approach for implementing recursion within a foreach loop in TypeScript?

Problem Situation I am attempting to develop a customized typewriting effect similar to the one demonstrated here with a 100ms delay using Angular. The TypeScript code I have written for this purpose is as follows: private arr: string[] = ["Lead Dev ...

The filter is displaying incorrect categories

I am facing an issue with creating a work filter based on the last column which represents categories. When I select an option from the dropdown, I want to display only that specific category and hide the others. Currently, when I try clicking on an option ...

Strategies for selecting glyphs in SVG fonts based on their Unicode properties

My goal is to extract specific characters from SVG fonts created for music engraving. Music fonts typically include a large collection of characters (> 3500), but I only require a small subset of them for caching glyphs in compressed form to ensure quick a ...

Creating a recursive function to compute the average of elements within multi-dimensional arrays

How can I recursively loop through this multi-dimensional array while calculating the average by Standards? Here is the initial array, followed by my code (which loops through each level - not ideal), and then the Output. I'm seeking a function to op ...

Display data in Highchart legend only if it has values

In a unique scenario, I am required to compare various items and display the results in a chart. The user inputs two, three, or four article IDs and receives the corresponding data displayed in a chart. The issue arises when the user enters only two or th ...

How can I update two divs simultaneously with just one ajax call?

Is there a way to update 2 divs using only one ajax request? The code for updating through ajax is in ajax-update.php. <?php include("config.inc.php"); include("user.inc.php"); $id = $_GET['id']; $item = New item($id); $result = $item->it ...

What could be causing the issue preventing me from updating my SQL database through AJAX?

$(document).ready(function(){ $('.button').click(function(){ var clickBtnValue = $(this).val(); var ajaxurl = 'functions/delivered.php', data = {'action': clickBtnValue}; $.post(ajaxurl, da ...

Angular 6 - Outdated Functions

I'm having trouble updating the request options as they are now deprecated. I can't seem to locate the alternative option for this. Can anyone offer some assistance? import { Injectable } from '@angular/core'; import { HttpClient } fr ...

tips for iterating through a json string

When retrieving data from PHP, I structure the return like this: $return['fillable'] = [ 'field_one', 'field_two', 'field_three', 'field_four', 'field_five', ]; $json = json_ ...

Configuration of injected services in IONIC 2

I am curious about how the services from injected work in IONIC 2. Specifically, my question is regarding the number of instances that exist when one service is used in two or more controllers. Previously, I asked a colleague who mentioned that IONIC 2 op ...

a common pattern used to substitute website links

I am trying to modify my code that creates HTML links from plain text. While it currently works well, I want to exclude any links that contain .png or .jpg extensions. Does anyone have suggestions on how to adjust the regular expression? var urlPattern ...

Ways to mimic an Angular directive with a required field

Recently, I encountered a challenge that involves two directives: directive-a, directive-b. The issue arises because directive-b has a `require: '^directive-a' field, which complicates unit testing. In my unit tests, I used to compile the direc ...

Typing in Text within Kendo Textbox using Protractor

I'm encountering an issue with Protractor while trying to input text into a Kendo TextBox. The error message I receive is "ElementNotVisibleError: element not visible". Interestingly, when the text box is clicked on, the "style="display: none;" change ...

Is it possible to use both interfaces and string union types in TypeScript?

My goal is to create a method that accepts a key argument which can be either a string or an instance of the indexable type interface IValidationContextIndex. Here is the implementation: /** * Retrieves all values in the ValidationContext container. ...

Guide on verifying Unicode input in JavaScript?

I am looking to create a form where the user can only input Khmer characters (Unicode characters) and display an alert if they input anything else. Khmer Name: <input type="text" class="namekh" name="namekh"> To achieve this, here is a snippet of m ...