WebDriver Selenium: Need to select element in the table after some element - css

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).

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.

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.

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.

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.

Related

QWebView find text inside invisible elements

In my Qt project I'm using the QWebView to load my html table data.
I'm using the findText function to find text in the html page.
But, I can't find invisible text...
HTML sample :
<table>
<tr>
<td> hello </td>
</tr>
<!-- invisible data -->
<tr style="display:none">
<!-- I want to find this value -->
<td> hey </td>
</tr>
</table>
Is there a way to find invisible text elements via Qt?
I know that I can evaluate JavaScript function for that..
But still I'm looking for some Qt solution?
Thanks in advance.
You can use QWebFrame::findAllElements() function which will perform elements look up by CSS selector and return all found elements as QWebElementCollection regardless of their visibility. From that list you can find the QWebElement that correspond to your searching criterion.

CSS Selector for sibling

How do I select the radio from a list of tr's where the only unique element is 'Some unique value'?
<tr>
<td>
<input type="radio" name="myradioname" value="4" onclick="myevent">
</td>
<td>
Some value
</td>
<td>Some unique value</td>
</tr>
While this cannot be done using pure CSS, it can be achieved using jQuery's :contains selector..
Working jsFiddle
The selector you're looking for is:
$("tr:contains('Some unique value')").find('input[type="radio"]')
First you look for a <tr> that contains 'Some unique value', then you find input[type="radio"] within it.
Works like a charm. In the jsFiddle only the radio near 'Some unique value' gets checked on page load using this selector.
Notes:
There are other ways you can go about it, for e.g finding the <td> that contains 'Some unique value' then looking for the <input> inside its siblings.. However I think the way presented here is most efficient.
If you can select the table first and search only the rows inside it do it, for it will run faster.. e.g: $("#myTable tr:contains('Some unique value')").find('input[type="radio"]').
If you still want to do it using CSS alone I would recommend viewing your server side code and using a conditional statement for adding a class to that specific <tr> for example class="special" then adding a CSS rule like so: .special input[type="radio"]{...}

Click on specific link in table row

I'm testing with Selenium Webdriver in Firefox and ideally also in IE8.
Here is my html structure:
<table id="table">
<tbody>
<tr>
<td>Text1</td>
<td><a id="assign" href="/assign/1>Assign</a></td>
</tr>
<tr>
<td>Text2</td>
<td><a id="assign" href="/assign/2>Assign</a></td>
</tr>
<tr>
<td>Text3</td>
<td><a id="assign" href="/assign/3">Assign</a></td>
</tr>
</tbody>
</table>
Basically what I need to do is this:
Click on the assign link on the row that contains Text1
So far i came up with the XPATH: //*[#id='table']//tr/td//following-sibling::td//following-sibling::td//following-sibling::td//a that selects all the assign links. Changing it to //*[#id='table']//tr/td[text='Text1']//following-sibling::td//following-sibling::td//following-sibling::td//a returns "No matching nodes" from Firebug.
However, I want a CSS selector for this. So, i tried #table>tbody>tr:contains('Text1') but Firebug returns "Invalid CSS Selector".
Any suggestions ?
You should find the td that has preceding td sibling tag with Text1 text, then get the a tag:
//table[#id="table"]//td[preceding-sibling::td="Text1"]/a[#id="assign"]
Alternatively you can find 'tr' having 'td' with text = 'Text1' and then inside the 'tr' find 'td' having text 'Assign'
//table[#id='table']//tr[td[.='Text1']]/td[.='Assign']
About css selectors, there are no pure css selector for text based search. 'contains' is not standardized yet, so may not work in your case.

Multiple tables css first child

I am having an issue stylizing a class in the first table while keeping the rest of the tables the same. Let me show an example
<table>
<tbody>
<tr class="a"></tr>
</tbody>
</table>
<table>
<tbody>
<tr class="a"></tr>
</tbody>
</table>
<table>
<tbody>
<tr class="a"></tr>
</tbody>
</table>
So I want the class a of the first table to be different than the rest of the tables. How do I go about doing that?
Thank you for your time.
Edit:
I forgot to mention. I cannot add separate classes on each table. I can only give them all the same class. It is generated that way.
In newer browser you can use CSS3's nth-child():
table:nth-child(1) tr.a{
background-color:#ff0000;
}
This works if this is the 1st child of the parent element (e.g. say that these 3 tables are the children of the body.
You can be also more specific that this is the nth table element using the :nth-of-type() selector.

If a child has a certain specific value, how to check and make "true" so that hover of the parent yields a result?

Okay, the title is worded terribly, I know. I really don't know exactly how to describe this.
I am editing a "website" but I don't have access to HTML or Javascript or PHP or anything else. Only CSS, and I can creatively manipulate the HTML already presented in the website.
<div id="list">
<table>
<tbody>
<tr>
<td class="td1">blahblahblah</td>
<td class="td1">blahblahblah</td>
<td class="td1">blahblahblah</td>
<td class="td1"><a href="bleach.com">Bleach</td>
<td class="td1">Score: 9</td>
</tr>
<tbody>
</table>
<table>
<tbody>
<tr>
<td class="td2">blahblahblah</td>
<td class="td2">blahblahblah</td>
<td class="td2">blahblahblah</td>
<td class="td2">Naruto</td>
<td class="td2">Score: 10</td>
</tr>
<tbody>
</table>
</div>
So this is basically how it's set up. These are 2 anime, Bleach and Naruto. Naruto's score is a 10, Bleach's is a 9. My goal is to select the parent table of the anime that contains a score of 10 so that I can set up a specific hover animation event using keyframes whenever an anime with a score of 10's table is hovered over.
Now the way this is set up, I don't think there's any way to do it other than manually selecting each anime with a score of 10 by doing something like #list > table > td:nth-of-type(4) a[href*="naruto.com"] though I'm not sure that's relevant. That's how I can select the child, but how do I select the table parent to style it for hover? There must be a way. :(
Appreciate any help you can offer. If you leave a comment within the next day I should be able to respond back immediately.
Thanks.
Please keep in mind, I can not simply give a table a class or id. I have no access to adding or editing anything within the set HTML. So I need to figure out a different method. Also, selecting the table by doing #list table:nth-of-type(n) is not possible because the list of tables will be ever-changing (tables added/removed), can be sorted (altering n), and the sheer volume (we're talking hundreds of tables) etc. which would throw it out of play.
This is not possible using only CSS. You need to select for an attribute at least. There was a proposal for a :content selector for CSS 3, but that didn't end up in the spec. (More info here).
My spirits were not dampened. I figured out a way to do it. By manipulating another td I don't need that's within the table that has a score of 10 and setting it to transparent and positioning it over the entire table, giving it a z-index of 1, and all of the other elements within the table a z-index of 2, I can cause the event on table hover to occur as I wished. :) I'm just posting this here in case anyone ever has a problem like this and this may help them as well.

Resources