1

The HTML page contains a table of users details.
I need to remove user.
I can select the first element in the row by username.
I need to select the "Delete" button on that row to delete that user.
The HTML structure is:

<table id="tblUsersGrid" cellpadding="2">  
<thead>  
<tbody>
<tr class="aboutMeRow" data-parentid="223">  
<tr>  
<tr>  
 ...
<tr>
    <td class="cell cell_278 cell_NameCell">xoxo</td>
    <td class="optionIcon overrideFloat orgIcon cell cell_278 gridCell"></td>  
    <td class="cell cell_278 gridCell">Custom</td>  
    <td class="cell cell_278 gridCell">qaadmin</td>  
    <td class="cell cell_278 gridCell">0</td>  
    <td class="cell gridCell">  
        <div class="removeAccountIcon"></div>  
    <td class="cell gridCell">  
        <div class="editAccountIcon"></div>  
    </td>  
    <td></td>  
</tr>  

So I can easily select the desired row by

driver.findElement(By.xpath("//td[@class='cell_NameCell'][contains(text(),'xoxo')]"))  

But how can I reach the removeAccountIcon element on that row?
I saw many questions dealing with selecting elements inside tables but didn't find solution for this issue.
Is there a way to do this by CSS selector, not only by Xpath? (I am sure there is a Xpath solution for this).

Prophet
  • 4,979
  • 11
  • 41
  • 57
  • I know it isn't what you really want but you could find the table then iterate per row and use findElements to get the list of columns (td). Over the list you can get elements by index to check the user and get the button (here is a similar code to do this http://stackoverflow.com/a/14192252) – Guillermo Jul 12 '15 at 21:14
  • Well, this is a solution. You are right. But I guess there is a single expression (Xpath) to do this work. – Prophet Jul 12 '15 at 21:18
  • Yep, I guess too... something like this: //td[contains(text(),'xoxo')/following-sibling::td//div[@class='removeAccountIcon'] – Guillermo Jul 12 '15 at 21:53

4 Answers4

2

You can make it in one go using the following XPath expression:

//tr[td[contains(@class, 'cell_NameCell')] = 'xoxo']//div[@class='removeAccountIcon']

Here we are locating the appropriate tr row by checking the text of the td element containing cell_NameCell class (this is your username cell). Then, we locate the "Remove Account Icon" inside this row.

Prophet
  • 4,979
  • 11
  • 41
  • 57
alecxe
  • 414,977
  • 106
  • 935
  • 1,083
  • I will check this too. Thanks! – Prophet Jul 12 '15 at 22:56
  • I understand your logic but the Xpath expression you provided didn't work for me. I tried to edit it but still couldn't succeed making it working. – Prophet Jul 13 '15 at 10:42
  • Could you please review the expression you wrote so it will work? I already have working solution provided by @Abhishek but it will be very nice to have more than 1 way to do this. – Prophet Jul 13 '15 at 13:31
  • @Eliyahu yup, fixed. Thanks :) – alecxe Jul 13 '15 at 13:32
  • Thanks, but this expression is still not good. Just by copying it into the 'driver.findElement(By.xpath("****")).click();' as an expression instead of the asterisks Eclipse editor detecting syntax errors... – Prophet Jul 13 '15 at 14:25
  • @Eliyahu alright, have you managed the single and double quotes correctly? – alecxe Jul 13 '15 at 14:26
  • I copy-pasted it as-is but it looks to be wrong. I don't know this expression rules. Normally I use [@class='calssname'][contains(text(), 'theText'] – Prophet Jul 13 '15 at 14:40
  • @Eliyahu the expression should work, I've tested it. Recheck the quotes. Thanks. – alecxe Jul 13 '15 at 14:51
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/83136/discussion-between-eliyahu-and-alecxe). – Prophet Jul 13 '15 at 14:55
1

If you can select the correct row, you can select the desired element within that row by calling findElement on that row instead of the original driver. However, the code you suggested for finding the correct row doesn't appear to work. (It selects a td instead of a tr.)

I would suggest the following:

WebElement userDataInRow = driver.findElement(By.xpath(//td[contains(text(),'xoxo')]))
WebElement row = userDataInRow.findElement(By.xpath(".."))
row.findElement(By.xpath("//div[@class='removeAccountIcon']"))

The second line goes to the parent element of the selected td element.

Jake Sebright
  • 659
  • 5
  • 14
  • I have a table. Each row contains `class="removeAccountIcon"` element. I need to select this element on desired row, containing the user I want to delete, not the first user in the table. – Prophet Jul 12 '15 at 21:16
  • This is not the way I asked for, but thank you. It's interesting approach too. – Prophet Jul 13 '15 at 10:57
1

I don't think there is an option to find the parent by using the css selectors. This article gives other alternates for finding the same.

To capture the "Remove" button by using the xpath, we just need to traverse back to the parent of the "Name" cell of the table and then fetch the "div" of the "remove link/button".

Then your xpath //td[@class='cell'][contains(text(),'xoxo')] should be updated as below :

//td[contains(text(),'xoxo')]/../td/div[@class='removeAccountIcon']

This will capture the "Remove Account Icon" based on the given name.

Community
  • 1
  • 1
Praveen
  • 1,199
  • 1
  • 10
  • 20
  • I will check this tomorrow. Thanks! – Prophet Jul 12 '15 at 22:55
  • Could you please review the expression you wrote so it will work? I already have working solution provided by @Abhishek but it will be very nice to have more than 1 way to do this. – Prophet Jul 13 '15 at 13:31
  • My Bad... there is a syntax error.. I didnt validte the xpath mentioned in the question. Anyways.. Here is the way to get it.. – Praveen Jul 13 '15 at 16:24
1

Xpath axes preceding-sibling would helps you to resolve the issue. You can try below xpath:

//td[preceding-sibling::td[contains(text(),'xoxo')]][5]/div[@class='removeAccountIcon']

Let me know if it works for you.

Abhishek Yadav
  • 449
  • 3
  • 16