xpath - assertTextPresent isn't finding the text in the UL, why not? - xpath

If I have a list:
<html>
<head>
</head>
<body>
<ul>
<li><span class="A">Vans</span></li>
<li><span class="B">Cars</span></li>
<li><span class="B">Trucks</span></li>
<li><span class="C">Vans</span></li>
<li><span class="C">Cars</span></li>
<li><span class="C">Trains</span></li>
<li><span class="C">Cars</span></li>
<li><span class="C">Bikes</span></li>
</ul>
</body>
</html>
How can I check the last "Cars" item exists?
I am trying to use assertTextPresent
I am using //ul//li//span[contains(text(),'Cars')][last()] for the target, however this is selecting the first 'Cars' row as the span containing the text is inside the li
I also tried //span[last()][contains(text(),'Cars')] but this also select the first 'Cars' not the last.
I also tried //span[contains(text(),'Cars')][last()] but same result.

If you are trying to find out if the text of the last <li> is "Cars", then:
//ul//li[last()][.="Cars"]
Testing using Nokogiri, which uses libxml2 (XPath 1.0):
require 'nokogiri'
doc = Nokogiri.HTML('<html><head></head><body>
<ul>
<li><span class="A">Vans</span></li>
<li><span class="B">Cars</span></li>
<li><span class="B">Trucks</span></li>
<li><span class="C">Vans</span></li>
<li><span class="C">Cars</span></li>
<li><span class="C">Trains</span></li>
<li><span class="C">Cars</span></li>
<li><span class="C">Bikes</span></li>
</ul>
</body></html>')
puts doc.at_xpath('//ul//li[last()]')
#=> <li><span class="C">Bikes</span></li>
puts doc.at_xpath('//ul//li[last()][.="Cars"]')
#=> nil
puts doc.at_xpath('//ul//li[last()][.="Bikes"]')
#=> <li><span class="C">Bikes</span></li>

Assuming that by "the last "Cars" item" you mean <li><span class="C">Cars</span></li>, you almost got it right. You want (//ul/li/span[contains(text(),'Cars')])[last()], which means "the last element in the set of elements that are <span>s containing "Cars" and contained within <li>s contained within <ul>s.

Related

XPath: Select any div that contains one or more descendant divs with a specific class

Assume that following HTML snippet exists somewhere in the <body> element of a web page:
<div id="root_1000" class="root bacon">
<ul>
<li id="item_1234567" class="active">
<div class="userpost author_4281">
<div>This text should be visible.<div>
</div>
<ul><li>Some item</li></ul>
</li>
</ul>
</div>
<div id="root_2000" class="root bacon">
<ul>
<li id="item_8675309" class="active">
<div class="userpost author_3333">
<div>
This text, and as the DIV.root that contains it, should be hidden.
<div>
</div>
<ul><li>Another item</li></ul>
</li>
</ul>
</div>
<div id="root_3000" class="root bacon">
<ul>
<li id="item_7654321" class="active">
<div class="userpost author_9877">
<div>This text should be visible.<div>
</div>
<ul><li>Yet another item</li></ul>
</li>
</ul>
</div>
So here's my question: what would the XPath syntax be to select the div.root that contains info posted by author #3333 (i.e. div[class~="author_3333"])?
The following XPath statement will properly match the div.userpost element associated with author #3333 that I want to hide, but does not include the <ul><li>Another item</li></ul> node, which I also need to hide:
.//div[contains(#class, 'author_3333')]
What I want to do is select the closest div.root ancestor associated with the node that my XPath statement matches. Any help would be greatly appreciated... thanks in advance!
you need to get the parent node that has the second div as its child, something like:
//div[.//div[contains(#class, "author_3333")]]
You can use this XPath expression:
.//div[contains(#class, 'author_3333')]/ancestor::div[contains(#class,'root')][1]
Output is:
<div id="root_2000" class="root bacon">
<ul>
<li id="item_8675309" class="active">
<div class="userpost author_3333">
<div>
This text, and as the DIV.root that contains it, should be hidden.
</div>
</div>
<ul>
<li>Another item</li>
</ul>
</li>
</ul>
</div>

Custom Transformation in Unipager Control

i don't need default layout of unipager so took the custom transformation. how to render the page numbers in ascx transformation
my code is following
<div class="container text-center">
<li><span aria-hidden="true"><i class="fa fa-angle-double-left"></i></span></li>
<li><span aria-hidden="true"><i class="fa fa-angle-left"></i></span></li>
<li class="active">1<span class="sr-only">(current)</span></li>
<li><span aria-hidden="true"><i class="fa fa-angle-right"></i></span></li>
<li><span aria-hidden="true"><i class="fa fa-angle-double-right"></i></span></li>
</div>
it rendering like
but it not rendering remaining pages
Anyone tell me what mistake i did or solution to render next pages like Above
Uni pager requires a list of transformation
Result you're getting is exactly what you have in markup.
<li><span aria-hidden="true"><i class="fa fa-angle-double-left"></i></span></li>
Above line should be First page transformation
<li><span aria-hidden="true"><i class="fa fa-angle-left"></i></span></li>
Previous page transformation
<%# Eval("Page") %>
Pages transformation (this is what you're missing)
Just continue like this other transformations.
Hope this helps

reject li dom element having specific attributes

I am trying to get scrape a page and get dom elements which is a collection on links with Ruby and Nokogiri. So I have a collection of li's which has a specific attributes in some li's. I need to reject those li;s which has specific attributes and get all the link tags of those li's.
Here is my DOM looks like.
<ul>
<li class="carousel-list-item">
<a itemprop="url" data-cr="CharNav23" class="property-icon property-icon-14" href="/max-and-shred/">
<div itemprop="name" class="property-tooltip">
Max & Shred
</div>
</a>
</li>
<li class="carousel-list-item">
<a itemprop="url" data-cr="CharNav24" class="property-icon property-icon-19" href="/rabbids-invasion/">
<div itemprop="name" class="property-tooltip">
Rabbids Invasion
</div>
</a>
</li>
<li data-sponsor="Sponsor" class="carousel-list-item">
<a itemprop="url" data-cr="CharNav21" class="property-icon property-icon-40" target="_blank" href="http://pubads.g.doubleclick.net/gampad/clk?id=47616903&iu=8675">
<div itemprop="name" class="property-tooltip">
LEGO Friends
</div>
</a>
</li>
<li class="carousel-list-item">
<a itemprop="url" data-cr="CharNav24" class="property-icon property-icon-19" href="/rubyds-investment/">
<div itemprop="name" class="property-tooltip">
Rabbids Invasion
</div>
</a>
</li>
</ul>
I need to collect all a tags whose lis dont have data-sponsor="Sponsor" attributes. I tried like the below but it includes all lis.
page.search('ul.carousel-list > li > a').map{ |link| make_absolute(link['href']) }
The css way to do that is:
page.search('li:not([data-sponsor]) a')
or
page.search('li:not([data-sponsor=Sponsor]) a')
Probably a better option than xpath.
You should try:
# this will give you all ul elements which has no attribute named 'data-sponsor'.
page.search('//ul[#class="carousel-list"]/li[not(#data-sponsor)]/a').map{ |link| make_absolute(link['href']) }

xpath selectors

I have the following HTML:
<ul>
<li>
<p class="channel-show-time">Test 1</p>
</li>
<li>
<p class="channel-show-time">Test 2</p>
</li>
<li><span class="channel-show-carousel-label">Next</span>
<p class="channel-show-time">Test 3</p>
</li>
<li>
<p class="channel-show-time">Test 4</p>
</li>
</ul>
I want to select the text in the <p> tags from the preceding li to the li
with span class 'channel-show-carousel-label' so I want the text 'Test 2'.
I have the xpath that selects the text in the <p> tag for the li with the span class, i.e:
xpath=//ul/li/span[#class='channel-show-carousel-label']/../p
Does anyone know how I can achieve this?
You can use the following XPath:
//span[#class="channel-show-carousel-label"]/../preceding-sibling::li[1]/p/text()
It says: find the span with the desired class, go to its parent (li), find the nearest preceding li sibling, go to its p child and return its text.

Ordered Lists with descriptions

I'm writing an ordered list. For each element in the list, I'd like to have two lines. One for the name of the item and another for a description of the item.
This is what I'm currently doing:
<ol>
<li>
<ul>
<li>Item one</li>
<li>An explanation of the item.</li>
</ul>
</li>
<li>
<ul>
<li>Item two</li>
<li>An explanation of the item.</li>
</ul>
</li>
</ol>
It seems like a lot to achieve what I was looking for. Does anyone know a quicker way to pull this off?
You may want to use a definition list (<dl>) instead of the inner ul.
<dl>
<dt>Dog</dt>
<dd>A carnivorous mammal of the family Canidae.</dd>
</dl>
How about:
<ol>
<li>
<h3>Item one</h3>
<p>An explanation of the item.</p>
</li>
<li>
<h3>Item two</h3>
<p>An explanation of the item.</p>
</li>
</ol>
(Replace <h3> with the appropriate level heading in that context in the document — or, if you’re using HTML5, wrap the <ol> in a <section> tag, and use <h1> in place of <h3>.)
Or do you really need an ordered list? If not, the definition list is the thing:
<dl>
<dt>Item one</dt>
<dd>An explanation of the item.</dd>
<dt>Item two</dt>
<dd>An explanation of the item.</dd>
</dl>

Resources