Utilize WebdriverIO to loop through elements and trigger a click event on a link

I am currently using Javascript and webdriverio (v2.1.2) for data extraction on an internal website. The process involves:

  • Authentication
  • Opening the necessary URL once authenticated
  • Searching for an anchor tag with a specific keyword on the new page
  • Clicking on the found anchor tag

The code snippet below shows what I have attempted so far, which is working for the last two steps. However, in order to achieve this, I had to utilize Q and async. My goal is to use only Q for this task. Could someone assist me in achieving this using only Q?

    var EmployeeAllocationDetails = (function () {
'use strict';
/*jslint nomen: true */
var Q = require('Q'),
    async = require('async'),   
    _ead_name = 'Employee Allocation Details',
    goToEadFromHome;

goToEadFromHome = function (browserClient) {
    browserClient.pause(500);
    var deferred = Q.defer();
    browserClient.elements('table.rmg td.workListTD div.tab2 div.contentDiv>a', function (err, results) {
        if (err) {
            deferred.reject(new Error('Unable to get EAD page. ' + JSON.stringify(err)));
        } else {

        async.each(results.value, function (oneResult, callback) {
                console.log('Processing: ' + JSON.stringify(oneResult));
                browserClient.elementIdText(oneResult.ELEMENT, function (err, result) {
                    if (err) {
                        if (err.message.indexOf('referenced element is no longer attached to the DOM') > -1 ){
                            callback();
                        } else {
                            callback('Error while processing :' + JSON.stringify(oneResult) + '. ' + err);
                        }
                    } else if(!result){
                        console.log('result undefined. Cannot process: ' + JSON.stringify(oneResult));
                        callback();
                    } else if(result.value.trim() === _ead_name){
                        deferred.resolve(oneResult);
                        callback();
                    }
                });
            }, function (err) {
                // if any of the processing produced an error, err would equal that error
            if( err ) {
        // One of the iterations produced an error.
        // All processing will now stop.
            console.log('A processing failed to process. ' + err);
            } else {
            console.log('All results have been processed successfully');
            }
            }); //end of async.each

        }
    });
    return deferred.promise;
};

return {
    launchEad : goToEadFromHome
  }
})();
module.exports = EmployeeAllocationDetails;

For more information, you can refer to the related Github Issue link here

Answer №1

Using the async function is recommended in this case. The code provided is efficient as it executes tasks in parallel and handles errors effectively.

However, if you decide to remove the async function, there are alternative options available:

  • Utilize the Q flow control module
  • Manually replicate async's functionality
  • Create your own implementation

Incorporating Q's flow control may involve a pseudo-code similar to the following:

var getTextActions = [];
function createAction(element){ 
    return function(){
        return element.getText();
    }
}

each(elements, function(element){ getTextActions.push( createAction(element) ) }); 
Q.all(getTextActions).then(function(results) {
    //Iterate through results and resolve promise with corresponding element
} ); 

It is important to note that this approach may have lower performance compared to using async, as it retrieves text from all elements before resolving promises.

Creating a custom implementation, though not recommended, would involve pseudo-code resembling the following:

var elementsCount = elements.length; 
elements.each(function(element){
    element.getText(function(err, result){
        elementsCount --;
        if ( !!err ) { logger.error(err); /** Handle error **/ } 
        if ( isThisTheElement(result) ) { deferred.resolve(result); }
        if ( elementsCount == 0 ){ 
            deferred.resolve(null);
        }
    })
})

If you require further clarification or if the answer does not fully address your question, feel free to let me know so I can enhance the explanation.

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

Replace the hyperlink with plain text using JQuery

Is there a way to replace a hyperlink within an li element with different text but without removing the entire list item? <li class="pull-left"> <a href="#" class="js-close-post" data-post-id="1"> Close </a> </li> ...

Vue-Router functions only on specific routes

While my vue-router correctly routes the URL for all menu buttons, it's not displaying each Vue component properly. You can see a demonstration here. Here is a snippet of my HTML (using Vuefy) <div class="navbar-start"> <a ...

Displaying an error page instead of the error message when a backend or template engine error occurs

Whenever a template engine error occurs, it is displayed on the webpage. I am looking to implement a functionality where if our server is running in production mode, an error page will be shown instead of displaying our server's error directly. The m ...

How to identify the character encoding in a node.js request

Did you know that Facebook chat has a feature where it automatically detects and displays messages in a left-to-right format when typing in English, but switches to right-to-left style when adding right-to-left characters? I'm curious about how Faceb ...

Finding a way to choose and interact with elements at random using Selenium WebDriver in Python

One of the tasks in my todo list app is to randomly select an element and click on it to delete. Each element shares the same selector, with only the index changing (e.g.//*[@class="destroy"])[2]). I have code that generates random sentences an ...

Vue is unable to capture Cordova events

Creating a hybrid app using Cordova while incorporating VueJS for routing and AJAX requests has presented some challenges for me. Despite my efforts, I have been unable to capture certain Cordova events. Even the essential deviceReady event seems to be el ...

Step-by-step guide for implementing a scroll event on FancyBox

I am facing an issue with a large fancybox popup that contains a scroll function. I need to find a way to attach an event to this fancybox popup when scrolling. I have tried several different events, such as: $('.fancybox-inner').off("scrol ...

Avoiding the occurrence of moiré patterns when using pixi.js

My goal is to create a zoomable canvas with rectangles arranged in a grid using pixi.js. Despite everything working smoothly, I'm facing heavy moire effects due to the grid. My understanding of pixi.js and webgl is limited, but I suspect that the anti ...

The issue of receiving an undefined JSON response persists in an AJAX file upload scenario

Currently, I am utilizing Valum's Ajax File uploader for handling same-page file uploads. The issue I'm facing is that despite numerous attempts and variations in my script, I consistently receive "undefined" when trying to access responseJSON[&a ...

Some elements in the DOM appear to not be rendering even though they are present in the HTML source code

As a newcomer to web development, I have stumbled upon a perplexing issue. In my usage of d3.js (specifically the script found here), I have been attempting to incorporate additional features. I modified my JavaScript code to include a simple <p> ele ...

Positioning Images in Tailwind Modals

I'm currently working on building a modal using Tailwind in Vue, but I've run into some challenges with aligning the elements inside the modal as desired. I've experimented with removing certain Tailwind classes and have tried implementing ...

Separating the login/register functionality from the main app using the MEAN Stack

Apologies for my poor English! I have developed an application using the MEAN stack (MongoDB + Express.js + Angular.js + Node.js) with authentication utilizing passport.js and JWT (jsonwebtoken and express-jwt). What I aim to achieve? The login and r ...

What is the best way to create a function that allows us to "wait for ajax" to load before proceeding with the page and then easily reuse that function in other test methods

I have been experimenting with different waiting options, but I am unable to click the button. It seems like the AJAX is taking time to load the page. How can I create a function to wait for AJAX and use it in other methods when needed? for (int row = 1; ...

Establishing the value of "document.cookie"

Encountering issues while trying to set a cookie using different methods: Method 1: document.cookie = name + "=" + value + "; expires=" + date.toUTCString() + "; path=/"; This method only sets the value up to "name=value" wh ...

What is the reason for the error message "Why does the method getText() appear as undefined for the String type?"

When attempting to access the link using a different method, I encountered issues. After opening the browser, the link failed to open and when trying to retrieve the motorvehicle variable, I received error messages stating "The method getText() is undefi ...

difficulty arises when attempting to invoke a viewmodel from another viewmodel inside a ko.computed function

Is it possible to have two view model functions in my JavaScript where one references the other? I am encountering an error with this setup. Here are my view models: var userViewModel = function (data) { var _self = this; _self.ID = ko.obs ...

Execute a JavaScript function on a Node server following a click event in an HTML document

Hello everyone, I am currently working on a project using node.js in a Windows environment. With the help of the express module, I am trying to create a static page that includes a Submit form. When someone clicks the "Submit" button, I intend to execute a ...

Guide on building a REST API with Node.js Express.js and OracleDB to perform database updates

Looking for assistance with creating an API in Node.js to fetch and update data on the frontend. I am able to retrieve data using the provided code, but facing challenges updating it. React.js is being used for the frontend. var express = require("expr ...

Error: The specified element to insert before is not a direct descendant of this parent node

As I work on converting a jquery dragable script to plain javascript, I encountered an issue at the insertBefore point. The error message that pops up is: NotFoundError: Node.insertBefore: Child to insert before is not a child of this node. This particula ...

Unusual escape_javascript quirk witnessed in Ruby on Rails

Once the ajax method is called, the escape_javascript function starts outputting </div> </div> </div> for each rendered item. Despite thoroughly checking all closing tags multiple times, I can't seem to identify any errors. Could thi ...