Xpath to an element with two different contains text - html

I have the next HTML and i have this xpath to find the "Show":
xpath=//*[#id="Some_id"]/div/table/tbody/tr/td[contains(text (), "Show")]
and it works, but i need to find "Show" of a particular item, in this matter of a "Main" item, so i need smth like this:
xpath=//*[#id="Some_id"]/div/table/tbody/tr/td[contains(text (), "Show")]/preceding-sibling::td[contains(text (), "Main")]
but it doesn't work. Thanks
<tr class="even">
<td title="Main">
<strong>Main</strong>
</td>
<td>
text/html
</td>
<td>
Another text
</td>
<td>
Some text here
</td>
<td>
No
</td>
<td>
Show
</td>
</tr>

You can try this xpath. This will first select a tr element which contains the specific td and then select the required a tag.
"//tr[#class='even' and td[#title='Main']]/a[text()='Show']"
EDIT: This xpath worked for the OP
"//*[#id='Some_id']/div[1]/table/tbody/tr[#class='even']/td/a[contains(text (), 'Show')]"

You want to find "Show" that belong to the "Main" row in the table.
Here is what i would do
xpath=//td[#title='Main']/following-sibling::td[contains(text(), 'Show')]
More on xpath axes: http://www.w3schools.com/xsl/xpath_axes.asp

Related

Xpath to select tr based on specific td not containing text

I'm trying to write a ruby/selenium script to click the first check box in a table where the row does not contain certain values (plural) for //tr/td[6].
Each tr in the table is structured as follows:
<tr>
<td>
<input name = "checkbox" type = "checkbox"></input>
</td>
<td> irrelevant </td>
<td> irrelevant </td>
<td> irrelevant </td>
<td> irrelevant </td>
<td> text I care about </td>
</tr>
I need the xpath for the checkbox of the first tr in the table where//tr/td[6] does not contain "badtext" and does not contain "badtext2"
Not exactly sure how to write an xpath for this. Hopefully I explained this well enough.
You need to use the not(expression) function like this
//tr/td[6][not(contains(text(),'badtext'))][not(contains(text(),'badtext2'))]
and your final xpath would be like this
//tr/td[6][not(contains(text(),'badtext'))][not(contains(text(),'badtext2'))]/../td/input[#name='checkbox']
if you want to filter any attribute including text, use
contains(.,'badtext')

ngIf for closing/opening tag

I have a table and I'm iterating in a over an array. In some scenarios, I'll want to add an extra <tr>. I'm looking for something like this:
<table>
<tr *ngFor="let element in array">
<td>
some content
</td>
//Starting block that will only be activated if some variable is true
</tr>
<tr>
<td>
some extra content
</td>
//End of the block that will only be activated if some variable is true
</tr>
</table>
Is there a way to create a boulder html that can wrap it like this?
The options I've tried so far are changing the data structure (array) so it include the element I'm looking for but I'm not pleased with having extra data there just for displaying purpose.
This should do what you want
<table>
<ng-container *ngFor="let element in array"
<tr>
<td>
some content
</td>
</tr>
<tr *ngIf="someVar">
<td>
some extra content
</td>
</tr>
</ng-container>
</table>
Perhaps the best option is to work with ng-repeat.
Example with ng-repeat:
<table ng-controller="myCtrl">
<tr ng-repeat="x in records">
<td>{{x.Name}}</td>
<td>{{x.Country}}</td>
</tr>
</table>
Ng-repeat makes a for in your object or array.
See if this can help you.

Xpath help to Find Unique value

I want to find the first tr tag with PONumber: text. I am not able to do that. Any help? I can find it using the //table/tbody/tr/td[contains(text(),'PONumber')] but it gives 2 objects. I want to find the first one only.
<tr>
<td class="clsLabel" align="right"> PONumber: </td>
<td class="clsInput"> PN659 </td>
</tr>
<tr>
<td class="clsLabel" align="right"> PreviousPONumber: </td>
<td class="clsInput"/>
</tr>
You can use following xpath to find exact object which you want
//tr/td[normalize-space(.)='PONumber:']
You can use something like
(//tr/td[contains(text(),'PONumber')])[1]
so put the xpath in brackets and with [1] you can specifiy to only return the first entry. Otherwise you could also use something like:
//tr/td[contains(text(),'PONumber') and not(contains(text(),'Previous'))]
so "Previous" will be excluded from the search results
You can limit the XPath result to return only the first matched by using [1] :
(//table/tbody/tr/td[contains(.,'PONumber')])[1]

HTML/CSS, getting table cells to balance

I have a table formatted as:
<table>
<tr>
<td>
Long list of info
Line two
</td>
<td>
Shorter list of info
</td>
</tr>
</table>
How can I get them to both display from the top of 'tr'? I assume there's a way to stop automatic vertical alignment with CSS?
To clarify for future viewers, I got it working using:
CSS:
td {
vertical-align: top;
}
HTML:
<table>
<tr>
<td>
Long list of info
Line two
</td>
<td>
Shorter list of info
</td>
</tr>
</table>
(Here's the fiddle)
Hey if you have some questions how to use tables pls look some examples here
http://www.w3schools.com/html/html_tables.asp
http://www.w3schools.com/css/css_table.asp
If you prefer to avoid CSS you can do the same thing inline with the depreciated valign tag. Valign is not supported in HTML5 but is the recommended method if you are working within the context of an HTML email.
<table border="1">
<tr>
<td width="110">
Long list of info Line two
</td>
<td valign="top">
Shorter list of info
</td>
</tr>
</table>
Or you could always use two rows if you can predict and control where your breaks are going to be and want to simplify the markup further.

Multiple classes with barely the same name

I've got a little question and it seems there's no place on the internet where I can find the answer except here :p
So I've got an html page with some tables. Thoses tables have lines (as usual :p), and in those lines they are some inputs.
I want to add a rule in my css file wich have an effect on all those lines. Those lines have an id that is barely the same semantic.
Here's my code :
<table>
<tr id="tr_creneau_1">
<td>
<input />
</td>
</tr>
<tr id="tr_creneau_2">
<td>
<input />
</td>
</tr>
</table>
<table>
<tr id="tr_logo_1">
<td>
<input />
</td>
</tr>
</table>
At the end I want a css rule who impact all the inputs in the tr_* lines.
You can try with:
tr[id^="tr_"] input
But this is a css 3 selector and it doesn't work on all browsers, alternatively you can simply use:
tr input
or add a class to every row with that id and match that class
You can try:
tr[id^="tr_"] { --your css here-- }
It will check all of the tr tags if their id starts with tr_.
If it doesn't need to be at the start of the id attribute, just somewhere random , you can use:
tr[id*="tr_"]
If above doesn't work I would suggest going for a class based approach.
You could always add a CSS class to each table row you wish to target. e.g.
<table>
<tr id="tr_creneau_1" class="style-me">
<td>
<input />
</td>
</tr>
<tr id="tr_creneau_2" class="style-me">
<td>
<input />
</td>
</tr>
<tr id="somethingElse">
no input, so no class needed
</tr>
</table>
Then style as so:
table .style-me input {
background-color: red;
}