I'm trying to write xpath for one of the elements in a tree-like structure in the UI.
The tree looks like a windows file structure, like parent node, child. So, in order to find child node parent node has to be clicked.
+ [file icon] Book
|_ Book 1
|_ Book 2
|_ Book 3
Selenium gives the following xpath for the text 'Book' in above tree shown
//ul[#id='book_xxx']/li/ul/li[8]/span
when I click on file icon, selenium gave me following
//ul[#id='book_xxx']/li/ul/li[8]/img[1]
How can one write an xpath for clicking the file icon(i.e image) based on knowing the span text? I need the xpath for clicking on file icon image.
It appears that the span and img elements are both children of the 8th li element, and I'm assuming the text inside the span that you would like to match on is "Book".
If you wanted to select the span filtering on the text you should be able to use:
//ul[#id='book_xxx']/li/ul/li[span[text()='Book']]/img[1]
This uses a nested predicate filter to identify the li that has a child span element who's text node value is "Book", and then selects that li's first img element.
Try:
//ul[#id='book_xxx']/li/ul/li[8]/img[1] | //ul[#id='book_xxx']/li/ul/li[8]/span
Which is practically xpath1 or xpath.
Related
Without using index specificity. I'm trying to target an element with exact text, but which also ignores the text of sibling elements. For example, target the span with Save below.
<span>Click and save money!</span>
<span>
<i>Icon</i>
Save
</span>
So something like //span[contains(text(), 'Save')] would grab any span with "Save" in it.
Try the xpath : //span[text()[normalize-space(.)='Save']]
It looks for span elements which have text nodes whose space-trimmed value is exactly Save
I am trying to find an element using Protractor. There are many drop downs on a page and I need to find the right one. The only way I can see of doing this is to find the grandparent of the item and then look at another grandchild which contains the label.
This works but returns many items:
element(by.xpath("//span[#class='k-widget k-dropdown k-header ng-isolate-scope']
I am trying then to tack on the additional parts to find the grandparent and then a child "a" tag and then a child "span" which contains the text I need to match against.
So this is not working:
element(by.xpath("//span[#class='k-widget k-dropdown k-header ng-isolate-scope']//..//a/span[.='Country']"));
Anybody know what is wrong?
To find the grandparent of the context node you could use ../... Then to find a child node, you can use just the child axis. So, in your question, if the a element is a child of the grandparent of span, the xpath should be something like:
//span[#class='k-widget k-dropdown k-header ng-isolate-scope']/../../a
And, to find its child span with value Country:
//span[#class='k-widget k-dropdown k-header ng-isolate-scope']/../../a/span[.='Country']
I'm looking through HTML documents for the text: "Required". What I need to find is the element that holds the text. For example:
<p>... Required<p>
I would get to element name = p
However, it might not be in a <p> tag. It could be in any kind of tag, which is where this question differs from some of the other search text Stack Overflow questions.
Right now I'm using:
page.at(':contains("Required")')
but this only get me the full HTML element
The problem you have is the :contains pseudo class matches any element that has the searched for text anywhere in its descendants. You need to find the innermost element that contains such text. Since html is the ancestor of all elements, if the page contains the text anywhere then html will contain, and so that will be the first matching element.
I’m not sure you can achieve this with CSS, but you can use XPath like this:
page.at_xpath('//*[text()[contains(., "Required")]]')
This finds the first element node that has a text() node as a child that contains Required. When you have that node (if it exists) you can then call name on it to give the name of the element.
For CSS you can do:
page.at('[text()*="Required"]')
It's not real CSS though, or even a jQuery extra.
You should use CSS selectors:
page.css('p').text
How would I write a selector which searches for an element which contains specific text in any of its children.
This is what I have so far, but alas it doesn't work:
div.taskBlock[contains(., 'Open Activities')]
What about:
.//div[contains(#class, 'taskBlock') and .//*[contains(., 'Open Activities')]]
It finds div that contains class name taskBlock and it has descendants that contain text "Open Activities".
I need to extract all links from a html document having text as the inner element and not a reference to an image. Basically I would like to do a doc.select("//a/attribute::href") for all elements in a tree where doc.select("//a/text()") returns anything. Thanks!
Well you can write conditions in XPath in a predicate in square brackets, e.g. //a[text()]/#href selects the href attributes of all link (a) elements that have at least one text node child. Or if you want to make sure there is no img child element in the link you can use e.g. //a[not(img)]/#href.