1
0
Fork 0
mirror of https://github.com/teamcapybara/capybara.git synced 2022-11-09 12:08:07 -05:00

Add section about custom selectors to README

This commit is contained in:
Jonas Nicklas 2010-08-27 21:07:26 +02:00
parent d995bfba42
commit fed2c5ba94

View file

@ -364,7 +364,7 @@ For ultimate control, you can instantiate and use a session manually.
end
session.click_link 'Sign in'
== XPath and CSS
== XPath, CSS and selectors
Capybara does not try to guess what kind of selector you are going to give it,
if you want to use XPath with your 'within' declarations for example, you'll need
@ -379,24 +379,51 @@ Alternatively you can set the default selector to XPath:
Capybara.default_selector = :xpath
find('//ul/li').text
Capybara allows you to add custom selectors, which can be very useful if you
find yourself using the same kinds of selectors very often:
Capybara::Selector.add(:id) { |id| XPath.descendant[XPath.attr(:id) == id.to_s] }
Capybara::Selector.add(:row) { |num| ".//tbody/tr[#{num}]" }
These must always return an XPath expression as a String, or an XPath expression
generated through the XPath gem. You can now use these selectors like this:
find(:id, 'post_123')
find(:row, 3)
You can specify an optional :for option which will automatically use the
selector if it matches the argument to find using ===:
Capybara::Selector.add(:id, :for => Symbol) { |id| XPath.descendant[XPath.attr(:id) == id.to_s] }
Now use it like this:
find(:post_123)
This :id selector is already built into Capybara by default, so you don't
need to add it yourself.
== Beware the XPath // trap
In XPath the expression // means something very specific, and it might not be what
you think. Contrary to common belief, // means "anywhere in the document" not "anywhere
in the current context". As an example:
page.find('//body').all('//script')
page.find(:xpath, '//body').all(:xpath, '//script')
You might expect this to find all script tags in the body, but actually, it finds all
script tags in the entire document, not only those in the body! What you're looking
for is the .// expression which means "any descendant of the current node":
page.find('//body').all('.//script')
page.find(:xpath, '//body').all(:xpath, './/script')
The same thing goes for within:
within('//body') do
page.find('.//script')
within(:xpath, '//body') do
page.find(:xpath, './/script')
within(:xpath, './/table/tbody') do
...
end
end
== Gotchas: