How to write Xpath for next Div using Sibling - selenium

I want to read the Tax Price using the sibling concept, so I have I've written below XPath, but it's not working
My code:
//div[#class='grid_3 d-grid_10']//label[contains(text(), 'Tax')]/following-sibling::div
HTML:
<div class="grid_3 d-grid_10">
<label class="m-confirmation-modal-print-detail-capgrey"> Tax:</label>
</div>
<div class="grid_1 d-grid_2">
<label class="m-confirmation-modal-print-price text-align-right"> $10.50</label>
</div>

To read the Tax Price i.e. $10.50 using text Tax within the ancestor node, you need to locate the <label> node with text as Tax: first. Then with respect to this node you need to locate the following <div> node which have a decedent node containing the required text i.e. $10.50 and to achieve that you can use the following solution:
XPath:
//label[#class='m-confirmation-modal-print-detail-capgrey' and contains(.,'Tax')]//following::div[1]/label

The second <div> is a sibling of the first one, not of the child <label>. You need to go back to the parent <div> first using .. or parent::div
//div[#class='grid_3 d-grid_10']//label[contains(text(), 'Tax')]/parent::div/following-sibling::div
As suggested in the comments you can simplify it by starting the xpath with the "Tax" <label>
//label[contains(text(), 'Tax')]/parent::div[#class='grid_3 d-grid_10']/following-sibling::div

You can use this :
//label[contains(text(), 'Tax')]/../following-sibling::div

Related

Find Xpath to an element depending on the value of another element in a table row

I'm new to Xpath so if this doesn't contain all relevant information apologies & let me know what you need to solve it.
I am trying to find an Xpath to an "expand arrow" element which expands a row in a table. The "expand arrow" element isn't unique so I would like to select it based on text contained in another element on the same row. The layout is as follows:
<td id="__table2-rows-row10-col0">
<div class="sapUiTableCellFlex">
<span id="__table2-rows-row10- treeicon" title="Expand Node" role="button">
<div id="__hbox27-__clone101">
<div id="__data70-__clone101">
<div id="__data71-__clone101">
<span id="__text47-__clone101" title="sys-admin">sys-admin</span>
I'd like to select the element with title = "Expand Node"
<span id="__table2-rows-row10- treeicon" title="Expand Node" role="button">
based on the element with title or text = "sys-admin"
<span id="__text47-__clone101" title="sys-admin">sys-admin</span>
I've played around with various options but I can't seem to get it to work. Any ideas would be much appreciated!
Thanks
To locate the element with title as Expand Node with respect to the element with title or text as sys-admin you can use either of the following Locator Strategies:
xpath and title attribute:
"//span[#title='sys-admin']//ancestor::span[#title='Expand Node']"
xpath and text() attribute:
"//span[text()='sys-admin']//ancestor::span[#title='Expand Node']"
I eventually got it to work using the following xpath:
//span[#title='sys-admin']/../../preceding-sibling::span[#title='Expand Node']

Selenium Python, extract text from node and ALL child nodes

I have the opposite problem described here. I can't get the text more than one layer deep.
HTML is structured in the following manner:
<span class="data">
<p>This text is extracted just fine.</p>
<p>And so is this.</p>
<p>
And this.
<div>
<p>But this text is not extracted.</p>
</div>
</p>
<div>
<p>And neither is this.</p>
</div>
</span>
My Python code looks something like this:
el.find_element_by_xpath(".//span[contains(#class, 'data')]").text
Try the same with child elements:
print(el.find_element_by_xpath(".//span[contains(#class, 'data')]").text)
print(el.find_element_by_xpath(".//span[contains(#class, 'data')]/div").text)
print(el.find_element_by_xpath(".//span[contains(#class, 'data')]/p").text)
Not sure what's the referred el in your original post. But able to get all the text using the below.
driver.find_element_by_xpath("//span[#class='data']").text
Output:
'This text is extracted just fine.\nAnd so is this.\nAnd this.\nBut this text is not extracted.\nAnd neither is this.'
Instead of relying on WebElement.text property consider querying innerText property
Consider using Explicit Wait as it will make your test more robust and reliable in case if the element you're looking for is loaded by i.e. AJAX call
Assuming all above:
print(WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//span[#class='data']"))).get_attribute("innerText"))
Demo:

How to write the XPath using sibling?

How to write the XPath using sibling?
I am trying to get the price value of the delivery fee using the sibling. But I am unable to get the XPath for the price tag below is the HTML code.
<div class="grid_3 d-grid_10">
<label class="m-confirmation-modal-print-detail-capgrey"> Delivery Fee:</label>
</div>
<div class="grid_1 d-grid_2">
<label class="m-confirmation-modal-print-price text-align-right"> $9.00</label>
</div>
You can try this:
//div[contains(., ' Delivery Fee:')]/following-sibling::div/label
Explanation to xPath: //div[contains(., ' Delivery Fee:')] finds a div on the top, then /following-sibling::div will select all next siblings div below our div. In our case only the next div. And finaly /label locates the element with value $9.00.
More information here
You can try this :
//label[contains(text(),' Delivery Fee:')]/parent:div/following-sibling::div/label
But yes #Andrei solution make much sense to use.

Xpath Selenium trouble

Can anyone help me? i tried using Firepath for a correct Xpath however the code it gives me is incorrect in my eyes. First line in the examples, is the provided one.
.//*[#id='content']/div/div/div[1]/h2/span
<div id="content" class="article">
<h1>News</h1>
<div>
<div>
<div class="summary">
<h2>
<span>9</span>
// this should be the correct xpath i think
_driver.findElement(By.xpath("//*div[#id='content']/div/span.getText()"));
Here i want check if the text in between is greater or equal to 1
and the other is:
.//*[#id='content']/div/div/div[3]
<div id="content" class="article">
<h1>News</h1>
<div>
<div>
<div class="summary">
<div class="form fancy">
<div class="common results">
Here i want to check if the div class common results has been made, 1 item equals 1 common results
For retrieving span text you can use this
String spanText=driver.findElement(By.xpath("//div[#id='content']/div/div/div/h2/span")).getText();
System.out.println(spanText);
From the second question I am not so much clear.You can get class name like this, Please explain me if its not your solution
String className=driver.findElement(By.xpath("//*[#id='content']/div/div/div/div/div")).getAttribute("class");
System.out.println(className);
I would suggest you making usage of:
//div[#id='content']/div/div/div/h2/span/text()
Note: the html code you shared was not well formed. I would suggest you to test in advance the code and the xpath with http://www.xpathtester.com/xpath (to fix the code) and http://codebeautify.org/Xpath-Tester (to test your xpath)

Retrieve 5th item's price value using selenium webdriver

Say I have multiple price quotes from multiple retailers, how will I retrieve the 5th value from a particular retailer - say Target or Walmart ? I can get to the 5th entry using the matching image logo bit how do I retrieve the value ?
Adding Html Code to make things more clear .I need to retrieve the ratePrice value (198)
<div id="rate-297" class="rateResult standardResult" vendor="15">
<div class="rateDetails">
<h4>Standard Goods
<br>
<img src="http://walmart.com/walmart/ZEUSSTAR999.jpg">
</h4>
<p>
<span class="vendorPart-380">
<img alt="Walmart" src="/cb2048547924/icons/15.gif">
<br>
<strong>
<br>
MNC
</span>
</p>
</div>
<div class="ratePrice">
<h3>
$198
<sup>49</sup>
</h3>
<p>
<strong>$754.49</strong>
<br>
</p>
<a class="button-select" href="https://www.walmart.com/us/order/95134/2013-05-14-10-00/95134/2013-05-17-10-00/297"> </a>
</div>
</div>
If you could provide some HTML it would help. Speaking generally from what you're asking you'd get a locator to the price div or whatever HTML element and then get its text using something like:
_driver.FindElement(locator_of_element).Text
The trick is understanding the HTML in order to target the 5th element. So if you can find the row that has the 5th entry then it's simply a matter or then finding the price div in that row and getting the text of it.
EDIT based on more info provided by OP in comments
Using the HTML you provided (which isn't well formed by the way, missing closing strong tag, a tag, etc.). I'd say do the following:
_driver.FindElement(By.XPath("//div[#class='ratePrice'][5]/h3")).Text