XPATH - how to get the text if an element contains a certain class - xpath

JHow do I grab this text here?
I am trying to grab the text here based on that the href contains "#faq-default".
I tried this first of all but it doesn't grab the text, only the actual href name, which is pointless:
//a/#href[contains(., '#faq-default-2')]
There will be many of these hrefs, such as default-2, default-3 so I need to do some kind of contains query, I'd guess?

You are selecting the #href node value instead of the a element value. So try this instead:
//a[contains(#href, '#faq-default-2')]

Related

How to find the exact element path without using xpath

I'm currently trying to locate this check box. I know I can use a xpath to locate it but I'm trying to see if there's a more efficient way of doing it. The problem I'm seeing is that there are multiple div class with the same name. I'm trying to find this specific one and isolate it. I'm trying to make my code more efficient if possible.
Xpath
/html/body/div/div/div/div[1]/cow-data/cat-panel/section/div[1]/div/div/md- checkbox[4]/div[1]
Element path:
<div class="cd-container" cd-gar-ripple="" cd-gar-ripple-checkbox=""><div class="cd-icon"></div></div>
Code I'm trying to use:
find('cd-container').click
The problem I'm seeing is that the div id 'cd-container' has multiple occurrences on the page and thus this doesn't work. I'm trying to see if I can find a more efficient way of doing this.
As per the HTML cd-container is the value of the class attribute but not id attribute. So your effective line of code will be:
find('.cd-container').click
If you want to find an element (AND THEN), return it's xpath. Use capybara.
This will allow you to locate using text / css selector. And then you can just return the path of the element.
i.e.
page.find('td', text: 'Column 1').path # Random td with text
page.find('#main').path # ID
page.all('div').select { |element| element.text == 'COoL dIv' }.first.path # First div that matches certain text
page.find('.form > div:nth-of-type(2)').path # Specific structured div
page.all('p div li:nth-child(3)').sample.path # Random li

xpath - element containing exact text, but minus sibling elements?

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

What is the proper way to use descendant in XPath

I am trying to find all DIV elements have the attribute widget-name and a descendant span tag that have a title attribute.
This is what I am trying.
//div[#widget-name and descendant::span[#title]]"
This seems to almost work but it is missing one element in the Nodes Collection it returns.
Never mind.
This is what I needed:
//div[#widget-name and descendant::span[#class='title']]
OK - take it back.
This is not the complete answer.
I am now trying to tweak this to where it returns all except where title is not equal to some text:
//div[#widget-name and descendant::span[#class='title' and [text()[contains(., '{someTextToKeep}'
Anyone see why this would be invalid XPath?
Final answer is:
//div[#widget-name and descendant::span[#class='title' and text()[not(contains(., 'someTextToKeep'))]]]"
This XPath should return all div's that:
has a widget-name attribute
has a descendant span element (used abbreviated syntax) that:
has a class attribute with the value 'title'
contains the text 'someTextToKeep' (if you want to exclude spans with certain text, wrap the contains() in not().
XPath:
//div[#widget-name and .//span[#class='title'][contains(.,'someTextToKeep')]]

Get element name by containing text

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

xpath search for divs where the id contains specific text

On my HTML page I have forty divs but I only want one div.
Using agility pack to search and get all the divs with Ids I use this XPath:
"//div[#id]"
But how do I search for divs with Ids where the id contains the text "test" like so:
<div id="outerdivtest1></div>"
Use the contains function:
//div[contains(#id,'test')]
I've used this with for the CSS class:
//div[#class = 'atom']
I assume it's similar with id's.
You can use the xpath
//div[#contains(#id,'test')]
If you want to use the first occurrence, it works fine but if it's not the first occurrence you have to go with different xpath specific to the particular element.
For example if you want first selection "id" is like that
(//[#id="numberIdentify"])//following:://a[contains(text(),'V ')]

Resources