mekdev
mekdev

Reputation: 468

NightWatch.js - get a list of child WebElements based on relative css locator

Hello all NightWatch adopters,

I am trying to parse a table with the following format to get a a list of rows and the cell in each rows

<tbody> 
  <tr> // 1 row
    <td>Item A</td> // name
    <td>John</td> // owner
    <td>Monday</td> // create date
  </tr>
  <tr> // 2 row
    <td>Item B</td>
    <td>Mary</td>
    <td>Tuesday</td>
  </tr>
</tbody> 

The code now looks like this which calls the function below.

browser.elements('css selector', 'tbody tr', getResultsList);

Where my function for parsing now looks like this.

function getResultsList(rowResults){
    // Here we get the correct set of rows 
    console.log(rowResults.length + ' rows found'); // this returns 2


    // Main loop going through the rows
    for(var i = 0; i < rowResults.value.length; i++) {
        var row = rowResults.value[i];
        console.log(row.value + ' -- row item');
        // need to get the <td> inside row
    }
}

In Java webdriver we can just do the following

List<WebElements> rows = driver.getElements("tbody tr");
    for (WebElement row : rows) {
        row.getElement(' > td:nth-child(1)') // name
        row.getElement(' > td:nth-child(2)') // creator
        row.getElement(' > td:nth-child(3)') // date
    }

I wanted to know if there is any straight forward way to do this in NightWatchJS similar how we do this in Java via child WebElement where we can just call startingWebElement.getElement(childlocator); without having to start all the way from the top and dynamically build/chain the locators e.g.

// name
browser.getText('css selector', 'tbody tr:nth-child('+i+') td:nth-child(1)')
// creator
browser.getText('css selector', 'tbody tr:nth-child('+i+') td:nth-child(2)')
// date
browser.getText('css selector', 'tbody tr:nth-child('+i+') td:nth-child(4)')

Any comments, suggestions, concerns, tips is greatly appreciated.

Upvotes: 3

Views: 4080

Answers (1)

kunal_bohra
kunal_bohra

Reputation: 71

See if this works for you:

Page.getTableRows((rows) => {  
  rows.forEach((row) => {
    client.elementIdElements(row.ELEMENT, 'tag name', 'td', (result) => {
      console.log(`row td length ${result.value.length}`);
      result.value.forEach((cell) => {
        client.elementIdText(cell.ELEMENT, (text) => {
          console.log(`cell text ${text.value}`);
        })
      });
    });
  });
});`

Implementation of getTableRows

getTableRows(callback) {
  this.api.elements('css selector', \`${this.elements.table.selector} tbody tr\`, (data) => {

    if(data.state === 'success'){
      callback.call(this, data.value);
    }
  });
},

Upvotes: 2

Related Questions