Using Javascript along with Protractor to automate tasks and manipulate increment counters

After previously posting a similar question, I wanted to clarify and focus my query further. That's why I am reposting here (should I continue editing the previous post instead?)

I'm currently working on writing end-to-end test specs for AngularJS using Protractor.

Within the Protractor spec, I am incorporating JavaScript as well.

The issue I am facing is that the JavaScript counter variables are not functioning as expected.

Let me share the relevant code snippet below:

// The code within this describe block has been perplexing :( Let's refer to it as 'sample 1'

//'use strict';

describe('list page ', function () {
    it('should list page', function () {

        browser.get('/list');

        var counterA = 0;

        element.all(by.repeater('page in pages')).each(function (page) {

            counterA++;
            //console.log(counterA);
        })

        //console.log(counterA);

        // This expectation needs to hold true :(

        expect(counterA).toBeGreaterThan(0);
    })
});

// Testing against a Protractor spec; written within the same js file. We'll call this 'sample 2'

bigitems = [["somevalue", "t", "y"], ["somevalue", "somevalue", "y"]];
counterB = 0;

for (smallitems in bigitems) {
    for (item in bigitems[smallitems]) {
        if (bigitems[smallitems][item] == "somevalue") { counterB++; }
    }
}

console.log(counterB)

One observation is that 'sample 2' with counterB is functioning correctly and returns '3' to the console. However, 'sample 1' returns 0 for counterA outside the .each{} block.

Below is the console output.

Using the selenium server at http://localhost:4444/wd/hub
3
0
1
2
3
4
5
6
.

Finished in 11.877 seconds
1 test, 1 assertion, 0 failures

Once again, thank you to everyone who assisted me with this matter previously.

Answer №1

It is not possible to accomplish the task that way due to the asynchronous nature of Javascript. This issue arises because expect does not wait for element.all.each to complete.

To resolve this, using promises is necessary. However, a challenge emerges as element.all.each does not currently return a promise (refer to here for ongoing discussions).

There are several alternative approaches available to address this situation.

-If the goal is solely to count the number of elements, the following solution can be used:

it('sample', function() {
  element.all(by.repeater('page in pages'))
    .then(function(elements){
      return elements.length;
    })
    .then(function(count){
      expect(count).toBeGreaterThan(0);
  });
});

-Alternatively, the count can be checked with the following simplified code:

it('sample', function() {
  expect(element.all(by.repeater('page in pages')).count()).toBeGreaterThan(0);
});

-For manual counting, another option involves calling element.all twice:

it('sample', function() {
  var count = 0;
  element.all(by.repeater('page in pages'))
  .then(function(){
    element.all(by.repeater('page in pages')).each(function(item){
      count++;
    });
  })
  .then(function(){
    expect(count).toBeGreaterThan(0);
  });
});

-Another method includes iterating through elements and incrementing a counter:

it('sample', function() {
  var counterA = 0;
  element.all(by.repeater('page in pages'))
    .then(function(elements){
      elements.forEach(function(entry){
        counterA++;
      });
    })
    .then(function(){
        expect(counterA).toBeGreaterThan(0);
    });
});

-Similarly, the count can be achieved with this approach:

it('sample', function() {
  element.all(by.repeater('page in pages'))
    .then(function(elements){
      var counterA = 0;
      elements.forEach(function(entry){
        counterA++;
      });
      return counterA;
    })
    .then(function(counterA){
        expect(counterA).toBeGreaterThan(0);
    });
});

Hopefully, these options provide assistance in resolving the issue.

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

AngularJS custom filter for ng-repeat sorting conditions

I am having difficulty understanding how to create a custom filter. I want the function to filter by ItemID from a dropdown. It is currently working, but I need it to stop filtering if the type is value 8. This is because I am modifying the dataset where i ...

Scanning through a directory to find fragments of a file's title

Currently, I am in the process of creating a media viewing platform that automatically downloads new episodes of TV shows. One obstacle I have encountered is the need to specify a source for the video content, as each episode download has a unique naming ...

Retrieving parameters from the URL in Angular

I'm facing an issue with my app. I am currently using a factory to manage data for two controllers. When I click on a link that redirects me to another view with a specific URL, I want to reuse the last tag in the URL by slicing it like this: window. ...

Node.js using Express: Modifying response data for specific route

I've searched through numerous resources but haven't been able to find a solution, so I'm reaching out for some assistance! :) I have developed a UI5 Application using Node.js with Express on the server-side. The data is retrieved from a SQ ...

Why would one pass in the value of undefined?

It has come to my attention that jQuery and related plugins like jQuery.UI often pass undefined as a parameter into their anonymous functions within module definitions. For example: (function($, undefined) { ... })(jQuery); On the other hand, I have obse ...

Utilize a dynamic URL within the HTML audio element

Currently, I am working with the use of the audio tag in HTML and AngularJS. I need to specify the source of the audio file I want to play, as shown below. <audio src="http://localhost/audio/221122/play/212223.mp3" audio player controls p ...

Discovering the world of Promises in TypeScript and understanding how to return specific types

Transitioning from coding in Clojure for the past two years to TypeScript has been an interesting journey. However, I've hit a bit of a roadblock today. The issue lies with my interface: interface ICustomer { id: number, first_name: string } I ...

Angular: the directive following the expression

Here is a directive and its corresponding definition that I'm working with: <div editor> {{markdown.html}} </div> The directive editor() looks like this: function editor() { return { restrict: "A", link: function (scope, ele ...

What is the process for inputting client-side data using a web service in ASP.NET?

Currently experimenting with this: This is my JavaScript code snippet: function insertVisitor() { var pageUrl = '<%=ResolveUrl("~/QuizEntry.asmx")%>' $.ajax({ type: "POST", url: pageUrl + "/inse ...

Is there a way to extract a PDF file from a URL where the document is embedded within the HTML code?

My Objective: I aim to extract the financial transaction amount from a PDF file that is dynamically loaded on a web page using JavaScript. For instance, on a site like . Upon clicking the 'View Document' button, the PDF file opens in my browser ...

Creating a jQuery accordion: A step-by-step guide

I'm currently working on building a dynamic accordion using jQuery where only one element can be open at a time. When a new element is opened, the previous one should close. I've managed to make it open and hide the button when opening it, but I ...

Tips for successfully passing an object via a Link

I am trying to pass an object through a Link component in react-router v6. Can someone please guide me on how to achieve this? Below is a snippet of my code where the user should be directed to another component. import React from 'react' import ...

Displaying two div elements horizontally using Material-UI

Can the styled utility from mui be used to align 2 divs side by side? The documentation examples don't seem to cover this specific scenario. While answers on this and this address it, they don't relate to mui / material ui. I attempted the fol ...

Aligning hyperlink with full-height image within a table cell (navigation buttons)

I am currently working on creating a traditional navigation bar that occupies 20% of the screen width and consists of 3 buttons. Each button is supposed to have an icon that is centered both vertically and horizontally. Additionally, I want the buttons to ...

Using jQuery to target the td:nth-child selector inside a document.ready function is not viable

Currently, I am working on a language learning project where I import a table of German words and their English translations from a .csv file using the jQuery.csvToTable plugin. My goal is to replace the words in the cells with an HTML input when the lang ...

Cease the execution of processes once a Promise has been rejected

My current code is functioning correctly, but I am facing an issue where if an error occurs, I want it to halt all other promises in the chain. Specifically, when chi.getCommand(val1, val2) returns a reject and triggers the exception catch block, I need to ...

Do the items appear on screen only once you start typing in AngularJS?

Most things are working well except for a couple of issues Code var app = angular.module("MyApp", []); app.filter('offset', function() { return function(input, start) { start = parseInt(start, 10); return input.slice(start); }; } ...

Tips for resolving Type Error in an Ionic Framework

Can anyone help me troubleshoot this issue: core.js:1449 ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'slug' of undefined TypeError: Cannot read property 'slug' of undefined Here is the code I am using: ...

I keep receiving a blank request body while using express.js

I'm having trouble retrieving data from my database as the body of the request is empty. I've tried using parse-body and CORS, but it's still not working. I attempted various solutions without success. Backend code: const bodyParser = requir ...

Securing JSON-based RESTful services

I am in the process of developing a web application, where I have established a clear separation between my "frontend" server using Lighttpd to serve index.html and javascript. My frontend, powered by Backbone.js, is connected to my Node.js backend webser ...