XPATH Firebug filter does not filter as expected - xpath

Basically I have a list of presidents and I am only interested in the Nixon link and not Clinton or Obama.
What I find is that filtering as I have done returns the correct number of presidents (ie 1 in this case) but returns ALL of the a links instead of just the one for Nixon.
HTML:
<div class="headlineBlock">
<h2>Obama</h2>
<p class="tudor"><strong>Conditions:</strong> Always sunny </p>
<table class="resultGrid"><tr> <td class="first">
<h4><a href="http://www.thelinkiwant.com?params" title="Click to view result"</a></h4>
<div class="headlineBlock">
<h2>Nixon</h2>
<p class="nixon"><strong>Conditions:</strong> Sometimes late </p>
<table class="resultGrid"><tr> <td class="first">
<h4><a href="http://www.thelinkiwant.com/?params" title="Click to view result"</a></h4>
<div class="headlineBlock">
<h2>Clinton</h2>
<p class="tudor"><strong>Conditions:</strong> Never rainy </p>
<table class="resultGrid"><tr> <td class="first">
<h4><a href="http://www.thelinkiwant/?params" title="Click to view result"</a></h4>
XPATH:
$x("//div[#class='headlineBlock']/h2[not(contains('|Clinton|Obama|',concat('|',.,'|') ))]//../../table/a/#href")

There are several issues with your example.
There brackets missing after ever single "Click to view result", your "headlineBlock" divs and tables aren't closed, etc. So first you should make sure that your data is well formatted.
W3C's Xml Validator can help with that
Your XPath looks mostly ok, I think the issue is with the // at the end - they are a bit too early. Try this instead:
//div[#class='headlineBlock']/h2[not(contains('|Clinton|Obama|',concat('|',.,'|') ))]/..//a/#href
//div[#class='headlineBlock']
All divs of class headlineBlock ...
/h2[not(contains('|Clinton|Obama|',concat('|',.,'|') ))]
... that don't contain certain terms.
/..
Up one level (now we are at div headlineBlock again)
//a
Any direct descendants of element type a
/#href
H-Ref Attribute

Related

xpath - axes methods return wrong nodes

I have noticed that using xpath axes methods sometimes return wrong nodes. I have two examples:
url: "http://demo.guru99.com/v1/"
<tr>
<td align="center">
<img src="../images/1.gif">
<img src="../images/3.gif">
<img src="../images/2.gif">
</td>
</tr>
I can select three img elements by axes methods "//td//child::img". However when I use "//td//following-sibling::img", it can still return the second and third img elements. As far as I know, child and sibling are two different thing, so why this happens?
url: http://demo.guru99.com/selenium/guru99home/
<div class="rt-grid-12 rt-alpha rt-omega" id="rt-feature">
<div class="rt-grid-6 ">
<div class="rt-block">
<h3>
Desktop, mobile, and tablet access</h3>
<ul>
<li>
<p>
Free android App</p>
</li>
<li>
<p>
Download any tutorial for free</p>
</li>
<li>
<p>
Watch video tutorials from anywhere </p>
</li>
</ul>
<p>
<img alt="" src="images/app_google_play(1).png"></p>
</div>
</div>
<div class="rt-grid-5 ">
<div class="rt-block">
<img src="images/logo_respnsivsite.png"><br>
</div>
</div>
</div>
Here, if I use "//div[#id='rt-feature' and (#class='rt-grid-12 rt-alpha rt-omega')]//following-sibling::div", those div elements which should be child elements are still be counted as siblings
Use "//div[#id='rt-feature' and (#class='rt-grid-12 rt-alpha rt-omega')]//parent::div", the self element and its child div elements are all counted as parent.
This cause me a lot of confusion, please help me.
Suggesting that the XPath parser returns the wrong nodes, rather than that you don't understand why it is returning what it does, is starting from the wrong mindset. Unless you know the XPath parser is unreliable, start with the assumption that it is right and your expectations are wrong. Then go to the spec and study the semantics of the expression you have written.
You will find that
//td//following-sibling::img
is an abbreviation for
/descendant-or-self::node()/td/descendant-or-self::node()/following-sibling::img
so you have asked for all the following siblings of all the descendants of all the td nodes, which is exactly what you are getting.
I've come across people who habitually write "//" in place of "/" as a sort of magic fairy dust without having the faintest idea what it means. Don't do it: read the spec.

Click on deeply nested div in Watir

I am trying to click on checkbox (which represents as ) in Firefox using Watir. I have code left to me from the previous tester, and this code works in Chrome, but not Firefox.
Here is what I have.
Here is the code that leads to this div:
<div class="x-grid3-body" style="width:515px;" id="ext-gen201">
<div class="x-grid3-row x-grid3-row-first" style="width:515px;">
<table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="width:515px;">
<tbody>
<tr>
<td class="x-grid3-col x-grid3-cell x-grid3-td-0 x-grid3-cell-first " style="width: 158px;" tabindex="0">
<div class="x-grid3-cell-inner x-grid3-col-0 x-unselectable" unselectable="on">Organisation</div>
</td>
<td class="x-grid3-col x-grid3-cell x-grid3-td-1 " style="width: 298px;" tabindex="0">
<div class="x-grid3-cell-inner x-grid3-col-1 x-unselectable" unselectable="on">Catch Software</div>
</td>
<td class="x-grid3-col x-grid3-cell x-grid3-td-scopeCheckColumn x-grid3-cell-last x-grid3-check-col-td" style="width: 53px;" tabindex="0">
<div class="x-grid3-cell-inner x-grid3-col-scopeCheckColumn x-unselectable" unselectable="on">
<div class="x-grid3-check-col x-grid3-cc-scopeCheckColumn"> </div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
What I need essentially is to click on this div
<div class="x-grid3-check-col x-grid3-cc-scopeCheckColumn"> </div>
I can't attach screenshots (rating is low), but this div is the checkbox that I need to click.
This piece of code works in Chrome:
#browser.div(:class => 'x-box-inner', :index => 1).table(:class => 'x-grid3-row-table').td(:text => 'Organisation').parent.td(:index => 2)
But in Firefox I can see that Watir is just click on the whole parent div (can see selection appear in browser), not on the checkbox div.
Thank you.
First off, there is only one element in the html you've showed that has the class 'x-grid3-cc-scopeCheckColumn', so is there a reason you can't do:
#browser.td(class: 'x-grid3-cc-scopeCheckColumn').click
If not, you can simplify your element location drastically to get the td you want, since there is only one td that has the text 'Organisation', and .parent would only get the td above it, but it looks like you want the tr tag above that, so perhaps you want:
#browser.td(text: 'Organisation').parent.parent.td(index: 2)
Using an XPath worked for me in Firefox:
#browser.div(:xpath, "//*[#id='ext-gen201']/div/table/tbody/tr/td[3]/div/div").click
I was able to verify it with .flash in place of .click since your div just contains a space and there was nothing to otherwise see.

How to find <span> Element within <tr> by XPath

My HTML Code looks like this:
<html>
<body>
<div>
</div>
<div>
<table>
<tbody id=a>
<tr>
<td>
<div>
<span>
some Text
</span>
</div>
</td>
</tr>
<tr>
<td>
<div>
<span>
some Text2
</span>
</div>
</td>
</tr>
<tr>
<td>
<div>
<span>
some Text3
</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</body>
I'm trying to select each of the span elements by their text. I'm able to select the tbody by id. I Tried this:
tbody.FindElement(By.XPath(String.Format(".//span[contains(text(), {0}))]", &var)));
(var = somex0020Text)
but this always returns the first <span> element in my table.
I also tried:
tbody.FindElements(By.XPath(String.Format(".//span[contains(text(), {0}))]", &var)));
which returned a list containing every single <span> element in my table, and I don't know why.
I also don't understand why
tbody.FindElement(By.XPath(String.Format(".//span[text() = {0})]", &var)));
throws an Element not found Exception, when the contain method returns a <span> element with just the same text.
I tried by using xpath as:
.//span[contains(text(),'some Text')]
it is selecting all the 3 span.
so to this i have refer to parent element.
for 1st span: .//tbody[#id='a']//tr[1]//span[contains(text(),'some Text')]
for 2nd: .//tbody[#id='a']//tr[2]//span[contains(text(),'some Text')]
for 3rd: .//tbody[#id='a']//tr[3]//span[contains(text(),'some Text')]
through this I can select every span element individually.
You could use the jQuery to get all the span elements within "Table".
Example:
var items = $('table div span');
items.each(function (x) {
alert(items[x].innerHTML);
});
tbody.FindElement(By.XPath(String.Format(".//span[contains(text(), {0}))]", &var)));
(var = somex0020Text)
but this always returns the first Element in my table.
This is an expected behavior in Selenium. As i can see, there are 3 elements with the same xpath as mentioned in your code, in this case Selenium returns the first element.
tbody.FindElements(By.XPath(String.Format(".//span[contains(text(), {0}))]", &var)));
which returned a list containing every single Element in my table, and i dont know why.
This is also an expected behavior in Selenium. FindElements will return all the elements with the same xpath.
So change the value of var to some Text2 or some Text3 to locate the other two elements.
The following xpath will work for some Text2 :
.//span[contains(text(), 'some Text2'))]
Try with this Xpath $x("//tr//span[contains(.,'some Text')]")
For what I can see, you are having a trouble with the contains. All 3 spans are containing this 'some Text' portion.
If you want to check the entire string, you could use .//span[text()='some Text'].
Hope this helps, and have fun with web parsing!

Select elements which has certain descendent using Xpath

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"

Firefox displays 3 columns in a table, IE8 only 2

Would love some help here... Firefox displays the last column in the table (an image they click on to edit their email address, it's a link), and IE8 displays nothing for the last column (doesn't even appear to display a column!) I've left out other rows in the table, but similar stuff happens.
Anyone know why?
<table class="profile-display">
<tr>
<td style="text-align: right; color: red;"> Email address: </td>
<td class="profile-content"> <?php echo("$evar"); ?> </td>
<td> <a href="profile_change.php?edit=13"
<img src="../images/writegreen.png" class="profile-edit" alt="Edit"
title="Edit Email Address"
border="0" />
</a>
</td>
</tr>
</table>
Your <a> tag is missing its >. That will cause a browser to not recognize the end of the tag until the first > it sees, which is the end of the img tag. Frankly, I'm surprised that Firefox shows the img.
Edit: Other common causes of this problem are missing quotes and misspelled tags.

Resources