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.
Related
I have a simple React weather app I am experimenting around with.
The "table" and "table-hover" css classes used below are bootstrap classes.
<table className="table table-hover">
<thead>
<tr>
<th>City</th>
<th>Temperature (K)</th>
</tr>
</thead>
</table>
As a test, I changed as follows:
<table className="tableJIBERRISH table-hoverJIBBERISH">
<thead>
<tr>
<th>City</th>
<th>Temperature (K)</th>
</tr>
</thead>
</table>
As expected, the formatting breaks.
However, in my debugging tools (I am using Firefox), I don't have any indication as to whether the CSS class being used is valid or not. How can I get this feedback from my browser's devtools?
OK, this is pretty simple. As mentioned in the comments above,
Open Firefox devtools
Right-click and select "Inspect Element"
On the right side of devtools under the Inspector tab, there is another group of tabs. By default, "Rules" should display all rules that are applied to the element.
All css classes that are applied should display here (there is a search bar to help filter as well)
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.
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.
Please help me with CSS selector.
I need to apply special attributes to the last row in a table, which (row) does'n have specified class, for example class "zzz".
<table>
<tbody>
<tr class="odd">...</tr>
<tr class="even zzz">...</tr>
<tr class="odd">...</tr>
<tr class="even">This one should be selected</tr>
<tr class="odd zzz">...</tr>
<tr class="even zzz">...</tr>
</tbody>
</table>
I'm looking for only pure CSS solution, not javascript one. Please don't suggest :not() pseudo-class, as some browsers do not support it.
Thank you for your help,
--Vadim
Sorry, this is not doable with pure CSS, not even with a selector that only modern browsers support.
I'm not 100% certain i fully understand, but you can use something like
tr:last-child
in your css
Suppose I have the following table (JS Fiddle):
<table class="data-table">
<thead>
<tr>
<th scope="col">Method</th>
<th scope="col">Price</th>
</tr>
</thead>
<tbody>
<tr>
<td>Pickup*</td>
<td>no charge</td>
</tr>
<tr>
<td>Campus mail</td>
<td>no charge</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2">* At 1st floor desk</td>
</tr>
</tfoot>
</table>
The rows of the TBODY have been zebra striped using an :nth-child(2n) selector. But the background of the row in the TFOOT doesn't get those styles, and breaks the even/odd striping any time the table has an even number of rows in the TBODY.
I'd like to select the TFOOT row with something like .data-table tbody tr:nth-child(2n):last-child + tr, but that won't work. The + selector is for adjacent sibling elements that share a single parent element. The two TRs here aren't siblings, they're cousins.
I could use jQuery (something like $(".data-table tbody tr:nth-child(2n):last-child").parent().next().find("tr").css({"background-color": "blue"})). But I'd prefer a CSS solution if there is one.
So, is there any way to select an element's cousin?
CSS works down the DOM (although selectors are processed backwards), so you can't navigate up an element tree and then back down to reach an element's cousin. You can only either operate on the same level of elements (only going forward), or go down.
You'll have to go with your jQuery solution.
Reference:
http://www.w3.org/TR/2009/PR-css3-selectors-20091215/#selectors
No, there are only decendant and limited sibling selectors. You would have to use javascript to locate the element.