driver can be queried for supported query formats and support for native css queries within a scope

This commit is contained in:
Thomas Walpole 2013-02-18 12:35:24 -08:00
parent 4f805d5a1c
commit 4a5876d95e
11 changed files with 53 additions and 29 deletions

View File

@ -99,8 +99,8 @@ module Capybara
# @param [Symbol] name The name of the selector to add
# @yield A block executed in the context of the new {Capybara::Selector}
#
def add_selector(name, &block)
Capybara::Selector.add(name, &block)
def add_selector(name, preferred_format=:xpath, &block)
Capybara::Selector.add(name, preferred_format, &block)
end
def drivers

View File

@ -7,7 +7,7 @@ class Capybara::Driver::Base
raise NotImplementedError
end
def find(query)
def find(query_format=:xpath, query)
raise NotImplementedError
end
@ -57,4 +57,8 @@ class Capybara::Driver::Base
def needs_server?
false
end
def supports_query_format?(format)
format==:xpath
end
end

View File

@ -146,8 +146,8 @@ module Capybara
def resolve_query(query, exact=nil)
elements = synchronize do
# base.find(query.xpath(exact)).map do |node|
if query.selector.name==:css && base.respond_to?(:find_css)
base.find_css(query.locator)
if query.selector.preferred_format==:css and driver.supports_query_format?(:css)
base.find(:css, query.locator)
else
base.find(query.xpath(exact))
end.map do |node|

View File

@ -80,8 +80,8 @@ class Capybara::RackTest::Browser
@dom ||= Nokogiri::HTML(html)
end
def find(selector, type=:xpath)
if type==:css
def find(format=:xpath, selector)
if format==:css
dom.css(selector, Class.new {
def disabled list
list.find_all { |node| node.has_attribute? 'disabled' }

View File

@ -62,14 +62,10 @@ class Capybara::RackTest::Driver < Capybara::Driver::Base
response.status
end
def find(selector)
browser.find(selector)
def find(format=:xpath, selector)
browser.find(format, selector)
end
def find_css(selector)
browser.find(selector, :css)
end
def html
browser.html
end

View File

@ -1,6 +1,6 @@
module Capybara
class Selector
attr_reader :name, :custom_filters
attr_reader :name, :custom_filters, :preferred_format
class << self
@ -8,8 +8,8 @@ module Capybara
@selectors ||= {}
end
def add(name, &block)
all[name.to_sym] = Capybara::Selector.new(name.to_sym, &block)
def add(name, preferred_format=:xpath, &block)
all[name.to_sym] = Capybara::Selector.new(name.to_sym, preferred_format, &block)
end
def remove(name)
@ -17,12 +17,13 @@ module Capybara
end
end
def initialize(name, &block)
def initialize(name, preferred_format, &block)
@name = name
@custom_filters = {}
@match = nil
@label = nil
@failure_message = nil
@preferred_format = preferred_format
instance_eval(&block)
end
@ -67,7 +68,7 @@ Capybara.add_selector(:xpath) do
xpath { |xpath| xpath }
end
Capybara.add_selector(:css) do
Capybara.add_selector(:css, :css) do
css { |css| css }
end

View File

@ -46,14 +46,10 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
browser.current_url
end
def find(selector)
browser.find_elements(:xpath, selector).map { |node| Capybara::Selenium::Node.new(self, node) }
def find(selector_format=:xpath, selector)
browser.find_elements(selector_format, selector).map { |node| Capybara::Selenium::Node.new(self, node) }
end
def find_css(selector)
browser.find_elements(:css, selector).map { |node| Capybara::Selenium::Node.new(self, node) }
end
def wait?; true; end
def needs_server?; true; end
@ -131,4 +127,8 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
def invalid_element_errors
[Selenium::WebDriver::Error::StaleElementReferenceError, Selenium::WebDriver::Error::UnhandledError, Selenium::WebDriver::Error::ElementNotVisibleError]
end
def supports_query_format?(format)
[:xpath, :css].include? format
end
end

View File

@ -76,8 +76,8 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
alias :checked? :selected?
def find(locator)
native.find_elements(:xpath, locator).map { |n| self.class.new(driver, n) }
def find(locator_format=:xpath, locator)
native.find_elements(locator_format, locator).map { |n| self.class.new(driver, n) }
end
def ==(other)

View File

@ -42,8 +42,13 @@ Capybara::SpecHelper.spec '#find' do
@session.find(:css, "input[id='test_field']")[:value].should == 'monkey'
end
it "should support pseudo selectors" do
@session.find(:css, 'input:disabled').value.should == 'This is disabled'
context "with native css query", requires: [:native_css] do
it "should support pseudo selectors" do
unless @session.driver.supports_query_format?(:css)
pending "#{@session.driver.class.name} doesn't support native css queries"
end
@session.find(:css, 'input:disabled').value.should == 'This is disabled'
end
end
end
@ -300,5 +305,17 @@ Capybara::SpecHelper.spec '#find' do
@session.find('.//li[1]').text.should =~ /With Simple HTML/
end
end
context "with native css query", requires: [:native_css] do
it "should find an element using the given css locator" do
unless @session.driver.supports_query_format?(:css)
pending "#{@session.driver.class.name} doesn't support native css queries"
end
@session.within(:xpath, "//div[@id='for_bar']") do
@session.find(:css, 'input:disabled').value.should == 'James'
end
end
end
end
end

View File

@ -4,6 +4,7 @@
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim venia.
<a href="/redirect">Go</a>
<input name="disabled" disabled/>
</p>
<div id="for_bar">
@ -23,6 +24,10 @@
<label for="bar_first_name">First Name</label>
<input type="text" name="form[first_name]" value="Peter" id="bar_first_name"/>
</p>
<p>
<label for="bar_other_name">Other Name</label>
<input type="text" name="form[other_name]" value="James" id="bar_other_name" disabled/>
</p>
<p><input type="submit" value="Go"/></p>
</form>
</li>

View File

@ -10,7 +10,8 @@ Capybara::SpecHelper.run_specs TestClass.new, "DSL", :skip => [
:screenshot,
:frames,
:windows,
:server
:server,
:native_css
]
describe Capybara::DSL do