Challenges with asynchronous actions in Webdriver.io: handling the sequence of clicking on an element and input

In my automated testing script, I am faced with the challenge of accounting for "chosen selects." My current approach involves using webdriver.io and referencing the API documentation available at

The specific task at hand is to trigger a click on 'a.chosen-single,' which in the context of "chosen" signifies a user interacting with a select element. This action directs the user's focus towards a text input field, enabling them to filter through options seamlessly - highlighting why the chosen feature is valuable. Subsequently, I aim to simulate the process of entering text as if done by a user.

However, the issue lies in my existing script, where all chosen-select elements are clicked first, followed by the keystrokes being entered afterward. Consequently, the text input values are only captured from the final chosen-select field.

To address this anomaly, I have incorporated a pause() function after each element click operation. Expecting the pause to occur following every click, it appears that the delay waits until all selections have been made before executing the keystrokes together towards the end, resulting in the last element having the combined value 'FIL12'.

this.click(container + ' a.chosen-single').then(function(){
                console.log('clicked');
                console.log('value', fields[selectName]);
                this.pause(1000)
                this.keys(fields[selectName])
                //press enter to finalize selection
                //.keys('\uE007')

                console.log('keys pressed');
              });

The terminal output reflects this behavior:

clicked
value F
keys pressed
clicked
value IL
keys pressed
clicked
value 1
keys pressed
clicked
value 2
keys pressed

I am seeking assistance in resolving this issue so that subsequent tasks do not queue up until the entire set of keystrokes has been effectively entered. Your help would be greatly appreciated.

Answer ā„–1

halt function also returns a promise, requiring you to utilize then after calling halt in order to run the code block following the completion of the halt callback.

this.halt(2000).then(function() {
  this.type(inputs[name])
  //press tab for next field
  //.type('\uE004')

  console.log('input typed');
});

Answer ā„–2

After much trial and error, I finally cracked the code myself. The issue stemmed from my use of a for(){} loop to cycle through various fields that needed to be filled in. The problem was that the loop executed each command without waiting for a specific select field to finish being set with the correct value (click on select, type value, press enter). To resolve this, I devised a solution where I stored the selector and value, encapsulated them in a function, and then added each complete function to a queue. By sequentially executing each function and calling the next one within the 'then' callback of the 'keys' command, I ensured that the next function only ran after the enter key was pressed on the previous select.

const webdriverio = require('webdriverio');

let tester = {};

const options = {
    desiredCapabilities: {
        browserName: 'chrome'
    }
};

const params = {
  // Redacted for privacy reasons
};

// Fields altered due to confidential information
const fields = {
testField: 'John Smith', 
testSelect: 'USA'

};

const execQueue = [];


const wrapFunction = function(fn, context, params) {
    return function() {
        fn.apply(context, params);
    };
};



function fillFields(driver, fields){
driver.iter = 0;
  driver.elements('select + .chosen-container').then(function(result){
    console.log('Number of selects:', result.value.length);
    tester.totalSelects = result.value.length;
  });

  // Iterate through all selects and inputs
 for(property in fields){
    let p = property;
    // Preserve value of property using closure
    (function(p){
      // If chosen input, choose from list
     driver.isExisting('div.' + p + ' .chosen-results').then(function(result){

       if(result === true){

        driver.elements('div.' + p + ' select').then(function(result){
          // Loop through each select (expiration date has two selections in one container)
          for(let i=0;i<result.value.length;i++){
            let s = result.value[i].ELEMENT;

            // Closure
            (function(s){

            // Find the name of each select
            driver.elementIdAttribute(s,'name').then(function(result){
              // Find the chosen container after select
              let container = 'select[name=' + result.value + '] + .chosen-container';

              let selectName = result.value;
              // Find corresponding a.chosen-single

              const qfunction = function(link, value){
                console.log('Value in queue function:', value);
                driver.click(link).then(function(){
                      this.keys([value, '\uE007']).then(function(){
                       driver.iter++;
                        execQueue[driver.iter]();
                      });
                });
              }

              execQueue.push(wrapFunction(qfunction, this, [container + ' a.chosen-single', fields[selectName]]));

             if(execQueue.length == tester.totalSelects - 1){
                  execQueue[driver.iter]();
              }

              console.log('Queue so far:', execQueue.length);

            });

            })(s);



          }

        });



        }else{

         driver.addValue('input[name=' + p + ']', fields[p]);

        }

      })

    })(p);

  }

};


webdriverio
  .remote(options)
  .init()
  .url('https://' + params.domain + '/' + params.clientId + '/?scope=' + params.scope +  '&cart=' + params.cart + '&cfg=' + params.cfg + '&progress=' + params.progress + '&language=' + params.language + '&currencyId=' + params.currencyId + '&debug=nocache') 
  .then(function(result) {

    fillFields(this, fields);

  });

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

Issue with TypeScript in VSCode: "Unable to save file 'x' as it would overwrite the input file."

As I work on improving my JavaScript quality with TypeScript in VSCode, Iā€™m encountering an issue with my tsconfig.json file. It keeps throwing errors when trying to write my .js files, specifically displaying the message: "Cannot write file 'lib/c ...

Issue with the react-native-autocomplete-input where the list does not close after selecting an option

After selecting an item from the list in my react-native-autocomplete-input, the list does not close. let Location = (props) => ( <View style={styles.formItem}> <Autocomplete data={props.autocompleteResults.predictions} de ...

Are there any jQuery plugins available that can automatically resize images to fit within a div in a collage-style layout?

I'm interested in creating a layout similar to what I see on for my portfolio project. My goal is to showcase images that span the full width, occupy 1/4 or 1/2 of the div, and fade in smoothly. I envision them arranging themselves in a dynamic news ...

Tips on how to utilize JavaScript to display data on a page without the need for refreshing, updating every 2-5

Could you please assist me? I am working on a CRUD application and have created a function called loaddata();. My issue is that when another user adds data, it should be displayed in my table without the need to refresh. Is there a way to achieve this? fun ...

The subsequent middleware in express next() is failing to trigger the next middleware within the .catch() block

I'm facing a puzzling issue with my POST route. It's responsible for creating transactions through Stripe using the Node package provided by Stripe. Everything works smoothly until an error occurs, such as when a card has insufficient funds. Whe ...

The use of PUPPETEER_DOWNLOAD_HOST has been phased out. It is recommended to use PUPPETEER_DOWNLOAD_BASE_URL moving forward. / Puppeteer

Trying to install puppeteer, I followed the installation guide. However, after a few seconds, I encountered this error: .../node_modules/puppeteer postinstall$ node install.mjs ā”‚ PUPPETEER_DOWNLOAD_HOST is deprecated. Use PUPPETEER_DOWNLOAD_BASE_URL ins ...

Why is it important to avoid reassigning parameters in real-life situations? Can you provide an example of a problem that may arise from this practice?

Many inquiries focus on the best methods to follow the no-param-reassign linting rule, but there is a lack of requests to demonstrate the reasoning behind the rule. It is common to hear claims like 'Assigning values to variables defined as function p ...

Steps for creating an Xpath to select the next div using the sibling axis

Can anyone help me with retrieving the Tax Price using the sibling concept? I've tried using the XPath below but it seems to not be working properly. This is my code snippet: //div[@class='grid_3 d-grid_10']//label[contains(text(), 'T ...

What is the step-by-step process for incorporating the `module` module into a Vue project?

ERROR Compilation failed with 6 errors 16:20:36 This specific dependency could not be located: * module in ./node_modules/@eslint/ ...

Leveraging Promises for Concurrent In-Memory Processing

We are currently working on a project that involves processing approximately 5,000 objects, with each object requiring between 200-500 milliseconds to process. One of the developers on our team has suggested utilizing promises to handle the concurrent proc ...

Image not displaying correctly with Neatshow JS Plugin

I've added neatshow.min.js to my project and I'm following all the instructions in the script. The first step is to hide images with CSS, then show them using the script. Here are my instructions: $(window).ready(function(){ $('img&ap ...

Error message: webpack's CLI has been relocated to its own package named webpack-cli

I've been diving into the world of ReactJS and decided to follow a tutorial here on installing React. This is all new to me. After completing the installations as demonstrated in the video, I proceeded to run this command in the project's main f ...

export module from the express framework

function affirm(){ console.log("yes") } Element={} Element=affirm Element.something="something" Element.nothing="nothing" DEPICTED IN WEB BROWSER: In the code snippet above, if you were to console.log(Element), it would display ...

What is the best way to conceal a website's URL?

Is it possible to hide the actual URL some.otherdomain.com and show only domain.com to visitors of my website? I am looking for a way to mask the URL, perhaps through .htaccess or javascript. Is there any solution available? ...

"Functionality requiring Javascript is not enabled following an AJAX call until the page is

I've created a system that can generate an online form page and send it to a printer. This system utilizes AJAX to extract data from an existing page and send it to a Java servlet. The servlet then constructs the HTML and sends it back, where it is d ...

Reload a single php page by utilizing a different page

Whenever I click on a button on my PHP page (dashboard.php), it opens a pop-up page (viewstatus.php). On this pop-up page, I update some data and then click the submit button. However, after submitting the data, the pop-up should close and the dashboard. ...

Error Encountered During JavaScript Form Validation

Currently, I am troubleshooting a website that was created by another developer. There is a form with JavaScript validation to ensure data is accurately entered into the database. However, I am puzzled as to why I keep receiving these alert messages. Pleas ...

Populate vue-multiselect with links from the router

Is there a way to populate the vue-multiselect dropdown with <router-link> options? Typically, router links are defined declaratively in the <template>, but vue-multiselect relies on binding an array of options. Any suggestions on how to approa ...

Tips for managing numerous HTTP requests in Angular 6

I have a method that is trying to chain together 3 requests like this: showProfileDetails() { this.getUserInfo(this.currentUser.id).pipe( mergeMap(e => this.getAccounts(this.currentUser.id) ), mergeMap(e => this.getPayments ...

Refreshing the package using Bower

I'm facing an issue while trying to upgrade angular from version 1.0.5 to 1.0.6 using Yeoman. Despite clearing the cache and checking the Github repository, it still installs version 1.0.5. Is there a workaround to force the update to version 1.0.6? ...