Convert XPath to CSS - xpath

//td[#class='Bu']/following::td[#class='Bu']
or
//td[#class='Bu'][2]
both are the same result when using XPath, so how can I change/convert them to CSS?

You can only do this with a CSS selector if the second td.Bu is a following sibling (means they share the same parent), or their parents are siblings and there are only two of them:
td.Bu ~ td.Bu
If they're completely unrelated, then it's not possible with CSS.

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 do I get span text value in prototype

This is my prototype code:
$$('coupon-value').findAll("price").innerHTML
<span class="coupon-value"><span class="price">66.67</span></span>
How do I get the value of .price in the prototype? In my html code there are multiple price classes. In jquery it would be simple:
$(".coupon-value").find(".price").text();
But in prototype I have no idea. Can you help me?
If you would like to get the contents of the <span> with the price class that is a child of a <span> with the coupon-value class you would do it like this
$$('.coupon-value .price').first().innerHTML
This will give you the first element that matches that CSS selector. You can also be very specific with your CSS selection as well.
$$('span.coupon-value span.price').first().innerHTML
you can also select that element and then traverse down the DOM like this
$$('.coupon-value').first().down('.price').innerHTML
Just be aware $$() returns an array of elements that match the CSS selector so you cannot just operate on them like a jQuery collection. However all of the elements in that array are already extended with the PrototypeJS extensions.
Try:
$$('coupon-value').getElementsByClassName("price").innerHTML;
You can change innerHTML for [0]
Like this:
$$('coupon-value .price')[0];
Or even this:
$$('span.price')[0];

Search for an element with a specific content?

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.

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

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