I have html page like this:
<table>
<thead>
<tr>
<td>title</td>
<td>desc</td>
<td>status</td>
</tr>
</thead>
<tbody>
<tr>
<td><label>lorem1</label></td>
<td><label>desc1 lorem</label></td>
<td><label>active</label></td>
<td> Delete </td>
</tr>
<tr>
<td><label>lorem2</label></td>
<td><label>desc2 lorem</label></td>
<td><label>active</label></td>
<td> Delete </td>
</tr>
<tr>
<td><label>lorem3</label></td>
<td><label>desc3 lorem</label></td>
<td><label>deactive</label></td>
<td> Delete </td>
</tr>
</tbody>
</table>
Now I delete record lorem2 from above list (with click on delete link) and after that I want to check lorem2 that deleted shouldn't exist or contain in page.
I write this code but it's not correct:
expect(element(by.css("table")).getText()).not.toBe('lorem2');
You will delete the lorem2 by a locator may be xpath
below for deleting
//tr/td//label[contains(text(),"lorem2")]/following::td/a
below for checking if exist after deletion
//tr/td//label[contains(text(),"lorem2")]
you should parameterize xpath (i.e) the text Lorem2 for other text.
expect(element(by.xpath('//tr/td//label[contains(text(),"lorem2")]
')).isPresent()).toBe(false);
Related
Say I get a list of rows like this
var table_stop_rows = (from r in doc.Descendants("TR").Cast<HtmlNode>()
where r.Attributes["name"]?.Value == "laneStop"
select r).ToList();
Now, for each of those "laneStop" rows, I want to refer back to the smaller table containing the "shipment_number" field and read its corresponding node value, eg "abc_123_florida-4". However, I cant simply get a list of all rows where there is a shipment_number, each one has to be in a table that precedes the "laneStop" row in the row collection I'm getting.
I suppose my question then is - if I have a collection of rows, can I then use an xpath statement relative to each row to get back to this shipment_number field in the table preceding?
Here is the html doc, note there would be dozens of these "table pairs". Since I can't control the structure of these files, I need a way to extract the data from the existing structure
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<table border="1">
<tbody>
<tr>
<td>
<table>
<tbody>
<tr>
<td>
<table>
<tbody>
<tr>
<td>Date</td>
<td>11/15/2019</td>
</tr>
<tr>
<td>shipment number</td>
<td>abc_123_florida-45</td>
</tr>
<tr>
<td>Departure time:</td>
<td>0430</td>
</tr>
</tbody>
</table>
</td>
<td>
<table>
<tbody>
<tr>
<td>Time arrival</td>
<td>1715</td>
</tr>
<tr>
<td>customer</td>
<td>bob smith</td>
</tr>
<tr>
<td>box type</td>
<td>square</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
<table border="1">
<tbody>
<tr>
<td>
<table>
<tbody>
<tr name="laneStop">
<td>box1</td>
<td>23.45</td>
<td>lane1</td>
<td>south</td>
</tr>
<tr name="laneStop">
<td>box2</td>
<td>17.14</td>
<td>lane1</td>
<td>south</td>
</tr>
<tr name="laneStop">
<td>box3</td>
<td>17.18</td>
<td>lane1</td>
<td>north</td>
</tr>
<tr name="laneStop">
<td>box2</td>
<td>199.14</td>
<td>lane1</td>
<td>west</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</body>
</html>
Try this xpath expression:
(//tr[#name="laneStop"]/ancestor::table/preceding-sibling::table//tr[2]/td[2])[1]
I have the following html
<table>
<tr>
<th>value</th>
<th>description</th>
</tr>
<tr>
<td>OverallHealthScore</td>
<td>
Overall HealthScore.
</td>
</tr>
<tr>
<td class="deprecated">DESTAGED_TRACKS_PER_SEC</td>
<td>
The tracks per second saved into disks.
</td>
</tr>
</table>
There are many many tr's but this is an excerpt of the two scenario's
I need to only print out OverallHealthScore
table.css('tr').map do |row|
puts row.css('td:not(.deprecated)').map(&:text)[0]
end
Gets me just about there but prints out the "description" td on the deprecated items. I can't seem to figure out what I need to do in order to get the results I am needing.
Assuming you want to get the first td's value which are not deprecated:
<table>
<tr>
<th>value</th>
<th>description</th>
</tr>
<tr>
<td>OverallHealthScore</td>
<td>
Overall HealthScore.
</td>
</tr>
<tr>
<td class="deprecated">DESTAGED_TRACKS_PER_SEC</td>
<td>
The tracks per second saved into disks.
</td>
</tr>
<tr>
<td>AvaiableAnother</td>
<td>
Another Available HealthScore.
</td>
</tr>
<tr>
<td class="deprecated">OTHER_DEPRE</td>
<td>
The tracks per second saved into disks.
</td>
</tr>
</table>
Then
puts table.css('td:first-child:not(.deprecated)').map(&:text)
# OverallHealthScore
# AvaiableAnother
I'm stumped on why and how to do this query.
My html structure is like this (tables nested inside tables):
<root>
<table>
</table>
<table>
<tr>
<td>
<table>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</table>
</td>
</tr>
</table>
</root>
If I start out my xpath like:
var tables = blah.SelectNodes("//table");
which returns me the 3 parent tables, then I want to select the td's from the 2nd tr like this:
var td = tables[2].SelectNodes("//tr[2]/td");
But, when I do this, it goes back to the parent/root, the "blah" level. Why is this, and how can I keep filtering my search results down?
Note: The example xml structure may not directly match the queries written, just trying to give a general idea...
Just keep extending the XPath
This one returns the <tr> items (four of them) of the second table:
/table/tr/td/table/tr
This one returns the second <tr> item:
/table/tr/td/table/tr[2]
Your best bet, though, is to give individual id attributes to each table, so that you can find it directly using that attribute.
Using something like this:
<root>
<table id="1">
</table>
<table id="2">
<tr>
<td>
<table id="3">
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</table>
</td>
</tr>
</table>
</root>
You can get the items in the innermost table with:
//table[#id="3"]
You can get an individual <td> item from that innermost table with:
//table/tr/td/table/tr[2]/td[1]
Assigning an id attribute makes it a little easier (note missing /tr/td items after the first table):
//table[#id="3"]/tr[2]/td[1]
I have a partial view like this:
#model List<user>
#foreach (var user in Model)
{
<tr>
<td>#user.name</td>
<td>...</td>
</tr>
}
And get an error like this:
Validation (HTML5): Element 'tr' cannot be nested within element 'tr'.
It's annoying me more than it should, but I want to get rid of it. Installing Web Standards Update didn't help. Any ideas?
Edit
This is the main view:
<table>
<thead>
<tr>
<th>#i18n.name</th>
<th>...</th>
</tr>
</thead>
<tbody id="results">
#Html.Partial("list_rows", #Model.users)
</tbody>
</table>
This is the generated HTML:
<table>
<thead>
<tr>
<th>naam</th>
<th>...</th>
</tr>
</thead>
<tbody id="results">
<tr>
<td>...</td>
<td>...</td>
</tr>
<tr>
<td>...</td>
<td>...</td>
</tr>
</tbody>
</table>
Edit Pulling the entire page through the W3C validator gives
This document was successfully checked as HTML5!
This error appears when you open a <tr> element before you loop through your model. So far the code you postet is correct and free of errors.
Just make sure that your code looks something like this:
<table>
#foreach (var user in Model)
{
<tr>
<td>#user.name</td>
<td>...</td>
</tr>
}
</table>
It seems like you already have an open tr tag in which you are trying to add more tr tags. If you already have tr tags in your table, just make sure they are all closed before the loop starts:
<tr>..</tr>
I had my webpage validated for xhtml transitional till I added this table (see below). Since then it doesn't validate and says "
document type does not allow element "tfoot" here <tfoot>
The element named above was found in a context where it is not allowed. This could mean that you have incorrectly nested elements -- such as a "style" element in the "body" section instead of inside "head" -- or two elements that overlap (which is not allowed).
One common cause for this error is the use of XHTML syntax in HTML documents. Due to HTML's rules of implicitly closed elements, this error can create cascading effects. For instance, using XHTML's "self-closing" tags for "meta" and "link" in the "head" section of a HTML document may cause the parser to infer the end of the "head" section and the beginning of the "body" section (where "link" and "meta" are not allowed; hence the reported error)."
Any ideas as what is happening? I checked for any opened and not closed tags but did not find any so I don't know what else is wrong.
<table>
<caption>
My first table, Anna
</caption>
<thead>
<tr>
<th>
June
</th>
<th>
July
</th>
<th>
August
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
Data 1
</td>
<td>
Data 2
</td>
<td>
Data 3
</td>
<td>
Data 4
</td>
</tr>
<tr>
<td>
Data a
</td>
<td>
Date b
</td>
<td>
Data c
</td>
<td>
Data d
</td>
</tr>
<tfoot>
<tr>
<td>
Result1
</td>
</tr>
</tfoot>
</tbody>
</table>
You've got the <tfoot> at the end of the table. It should be between the <thead> and the <tbody>. It will appear at the bottom, but it's coded at the top. One of the original ideas is that as a large table loaded, the heading and footer would be visible quickly, with the rest filling in (esp. useful if the body was scrollable between them). It hasn't quite worked out like that in practice, but it does make more sense if you know that.
In the DTD it lists:
<!ELEMENT table (caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))>
That is, optional caption, then zero-or-more col or colgroup, then optional thead, then optional tfoot, then at least one tbody or tr.
UPDATE: Note that HTML 5 now allows one to put the <tfoot> at the end of the table, instead of before the first <tbody> (or the first <tr> that isn't in a <thead>, <tfoot> or <tbody> and hence in a single implicit <tbody>). As such the code in the question would now be considered valid. The older approach is also still valid, and probably advisable.
The tfoot element should be outside of the tbody element, like this:
<table>
<caption>
My first table, Anna
</caption>
<thead>
<tr>
<th>
June
</th>
<th>
July
</th>
<th>
August
</th>
</tr>
</thead>
<tfoot>
<tr>
<td>
Result1
</td>
</tr>
</tfoot>
<tbody>
<tr>
<td>
Data 1
</td>
<td>
Data 2
</td>
<td>
Data 3
</td>
<td>
Data 4
</td>
</tr>
<tr>
<td>
Data a
</td>
<td>
Date b
</td>
<td>
Data c
</td>
<td>
Data d
</td>
</tr>
</tbody>
Here is a small example of the correct nesting for those who need it.
<table>
<caption></caption>
<thead>
<tr>
<th></th>
</tr>
</thead>
<tfoot>
<tr>
<td></td>
</tr>
</tfoot>
<tbody>
<tr>
<td></td>
</tr>
</tbody>
</table>