Search for an element with a specific content? - ruby

Assuming I have the following HTML code:
...
<p>bla bla</p>
<h3>Foobar</h3>
<p>bla bla</p>
<p>bla bla</p>
<h3>Example</h3>
...
Is there a way to fetch the first h3 element which contains the text Foobar?

Since this is HTML, I would recommend CSS selectors:
puts doc.at_css('h3:contains("Foobar")')
#=> <h3>Foobar</h3>
CSS selectors tend to make for more readable expressions when parsing HTML. I tend to use XPath only for XML or when I need the full power of XPath expressions.

You can use the contains() XPath function:
doc.xpath("//h3[contains(text(), 'Foobar')]")
Or if the target text could be in a descendent text node of h3, use:
doc.xpath("//h3[contains(.//text(), 'Foobar')]")
To fetch the first matching element directly rather than an array, use at_xpath rather than xpath.

Related

How to convert below xpath to css?

How to change this XPath to CSS selector?
//div[following-sibling::div[contains(#class, 'active-member')]]
Does any XPath can be converted to CSS selector?
Not every XPath can be converted to CSS selector.
CSS selectors do not support matching elements according to their texts and not supporting traversing up to parent elements
As about converting this specific XPath to CSS selector I think it will be
div+div.active-member
However I'm not fully sure about this

How to exclude particular class/atrribute name in CSS selector in Selenium Automation?

I have below HTML sample code:
<a href="" title="Design" class="reMode_design reMode_hover">
<span>Design</span>
</a>
<a href="" title="Design"
class="reMode_design reMode_hover reMode_selected">
<span>Design</span>
</a>
Here, i need to define CSS for the 1st href element and want to ignore 2nd element which has this class "reMode_selected". How to define css for the 1st element by ignoring 2nd element???
I don't want to use Xpath and I am looking for like this below CSS selector:
element :fld_link, "[title='Design'] [class !='reMode_selected']"
This format doesn't work in SitePrism Cucumber. Need Help on how to exclude a attribute name in CSS selector...
You can do this with cssSelector
driver.find_element(:css,".reMode_design:not(.reMode_selected)")
You can do with this css locator a[title='Design']:not([class*='reMode_selected'])
Have you tried using an xpath to locate the element? Perhaps something like: //a[contains(#title, 'Design') and not(contains(#class, 'reMode_selected'))]
References/Examples:
Using not in xpath
Using and in xpath
You can use the not: css prefix as others have mentioned or you could combine a capybara query to return the element based off it's text, or use a waiter.
SitePrism is quite advanced, so pretty much all options are open to you

How to get node text without children?

I use Nokogiri for parse the html page with same content:
<p class="parent">
Useful text
<br>
<span class="child">Useless text</span>
</p>
When I call the method page.css('p.parent').text Nokogiri returns 'Useful text Useless text'. But I need only 'Useful text'.
How to get node text without children?
XPath includes the text() node test for selecting text nodes, so you could do:
page.xpath('//p[#class="parent"]/text()')
Using XPath to select HTML classes can become quite tricky if the element in question could belong to more than one class, so this might not be ideal.
Fortunately Nokogiri adds the text() selector to CSS, so you can use:
page.css('p.parent > text()')
to get the text nodes that are direct children of p.parent. This will also return some nodes that are whtespace only, so you may have to filter them out.
You should be able to use page.css('p.parent').children.remove.
Then your page.css('p.parent').text will return the text without the children nodes.
Note: the page will be modified by the remove

Xpath not working when element contains xml:lang attribute

I am using an Xpath expression in Adobe Indesign to generate the list of elements used. I came to know, that if the element contains "xml:lang" attribute, then my Xpath expression does not work in Adobe Indesign.
For example in the below XML:
<chapter>
<section>
<p xml:lang="en">This is sample para</p>
</section>
</chapter>
When I use the below Xpath expression to list elements it does not generate any values.
//p
Is there any things needs to be done additionally
I am not familiar with Adobe Indesign but in terms of XPath the path //p should select all p element nodes in the input XML, whether they have an xml:lang attribute should not matter.

Cucumber/Capybara: is it possible to mix xpath and css on the same command?

I have an xpath expression that looks like this:
find(:xpath, "//div[#id='drawer-1' and #class='drawer']/h2/a[#class='drawer-toggle']")
I was wondering, is it possible to somehow mix this with css to read something like this?
find("div#drawer-1.drawer/h2/a.drawer-toggle")
Or if this is not possible, is there another way to navigate a DOM with css?
Cheers!
You cannot mix xpath with css. However, in your example, the xpath can be translated to css.
You should be able to do:
find("div#drawer-1.drawer > h2 > a.drawer-toggle")
Note that the "/" are changed to ">". Xpath uses "/" as child selector, where as css uses ">".
A couple useful links:
Child selectors
A cheat sheet that compares xpath with css locators

Resources