How to use preceding sibling in xpath - xpath

Here i want to Accept button. Here is the HTML.
<div class="friend-request no-pad ng-scope" ng-if="notifications.friendInvites.length > 0">
<p class="rem-head mzero small">
<div class="reminder-lst lst-box ng-scope" ng-repeat="friendInvite in notifications.friendInvites | limitTo:limit">
<span class="img-frame img-circle">
<span class="pull-left rem-detail-a">
<a class="pull-left rem-detail-a pzero" href="friend#/friends/friendprofile/b6c70e4f-bfe1-440d-836c-2e8fdc88540e">
<span class="frndact pull-right">
<a class="ignore" ng-click="ignoreNotification(friendInvite, 'friend')" href="javascript:void(0)">
<a class="accept" ng-click="acceptNotification(friendInvite, 'friend')" href="javascript:void(0)">
<i class="fa fa-lg fa-check-circle green"></i>
</a>
I have tried using below xpath but not working. Can anyone plz help me?
#FindBy(xpath=".//a[ng-click='acceptNotification(friendInvite, 'friend')']/preceding-sibling::i[#css='.fa.fa-lg.fa-check-circle.green']").
Thanks in advance

Assuming that you are looking for the 'A' tag of class accept, you can try
//i[#class="fa fa-lg fa-check-circle green"]/preceding-sibling::a[#class="accept"]
or
//i[#class="fa fa-lg fa-check-circle green"]/preceding-sibling::a[#ng-click="acceptNotification(friendInvite, 'friend')"]
a couple of things:
as TT noted your xpath was missing the # for the attribute selector
the sample you posted is not a well formed xml, expect troubles with xpath if you don't have an xhtml compliant source.
if you use the second example mind to escape either the " or the ' quotes, if you use it inside another expression

Related

How to properly get the value contained inside a section using XPath?

having the following HTML (snippet grabbed from the web page I wanted to scrape):
<div class="ulListContainer">
<section class="stockUpdater">
<ul class="column4">
<li>
<img src="1.png" alt="">
<strong>
Buy*
</strong>
<strong>
Sell*
</strong>
</li>
<li>
<header>
$USD
</header>
<span class="">
20.90
</span>
<span class="">
23.15
</span>
</li>
</ul>
<ul>...</ul>
</section>
</div>
how do I get the 2nd li 1st span value using XPath? The result should be 20.90.
I have tried the following //div[#class="ulListContainer"]/section/ul[1]/li[2]/span[1] but I am not getting any values. I must said this is being used from a Google Sheet and using the function IMPORTXML (not sure what version of XPath it does uses) can I get some help?
Update
Apparently Google Sheets does not support such "complex" XPath expression since it seems to work fine:
Update 1
As requested I've shared the Google Sheet I am using to test this, here is the link
What you need is :
=IMPORTXML(A1;"//li[contains(text(),'USD')]/span[1]")
Removing section from your original XPath will work too :
=IMPORTXML(A1;"//div[#class='ulListContainer']/ul[1]/li[2]/span[1]")
Try this:
=IMPORTXML("URL","//span[1]")
Change URL to the actual website link/URL

Proper xpath Syntax for Extracting Two Text Values

I am trying to scrape a web page for NAME OF COMPANY and CITY AND STATE OF COMPANY shown below.
I have an xpath code snippet that identifies both text elements at the same time:
// span[starts-with(#class,"text-align")]/text()[2]
This xpath snippet pulls the first text value (COMPANY NAME). How do I get the second text element (CITY,STATE)?
A snip of the web page code looks like this:
<div>
<ul class="pv-top-card-v3--experience-list">
<li>
<a class="pv-top-card-v3--experience-list-item" href="#" data-control-name="position_see_more" data-ember-action="" data-ember-action-172="172">
<img src="https://media.licdn.com/dms/image/C4E0BAQFhA8h46hvabA/company-logo_100_100/0?e=1582761600&v=beta&t=VAeZqaGu3Lu6Ol_n5kiiI74FSRuSOZA1ggAI5qTVRjE" id="ember173" class="EntityPhoto-square-1 flex-shrink-zero ember-view">
<span id="ember174" class="text-align-left ml2 t-14 t-black t-bold full-width lt-line-clamp lt-line-clamp--multi-line ember-view" style="-webkit-line-clamp: 2"> THIS IS THE NAME OF A COMPANY
<!----></span>
</a>
</li>
<li>
<a class="pv-top-card-v3--experience-list-item" href="#" data-control-name="education_see_more" data-ember-action="" data-ember-action-176="176">
<img src="https://media.licdn.com/dms/image/C560BAQEr2uQX-x2EwQ/company-logo_100_100/0?e=1582761600&v=beta&t=aDbYLUDMvlS4DpwOLjOaQj3Dj60C_cYLC5UUvGoyld0" id="ember177" class="EntityPhoto-square-1 flex-shrink-zero ember-view">
<span id="ember178" class="text-align-left ml2 t-14 t-black t-bold full-width lt-line-clamp lt-line-clamp--multi-line ember-view" style="-webkit-line-clamp: 2"> THIS IS THE CITY AND STATE OF COMPANY
<!----></span>
</a>
</li>
</ul>
</div>
The xpath string is picking up the two span elements using class. I can't use the span id attributes because they are dynamic and change with each page (one page per company).
Can someone advise how I extract the desired text?
Thanks.
point to the li level.
//ul/li[2]/a/span[starts-with(#class,"text-align")]

Select a radio button by text using XPath

<div class="btm0">Question 1
</div><span class="small"></span>
<span id="form2">
<span id="form2:j_idt4598" style="display: none;"></span><ul id="form2:radioButton" class="controls full-width">
<li>
<input class=" firepath-matching-node" name="form2:radioButton" id="form2:radioButton:0" type="radio"><label for="form2:radioButton:0"> Yes</label></li>
<li>
<input class=" firepath-matching-node" name="form2:radioButton" id="form2:radioButton:1" type="radio"><label for="form2:radioButton:1"> No</label></li>
</ul>
<span id="form2:errMessage"></span>
</span>
<div class="btm0">Question 2
</div><span class="small"></span>
<span id="form1">
<span id="form1:j_idt4617" style="display: none;"></span><ul id="form1:radioButton" class="controls full-width">
<li>
<input class=" firepath-matching-node" name="form1:radioButton" id="form1:radioButton:0" type="radio"><label for="form1:radioButton:0"> Yes</label></li>
<li>
<input class=" firepath-matching-node" name="form1:radioButton" id="form1:radioButton:1" type="radio"><label for="form1:radioButton:1"> No</label>
I have this above simple page having a label and option button.
I want to select the 'Question 1 - Yes' using an XPath.
Is there an easy way to create a unique XPath, which will select the correct 'YES' option (which could be Question 1 or Question 2)? I donĀ“t want to hardcode the XPath.
I tried out a partial solution but I only get the second 'YES' option selected:
//*[contains(text(),'Question 1')]/following::label[contains(text(),'Yes')]
Not sure if this is what you are asking, but if you want to limit the scope of your XPath expression to just the 2 label elements after the div, you can use the position() function:
//div[contains(text(),'Question 1')]/following::label[position() <= 2 and contains(text(),'Yes')]
If this is not what you are looking for, please try to clarify your question, perhaps by providing some sample results.
I was able to get some solution after try, but really not happy with the answer as I have to to change my xpath based on YES or NO of option button
for YES :
//*[contains(text(),'Question 1')]/./following::li[1]/label[contains(text(),'Yes')]
for NO :
//*[contains(text(),'Question 1')]/./following::li[2]/label[contains(text(),'Yes')]
As you see in the above solution, I have to toggle the values of li[].
But with above solution, I am able to pinpoint the option.

How to get xpath to a link to picture?

How to extract xpath to link of image? I want to extract this specific link:
http://insales.ru/images/bigpic.jpeg
I dont know how I must specify xpath. Do I have to include all parent tags to get it or I just can go directly to tag?
<div class="tango">
<div class="container-horizontal">
<div class="clip-horizontal">
<ul id="carousel" class="pagination jcarousel">
<li class="jcarousel-item">
<a rev=http://insales.ru/images/bigpic.jpeg href="http://insales.ru/images/pic2.jpeg">
<img src="http://insales.ru/images/thumb.jpeg">
</a>
</li>
</ul>
</div>
</div>
</div>
So my xpath would be:
//li[contains(#class, 'jcarousel-item jcarousel-item-horizontal jcarouse')]/a
Or I have to include all parent div tags:
//div[#class="tango"]//div[#class="container-horizontal"]//li[contains(#class, 'jcarousel-item jcarousel-item-horizontal jcarouse')]/a
But anyway both of this xpaths don't work.
How to specify xpath to extract this link: http://insales.ru/images/bigpic.jpeg
There are several options but the shortest one is probably:
.//*[#id='carousel']/li/a/img

Trouble selecting quantity out of drop down in watir

I have never run into an issue with being able to select a value in a drop down, so I'm not sure how this is different. First, here is the HTML I'm working with:
<div class="hn-select-content hn-select-expand" ng-class="{'open-to-left':openToLeft, 'expand-to-left':expandToLeft}" ng-transclude="" style="">
<ul class="qty-discount whiteBackground border border-hn-secondary-lt text-small ng-scope" scroll-lock="">
<li float-container="">
<div class="float-cont">
<ul class="text-small">
<li class="selected ng-isolate-scope HN-Item-Opt-Sel" li="" <="" on-option-select="changeQuantity(val)" value="1" option="1" ng-class="{'HN-Item-Opt-Sel selected':atcData.quantity == 1}" hn-select-option="">
<div class="hn-select-option ng-binding">1</div>
</li>
</ul>
</li>
<li float-container="">
<div class="text-hn-red float-cont">
<div scroller="qty-discount" floater="" style="">
<span> 10% Off </span>
</div>
<div></div>
</div>
<ul class="text-small">
<li class="ng-isolate-scope" li="" <="" on-option-select="changeQuantity(val)" value="2" option="2" ng-class="{'HN-Item-Opt-Sel selected':atcData.quantity == 2}" hn-select-option="">
<div class="hn-select-option ng-binding">2</div>
</li>
I want to select a specific option. in this case, I have a variable set for the quantity, and it's set to 2.
This it the code from the step that is failing:
#browser.div(:id, 'hn_modal_contentIV').div(:text, '1').when_present.click
#browser.ul(:class, 'whiteBackground border border-hn-secondary-lt text-small ng-scope').div(:text, quantity).when_present(5).click
#browser.span(:class, 'redText floatRight marginTopOnly3px').wait_until_present(10)
And this is the error I receive:
Watir::Wait::TimeoutError: timed out after 5 seconds, waiting for {:text=>"2", :tag_name=>"div"} to become present
The drop down box opens, I just can't get the value to be selected.
I have tried a few other variations, but none have worked. Any help would be GREATLY appreciated. Hopefully there is something small that I'm just missing.
Thanks!
First, before this code, HTML must have an select list, perhaps this select list have the attribute "display: none", then you can:
browser.execute_script("document.getElementById('[id of this select list ]').style.display = 'block';")
browser.select(:id => '[id of this select]').option(:text => '[text that you need]').select

Resources