Protractor patiently anticipates the presence of several elements

After loading the following elements into the DOM using AJAX:

<div class="elm_class"></div>
<div class="elm_class"></div>
<div class="elm_class"></div>

I need to wait for a specific number of elements to be present in my Protractor test. Here is what I've tried so far:

function checkElements(css, i) {
    var elements = element.all(by.css(css));
    var EC = protractor.ExpectedConditions;

    if (elements.length > i) {
        return EC.presenceOf($$(".heading-description.uplevel").get(i));
    } else {
        return setTimeout(checkElements(css, length), 1000);
    }
}

browser.driver.wait(checkElements(".elm_class", 3), 10000);

However, this approach is not working as expected and it throws an error:

maximum call stack size exceeded.

I would appreciate it if someone could provide guidance on how to incorporate a "promise" object back into the wait function.

Answer №1

Create a custom Expected Condition for waiting until a specified number of elements matching a selector are present:

function waitForElements(elements, n) {
    return function () {
        return elements.count(function (count) {
            return count >= n;
        });
    };
}

browser.wait(waitForElements($$(".element_selector"), 3), 10000);

An important point to highlight is that the waitForElements function returns a function that browser.wait() will continue to run until it resolves to true or a timeout occurs.

Answer №2

browser.wait will continuously loop until it returns true within the specified number of milliseconds, so avoid using a setTimeout function inside it. Additionally, make sure to utilize .count() instead of .length when counting the elements found by .all

function checkIfTrue(css, expectedCount){
  var elements = element.all(by.css(css));

  // Count the number of elements found
  return elements.count().then(function(elementCount) {
    // Return false if there are not enough elements, causing browser.wait to continue looping
    return elementCount >= expectedCount;
  });
};

browser.driver.wait(checkIfTrue(".elm_class", 3), 10000);

// After waiting for the elements, perform additional checks
// I am not familiar with EC usage, so I cannot guarantee the functionality of this part of the code
var EC = protractor.ExpectedConditions;
expect(EC.presenceOf($$(".heading-description.uplevel").get(m1I))).toBe(true);

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

Transform the date and time into a timestamp with milliseconds while adding one month

Issue with high chart not rendering in Internet Explorer and Safari has been identified. The solution to this problem is converting the date from the API into a timestamp in milliseconds. Here is an example code snippet for conversion: var date = '201 ...

An automated feature that smoothly transitions a large image onto the screen

I came across a plugin, possibly a slideshow plugin, that smoothly slides a large image along the y-axis. It's hard to explain, but imagine the visible image is only 600px by 300px, while the actual image is 600px by 600px. This plugin would scroll t ...

Implementing a function trigger on button click using jQuery

I recently created a jQuery code snippet: <span id="counter-up" class="timer"> </span> <div class="buttons"> <button id="trigger">Find out!</button> </div> </div> <div class="container"> </div> & ...

How to synchronize $scope variables between controllers in AngularJS

As a newcomer to Angular, I have a seemingly simple question regarding setting up a comments system for articles. I've implemented two angular controllers - one for loading comments upon page load and another for submitting new comments to the server. ...

Can you provide tips on how to center the title on the page?

Currently, I am working on codepen.io and have been tasked with creating a paragraph that includes a title. However, my dilemma lies in the fact that I need this title to be center-aligned without directly altering the "x" value. Unfortunately, CSS is not ...

What is the method for selecting an li element within a ul list using Selenium in Python?

My goal is to automate the process of clicking on 'National Data' on a specific website using the Selenium package in Python. The website I am referring to can be found at . Although I attempted to achieve this automation, I encountered difficul ...

Guide on including the sequential images within the previous and next button of a carousel

Currently working on my portfolio website, I have managed to code a carousel for displaying my images. The only challenge I am facing now is how to make the 'Next' and 'Prev' buttons show the next and previous images respectively. Does ...

Having difficulty retrieving the data from an excel spreadsheet

I am encountering an issue where my program is returning values like [[Ljava.lang.String;@490ab905 instead of the actual data present in an excel file, specifically the user names. I have used jxl and data provider, but I am not very familiar with data pro ...

Is it possible to load asynchronous JS and then execute functions?

Is there a way to make my script behave like the Google Analytics JavaScript snippet? Here is an example of what I have: (function(d, t) { var g = d.createElement(t), s = d.getElementsByTagName(t)[0]; g.src = 'myjs.js'; s.par ...

Using Google Apps Script to input data into the next available row

Utilizing Google Apps Script, I am retrieving data from another spreadsheet and storing it daily in a sheet named "DATABASE". Although my current solution is basic, it keeps overwriting existing data. I wish to enhance the script to copy data from the imp ...

Harvesting Angular information using Selenium

Here is some HTML code that can be extracted using a Selenium driver: <td colspan="2"><strong>Owner</strong> <div ng-class="{'owner-overflow' : property.ownersInfo.length > 4}"> ...

Mapping a list with sections can easily be achieved by breaking down the elements

I'm facing an issue with listing array data under sections using .map in React. I know how to use .map to list the entire array, but struggling to list each item under its respective section. Currently, I have to use .map separately for each section. ...

Literal Route Waypoints Guidance Service

I am currently working on an angularjs directive that utilizes the Google Maps Direction Service. In my controller, I have a getFunction that watches for changes in a scope variable. Once the scope variable changes, it triggers the calculateAndDisplayRoute ...

The most effective way to ensure precise results is to implement explicit waits

I've been conducting numerous tests using Selenium and I am determined to enhance the strength of my tests. I'm wondering whether I should utilize ElementToBeClickable, elementExists, or both for maximum efficiency. For instance, which method sh ...

Toggle the functionality of the login button in foundation

I am currently utilizing the front-end framework Foundation. My question is, how can I modify this menu so that the Log in button is only enabled when both the Login and Password input fields are filled with text? <form data-abide="ajax"> <div ...

Extracting data from websites using Node.js

Currently, I am tackling a task involving web scraping. To give you some context, I take the URL from my webpage and extract the content located between the <body> tags. My objective is to then display this extracted content on my website. Through my ...

Avoid the occurrence of the parent's event on the child node

Attempting to make changes to an existing table created in react, the table is comprised of rows and cells structured as follows: <Table> <Row onClick={rowClickHandler}> <Cell onCLick={cellClickHandler} /> <Cell /> ...

Implement an event listener on an element dynamically inserted into the DOM through an AJAX request

My issue involves a set of checkboxes being dynamically added to a document using an Ajax call. <input type='checkbox' checked class='import'> <input type='checkbox' checked class='import'> <input typ ...

Monitor when a button in a grapesjs modal is clicked

When using the Grapesjs Editor, I needed a modal with a form inside it. Upon clicking the submit button, I wanted to trigger a Function that would make an ajax call. To achieve this, I attempted to create a custom component by extending it from the defaul ...

Learn how to remove data from a React JS application without causing a page refresh by utilizing the useLoaderData() function in conjunction with React Router

I am working on preventing my table from refreshing with the new version of userLoadData from react-router-dom@6 after deleting some data. In an attempt to achieve this, I created a function called products() within useLoaderData. While this function succ ...