Finding element based on two cell values in a tabl

2019-08-04 07:14发布

问题:

I am in a weird situation where I have multiple rows with similar values in my rows and I need to select element which has link with text "Protractor" in first cell and text "NewAge" in second cell of same row.

<table width="100%" border="0" cellspacing="0" cellpadding="2" class="resultsTable"><tr><td>
        <a href = "Mytitle.aspx">Protractor</a>
        <td>NewAge</td>
        </tr>
    <tr><td>
    <a href = "NewMytitle.aspx"> NewProtractor </a>
        <td>NewAge</td>
        </tr>
    <tr><td>
    <a href = "NewProtTile.aspx">Protractor</a>
        <td>NewAge World</td>
        </tr></table> 

Now I want my hyperlink element to be picked based on both text values in first and second cell which is 'Protractor' and 'NewAge'

I want to use exact text search instead of containing text as many other rows has similar values
This is the xpath returned by Chrome.

//*[@id="PageContent"]/table/tbody/tr[2]/td/table/tbody/tr[3]/td[1]/a

I tried using xpath to select the link with text as 'Protractor' in first cell and "NewAge" in second cell of same row but not getting an desired results.

   element(by.xpath("//tr['Protractor']['NewAge']"))

Can someone please help?

回答1:

To identify/retrieve the hyperlink element based on both text values in first and second cell which is Protractor and NewAge you can use the following xpath :

//table[@class='resultsTable']//td[text()='NewAge']//preceding::a[text()='Protractor']


回答2:

You can use XPath to do this.

//table[@class='resultsTable]//a[.='Protractor']//following::td[.='NewAge']

This starts with the table, finds an A that contains "Protractor", and then finds the next TD that contains "NewAge".

If it were me, I would wrap this in a function that takes in the two parameters to make it reusable. Then you can pass in any two strings, and it will return the value or click the element, whatever you want...



回答3:

Here is how I would handle it. First I would get a list of all rows

const rows = browser.element.all(by.tagName('tr'));

The I would get a list of rows from that list where the first cell text equals Protractor

const firstMatches = rows.filter((row) => {
  return row.all(by.tagName('td')).first().getText().then(text => text === 'Protractor');
});

Then from this list I would check the second cell equals NewAge

const secondMatches = firstMatches.filter((row) => {
  return row.all(by.tagName('td')).get(1).getText().then(text => text === 'NewAge');
});

If you throw all these together and log the count and text of secondMatches, the number of elements should only be one and the text should be Protractor NewAge letting you know you have the right row.

const rows = browser.element.all(by.tagName('tr'));
const firstMatches = rows.filter((row) => {
  return row.all(by.tagName('td')).first().getText().then(text => text === 'Protractor');
});

const secondMatches = firstMatches.filter((row) => {
  return row.all(by.tagName('td')).get(1).getText().then(text => text === 'NewAge');
});

secondMatches.count().then(count => {
  console.log(count);
});

secondMatches.first().getText().then(text => {
  console.log(text);    
});


回答4:

Try below xpath to find the exact row, it can match the only row in my chrome.

//table[@class='resultsTable']//tr[td[2][.='NewAge'] and td[1]/a[.='Protractor']]

Above xpath is stricted by limited on first and second cell, if you don't care which cell, you can use below xpath:

//table[@class='resultsTable']//tr[td[.='NewAge'] and td/a[.='Protractor']]

Then find your wanted element inside the matched row.
For example, you want to click the link inside the fist cell:

//table[@class='resultsTable']//tr[td[2][.='NewAge'] and td[1]/a[.='Protractor']]/td[1]/a

Or you want to click a link which text is 'Delete' and you don't care it in which cell:

//table[@class='resultsTable']//tr[td[2][.='NewAge'] and td[1]/a[.='Protractor']]//a[.='Delete']