Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handle multiple elements with the same selector with nightwatch.js

I'm using nightwatch-cucumber with the use of PageObjects to automate tests. nightwatch-cucumber based on nightwatch.js. So, I'm completely new to JavaScript. So far, I prefered using Java as language for Selenium/WebDriver automation.

I want to edit multiple input fields with defined values. The problem is that all these input fields have the same selector. And the number of the input fields is not known at the beginning of a test or is different from test to test. So, I need a solution. In the "holy" java world I can do something like this:

List<WebElement> listOfElements = webdriver.getElements('input.myclass');
for (WebElement el : listOfElements) {
    el.sendKeys("abc");
}

In JavaScript it's a little bit tricky and I don't know to handle with. In my PageObject I tried the following:

module.exports = {
  elements: {},
  commands: [{
    test() {
      this.api.elements('css selector', 'input.myclass',function (result) {
        for (var i = 0; i < result.value.length; i++) {
          console.log(result.value[i].ELEMENT);
          this.api.elementIdValue(result.value[i].ELEMENT, 'abc');
        }
      });

      this.api.pause(3000);
      return this.api;
    }
  }]
};

But this worked not for me. In this case I get an error while test execution (TypeError: Cannot read property 'elementIdValue' of undefined). Also, I don't want to handle everything in asynchronous callback function, because the following test steps maybe require the completed handling on the multiple input fields.

So, how can I implement such a solution to handle multiple elements in nightwatch-cucumber with and without callback functions? And what do you prefer in that case?

like image 641
GRme Avatar asked Jun 12 '17 10:06

GRme


1 Answers

thx to @Florent B.

I answered my own question. The following code works for me now:

module.exports = {
  elements: {},
  commands: [{
    test() {
      this.api.elements('css selector', 'input.myclass',function (result) {
        for (var i = 0; i < result.value.length; i++) {
          this.elementIdValue(result.value[i].ELEMENT, 'abc');
        }
      });

      return this.api;
    }
  }]
};

Because the code inside the callback function runs asynchronous I think you have to wait for a special condition (e.g. with waitForElementVisible) to go on with the automated test. Because sometimes you have to for the successful completed callback function before keep going with next steps in automated tests.

like image 104
GRme Avatar answered Oct 22 '22 14:10

GRme