How to select the nth html element in a table that has special class?

2.9k Views Asked by At

I am using Nightwatch.js to test a website. On this website there is a table which looks like this:

<tr>
    <td class="sorting_1">...</td>
    <td class="sorting_2">...</td>
    <td class="sorting_3">...</td>
    <td class="sorting_3">...</td>
</tr>

Now I want to check if this table contains the correct words. I found out that it is possible to select an element this way:

'td[class="sorting_2"]'

I can get the text with this command:

.getText('td[class="sorting_2"]', function(result){
    this.assert.equal(result.value, 'Testbenutzer');
})

But what do I have to do if I want to select one of two equally defined elements like in the list above. The last two elements both have the class sorting_3. How can I get the nth element of the table with a special class. I already tried this:

'td:nth-of-type(1)[class="sorting_3"]'
'td:nth-child(1)[class="sorting_3"]'
'td[class="sorting_3"]:nth-child(1)'
'td:nth-child(3)'

Nothing of this worked. How can I do it?

3

There are 3 best solutions below

7
On BEST ANSWER

The only way I can think of accessing multiple .sorting_3 elements, without knowledge of how Nightwatch.js actually works, is to pass it siblings ~ combinator selector.

i.e.: when you want to select the first element out of .sorting_3 elements, you would do this:

.getText('td[class="sorting_3"]', function(result){
    this.assert.equal(result.value, 'Testbenutzer');
})

And for second element:

.getText('td[class="sorting_3"] ~ td[class="sorting_3"]', function(result){
    this.assert.equal(result.value, 'Testbenutzer');
})

And so on ...

Problem is, this approach is not scalable. You will need to know ahead of time how many elements are you expecting in the .sorting_3 selector.

Hope this helps.

8
On

You could use the [<n>] notation to select the first, or second, etc.

//td[@class="sorting_3"][1]
//td[@class="sorting_3"][2]

The values of 1 and 2 correspond to the first and second, respectively.

function find_nodes(selector, callback)
{
  var result = document.evaluate(selector, document);

  var node = result.iterateNext();
  while (node) {
    callback(node);
    node = result.iterateNext();
  }
}

find_nodes('//td[@class="sorting_3"][1]', function(node) {
  node.style.backgroundColor = 'lightgreen';
});

find_nodes('//td[@class="sorting_3"][2]', function(node) {
  node.style.backgroundColor = 'lightblue';
});
<table>
<tr>
    <td class="sorting_1">foo</td>
    <td class="sorting_2">bar</td>
    <td class="sorting_3">baz</td>
    <td class="sorting_3">qux</td>
</tr>
</table>

0
On

You can use the solution that Jack proposed(//td[@class="sorting_3"][1]), but you have to set Nightwatch to use xPath as the locateStrategy. From the errors you were getting, your default locateStrategy appears to be CSS. See this command in the API reference