From the following XML-document, I'm trying to specify XPath that will capture the text that immediately follows the h4-headline "Source", namely - in this example - "Information about the source":
<div class="doc-inf doc-inf-information">
<h3>Document information</h3>
<div>
<h4>Source</h4>
<ul>
<li>Information about the source</li>
</ul>
I've tried the following:
//h4[contains(text(), "Source")]/ul/li'
Which doesn't seem to work. Would anyone be able to help? I would greatly appreciate it.
EDIT:
My problem (which I didn't specify fully, sorry) is that this div tag has multiple h4 tags in it of which I want to select the ul-child for each:
<div class="doc-inf doc-inf-information">
<h3>Document information</h3>
<div>
<h4>Source</h4>
<ul>
<li>Source information</li>
</ul>
<h4>Language</h4>
<ul>
<li>Swedish</li>
</ul>
<h4>Publishers</h4>
<ul>
<li>Publishing Project</li>
</ul>
<h4>Record ID</h4>
<ul>
<li>36785</li>
</ul>
In essence, I'm trying to grab the child under h4 headlines "Source", "Language", "Publishers", "Record ID" (= what I'm interested in is "Source information", "Swedish", "Publishing Project" and "36785") but the h4 headlines are inconsistently placed across pages so I need to be able to target the children of the specific headlines.
You are directly accessing the tag <h4>, which has no children, therefore the following doesn't work:
//h4[contains(text(), "Source")]/ul/li
Try this instead:
//div[h4[contains(text(), "Source")]]/ul/li/text()
which searches for a <div> that has the tag <h4> in it with the text 'Source' and then it selects the <ul> child.
Related
I'm trying to scrape a site using a highly varying HTML structure. The information at interest is not encapsulated. The only marker is a span with a target id TARGETID.
Structure is:
<h2>
<span class="TARGETID">TARGETID</span>
</h2>
<p> <!-- this is not always present, could be more p tags --> </p>
<ul> <!-- also not always present, if there, this is what we want --> </ul>
<h2>
<span class="SOMEIRRELEVANTID">IRRELEVANT</span>
</h2>
My approach was:
//h2/span[contains(text(), 'TARGETID')]/../following-sibling::ul[1][count(li) > 1][li]//a/text()
Which succeeds when a unordered list is present after the TARGETID, but if not, it takes the next unordered list it finds (which makes sense based on the query).
My question is: How can I limit the query to the nodes of two H2's, starting with the one containing a span with the target id and limited by any following H2 with a span of a different id?
Any hints are greatly appreciated.
This XPath,
//ul[preceding::h2[1][.='TARGETID']]//a
will select all a elements beneath a ul that occurs after a h2 with string value of "TARGETID" but before any other h2 elements.
So, for this expanded example,
<div>
<h2>
<span class="TARGETID">TARGETID</span>
</h2>
<p> <!-- this is not always present, could be more p tags --> </p>
<ul> link1 </ul>
<h2>
<span class="SOMEIRRELEVANTID">IRRELEVANT</span>
</h2>
<ul> link2 </ul>
<h2>
<span class="SOMEIRRELEVANTID">IRRELEVANT</span>
</h2>
</div>
it would select only
link1
and not link2, as requested.
Hello I am relatively new to QA automated web testing and I try to use SO as a last resort.
That being said I am having issues selecting a choice from a drop down menu in our web app.
Here is the following code:
<div id="edit-main-user-role-wrapper" class="form-item">
<select id="edit-main-user-role" class="form-select my-dropdown ahah-processed" name="main[user_role]" style="display: none;"></select>
<div class="newListSelected" style="position: static;">
<span class="selectedTxt">
Student
</span>
<ul class="newList" style="top: -136px; height: 136px; left: 0px; display: none;">
<li>
<a class="" href="JavaScript:void(0);"></a>
</li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
</div>
When I inspect the drop down icon with Firefox inspect element it directs me to this line in the code: span class="selectedTxt"
I have tried accessing the list by id, class, xpath, and css all to no avail.
Here are some of my past attempts:
#browser.div(:class => 'form-item').select_list(:text => 'Student').fire_event ("on click")
#browser.select_list(:xpath, menu).option(:text, option).click
An element with a select tag should only be meaningful if there are elements with option tags nested inside it. Often these pages have a lot of extra javascript in them to give context.
For dropdowns that don't follow the select/option pattern, you want to click on the element that drops down the list, and then click on the element you want that becomes visible as a result.
This is what eventually worked for me:
#browser.span(:class, "selectedTxt").click # to make the list visible
#browser.element(:xpath, "#{xpath}").click # click on the specified xpath
I know this may not be the most elegant answer, but it works!
not sure if you're still looking for answers, but either of these worked for me:
#browser.select_list(:id => "you_leaving_us").option(:text => "Other").select
#browser.select_list(:id => "you_leaving_us").option(:value => "8").select
Instead of li's, I had options. Hope it works
I am trying to get the error message off of a page from a site. The list contains several possible errors so i can't check by id; but I do know that the one with display:list-item is the one I want. This is my rule but doesn't seem to work, what is wrong with it? What I want returned is the error text in the element.
//*[#id='errors']/ul/li[contains(#style,'display:list-item')]
Example dom elements:
<div id="errors" class="some class" style="display: block;">
<div class="some other class"></div>
<div class="some other class 2">
<span class="displayError">Please correct the errors listed in red below:</span>
<ul>
<li style="display:none;" id="invalidId">Enter a valid id</li>
<li style="display:list-item;" id="genericError">Something bad happened</li>
<li style="display:none;" id="somethingBlah" ............ </li>
....
</ul>
</div>
The correct XPath should be:
//*[#id='errors']//ul/li[contains(#style,'display:list-item')]
After //*[#id='errors'] you need an extra /, because <ul> is not directly beneath it. Using // again scans all underlying elements for <ul>.
If you are capable to not use // it would be better and faster and less consuming.
I want to Select all the LI elements which contain SPAN with id="liveDeal152_dealPrice" as descendents. How do i do this with xpath?
Here is a sample html
<ul>
<li id="liveDeal_152">
<p class="price">
<em>|
<span class="WebRupee">₹ </span>
<span id="liveDeal152_dealPrice">495 </span>
</p>
</li>
<li id="liveDeal_152">
<p class="price">
<em>|
<span class="WebRupee">₹ </span>
(price hidden)
</p>
</li>
</ul>
//li[.//span[#id = 'liveDeal152_dealPrice']] should do. Or more verbose but closer to your textual description //li[descendant::span[#id = 'liveDeal152_dealPrice']].
Use this
//li[.//span[#id="liveDeal152_dealPrice"]]
It selects
ALL <li> ELEMENTS
//li[ ]
THAT HAVE A <span> DESCENDANT
.//span[ ]
WITH id ATTRIBUTE EQUAL TO "liveDeal152_dealPrice"
#id="liveDeal152_dealPrice"
That said, it doesn't seem like a very wise element selection, mostly due to the dynamically looking id. If you're going to use it once, it's probably ok, but if you're using it, say, for testing and will reuse it many times, it might cause trouble. Are you sure this won't change when you change your website and/or database?
As a side note:
ul stands for "unordered list"
ol stands for "ordered list"
li stands for "list item"
I need to select a link using xpath that matches the following three criterion:
parent #class = 'testItem'
child #class = 'icon icon_checked'
text = 'test text goes here!'
i'm unsure about where to put the text attribute in the xpath reference. i've tried many permutations of the following:
//a[#class="testItem" and child::span[#class="icon icon_checked"] and li[text()="test text goes here!"]]
my issue is that the text part is not in its own span.
here's the raw example:
<li>
<a class="testItem2" data-code="2" href="javascript:void(0);">
<span class="icon icon_checked"></span>
test text goes here2!
</a>
</li>
<li>
<a class="testItem" data-code="2" href="javascript:void(0);">
<span class="icon icon_checked"></span>
test text goes here!
</a>
</li>
Thanks for the help. I've found the answer.
I can simply change the last part of my xpath from li[text()="test text goes here!"] to .[text()="test text goes here!"]].
My final working xpath is:
//a[#class='testItem' and child::span[#class='icon icon_checked'] and .[text()='test text goes here!']]