From 4f805d5a1c42da29ed32ab0371e24add2dc08af1 Mon Sep 17 00:00:00 2001 From: Thomas Walpole Date: Sat, 16 Feb 2013 13:26:01 -0800 Subject: [PATCH 1/9] dont convert css to xpath --- lib/capybara/node/finders.rb | 7 ++++++- lib/capybara/query.rb | 1 - lib/capybara/rack_test/browser.rb | 15 +++++++++++++-- lib/capybara/rack_test/driver.rb | 4 ++++ lib/capybara/selenium/driver.rb | 4 ++++ lib/capybara/spec/session/find_spec.rb | 4 ++++ lib/capybara/spec/views/with_html.erb | 2 ++ 7 files changed, 33 insertions(+), 4 deletions(-) diff --git a/lib/capybara/node/finders.rb b/lib/capybara/node/finders.rb index 6ef1de87..a198f2b3 100644 --- a/lib/capybara/node/finders.rb +++ b/lib/capybara/node/finders.rb @@ -145,7 +145,12 @@ module Capybara def resolve_query(query, exact=nil) elements = synchronize do - base.find(query.xpath(exact)).map do |node| + # base.find(query.xpath(exact)).map do |node| + if query.selector.name==:css && base.respond_to?(:find_css) + base.find_css(query.locator) + else + base.find(query.xpath(exact)) + end.map do |node| Capybara::Node::Element.new(session, node, self, query) end end diff --git a/lib/capybara/query.rb b/lib/capybara/query.rb index 67b5e74a..88ec0031 100644 --- a/lib/capybara/query.rb +++ b/lib/capybara/query.rb @@ -85,7 +85,6 @@ module Capybara def xpath(exact=nil) exact = @options[:exact] if exact == nil - if @xpath.respond_to?(:to_xpath) and exact @xpath.to_xpath(:exact) else diff --git a/lib/capybara/rack_test/browser.rb b/lib/capybara/rack_test/browser.rb index 53510e40..7f756350 100644 --- a/lib/capybara/rack_test/browser.rb +++ b/lib/capybara/rack_test/browser.rb @@ -80,8 +80,19 @@ class Capybara::RackTest::Browser @dom ||= Nokogiri::HTML(html) end - def find(selector) - dom.xpath(selector).map { |node| Capybara::RackTest::Node.new(self, node) } + def find(selector, type=:xpath) + if type==:css + dom.css(selector, Class.new { + def disabled list + list.find_all { |node| node.has_attribute? 'disabled' } + end + def enabled list + list.find_all { |node| !node.has_attribute? 'disabled' } + end + }.new) + else + dom.xpath(selector) + end.map { |node| Capybara::RackTest::Node.new(self, node) } end def html diff --git a/lib/capybara/rack_test/driver.rb b/lib/capybara/rack_test/driver.rb index 7dc84120..8e13635f 100644 --- a/lib/capybara/rack_test/driver.rb +++ b/lib/capybara/rack_test/driver.rb @@ -65,6 +65,10 @@ class Capybara::RackTest::Driver < Capybara::Driver::Base def find(selector) browser.find(selector) end + + def find_css(selector) + browser.find(selector, :css) + end def html browser.html diff --git a/lib/capybara/selenium/driver.rb b/lib/capybara/selenium/driver.rb index a620bbf6..76c00687 100644 --- a/lib/capybara/selenium/driver.rb +++ b/lib/capybara/selenium/driver.rb @@ -49,6 +49,10 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base def find(selector) browser.find_elements(:xpath, 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 diff --git a/lib/capybara/spec/session/find_spec.rb b/lib/capybara/spec/session/find_spec.rb index 22cc8a01..8273c592 100644 --- a/lib/capybara/spec/session/find_spec.rb +++ b/lib/capybara/spec/session/find_spec.rb @@ -41,6 +41,10 @@ Capybara::SpecHelper.spec '#find' do @session.find(:css, 'h1').text.should == 'This is a test' @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' + end end context "with xpath selectors" do diff --git a/lib/capybara/spec/views/with_html.erb b/lib/capybara/spec/views/with_html.erb index babb19a9..fb5b8a99 100644 --- a/lib/capybara/spec/views/with_html.erb +++ b/lib/capybara/spec/views/with_html.erb @@ -89,3 +89,5 @@ banana
almost singular but not quite
almost singular
+ + From 4a5876d95e448ad2140d035adb8f7a8a3e46bf6f Mon Sep 17 00:00:00 2001 From: Thomas Walpole Date: Mon, 18 Feb 2013 12:35:24 -0800 Subject: [PATCH 2/9] driver can be queried for supported query formats and support for native css queries within a scope --- lib/capybara.rb | 4 ++-- lib/capybara/driver/base.rb | 6 +++++- lib/capybara/node/finders.rb | 4 ++-- lib/capybara/rack_test/browser.rb | 4 ++-- lib/capybara/rack_test/driver.rb | 8 ++------ lib/capybara/selector.rb | 11 ++++++----- lib/capybara/selenium/driver.rb | 12 ++++++------ lib/capybara/selenium/node.rb | 4 ++-- lib/capybara/spec/session/find_spec.rb | 21 +++++++++++++++++++-- lib/capybara/spec/views/with_scope.erb | 5 +++++ spec/dsl_spec.rb | 3 ++- 11 files changed, 53 insertions(+), 29 deletions(-) diff --git a/lib/capybara.rb b/lib/capybara.rb index 785e2401..d89f5dc9 100644 --- a/lib/capybara.rb +++ b/lib/capybara.rb @@ -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 diff --git a/lib/capybara/driver/base.rb b/lib/capybara/driver/base.rb index 7424e17a..4b0a63d1 100644 --- a/lib/capybara/driver/base.rb +++ b/lib/capybara/driver/base.rb @@ -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 diff --git a/lib/capybara/node/finders.rb b/lib/capybara/node/finders.rb index a198f2b3..84ebccab 100644 --- a/lib/capybara/node/finders.rb +++ b/lib/capybara/node/finders.rb @@ -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| diff --git a/lib/capybara/rack_test/browser.rb b/lib/capybara/rack_test/browser.rb index 7f756350..90803667 100644 --- a/lib/capybara/rack_test/browser.rb +++ b/lib/capybara/rack_test/browser.rb @@ -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' } diff --git a/lib/capybara/rack_test/driver.rb b/lib/capybara/rack_test/driver.rb index 8e13635f..d2c504ee 100644 --- a/lib/capybara/rack_test/driver.rb +++ b/lib/capybara/rack_test/driver.rb @@ -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 diff --git a/lib/capybara/selector.rb b/lib/capybara/selector.rb index 7246c1ab..02479c84 100644 --- a/lib/capybara/selector.rb +++ b/lib/capybara/selector.rb @@ -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 diff --git a/lib/capybara/selenium/driver.rb b/lib/capybara/selenium/driver.rb index 76c00687..6ac63fe9 100644 --- a/lib/capybara/selenium/driver.rb +++ b/lib/capybara/selenium/driver.rb @@ -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 diff --git a/lib/capybara/selenium/node.rb b/lib/capybara/selenium/node.rb index c0922ae1..1ba7cd99 100644 --- a/lib/capybara/selenium/node.rb +++ b/lib/capybara/selenium/node.rb @@ -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) diff --git a/lib/capybara/spec/session/find_spec.rb b/lib/capybara/spec/session/find_spec.rb index 8273c592..dd83aa79 100644 --- a/lib/capybara/spec/session/find_spec.rb +++ b/lib/capybara/spec/session/find_spec.rb @@ -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 diff --git a/lib/capybara/spec/views/with_scope.erb b/lib/capybara/spec/views/with_scope.erb index 4d18b80c..5a445477 100644 --- a/lib/capybara/spec/views/with_scope.erb +++ b/lib/capybara/spec/views/with_scope.erb @@ -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. Go +

@@ -23,6 +24,10 @@

+

+ + +

diff --git a/spec/dsl_spec.rb b/spec/dsl_spec.rb index 7bb7a531..50a6990e 100644 --- a/spec/dsl_spec.rb +++ b/spec/dsl_spec.rb @@ -10,7 +10,8 @@ Capybara::SpecHelper.run_specs TestClass.new, "DSL", :skip => [ :screenshot, :frames, :windows, - :server + :server, + :native_css ] describe Capybara::DSL do From fb6c0ce9e573b16b9dc70c8606b58d948a376869 Mon Sep 17 00:00:00 2001 From: Thomas Walpole Date: Mon, 18 Feb 2013 13:08:34 -0800 Subject: [PATCH 3/9] fix failing specs due to invalid css --- lib/capybara/spec/session/within_spec.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/capybara/spec/session/within_spec.rb b/lib/capybara/spec/session/within_spec.rb index 46eaf74a..da31a2f5 100644 --- a/lib/capybara/spec/session/within_spec.rb +++ b/lib/capybara/spec/session/within_spec.rb @@ -5,7 +5,7 @@ Capybara::SpecHelper.spec '#within' do context "with CSS selector" do it "should click links in the given scope" do - @session.within(:css, "#for_bar li[contains('With Simple HTML')]") do + @session.within(:css, "#for_bar li", text: 'With Simple HTML') do @session.click_link('Go') end @session.should have_content('Bar') @@ -46,7 +46,7 @@ Capybara::SpecHelper.spec '#within' do context "with Node rather than selector" do it "should click links in the given scope" do - node_of_interest = @session.find(:css, "#for_bar li[contains('With Simple HTML')]") + node_of_interest = @session.find(:css, "#for_bar li", text: 'With Simple HTML') @session.within(node_of_interest) do @session.click_link('Go') @@ -58,7 +58,7 @@ Capybara::SpecHelper.spec '#within' do context "with the default selector set to CSS" do before { Capybara.default_selector = :css } it "should use CSS" do - @session.within("#for_bar li[contains('With Simple HTML')]") do + @session.within("#for_bar li", text: 'With Simple HTML') do @session.click_link('Go') end @session.should have_content('Bar') From f6ababc62ddff900cec648f2026f05da3b32d5ba Mon Sep 17 00:00:00 2001 From: Thomas Walpole Date: Mon, 18 Feb 2013 14:41:44 -0800 Subject: [PATCH 4/9] Selector remembers format, CSSHelpers, and drivers assumed to handle css --- lib/capybara.rb | 5 +++-- lib/capybara/driver/base.rb | 4 ---- lib/capybara/node/finders.rb | 4 ++-- lib/capybara/rack_test/browser.rb | 11 ++--------- lib/capybara/rack_test/node.rb | 8 ++++++-- lib/capybara/selector.rb | 11 ++++++----- lib/capybara/selenium/driver.rb | 3 --- lib/capybara/spec/session/find_spec.rb | 7 ------- 8 files changed, 19 insertions(+), 34 deletions(-) diff --git a/lib/capybara.rb b/lib/capybara.rb index d89f5dc9..bbcdde65 100644 --- a/lib/capybara.rb +++ b/lib/capybara.rb @@ -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, preferred_format=:xpath, &block) - Capybara::Selector.add(name, preferred_format, &block) + def add_selector(name, &block) + Capybara::Selector.add(name, &block) end def drivers @@ -327,6 +327,7 @@ module Capybara autoload :Node, 'capybara/rack_test/node' autoload :Form, 'capybara/rack_test/form' autoload :Browser, 'capybara/rack_test/browser' + autoload :CSSHandlers, 'capybara/rack_test/css_handlers.rb' end module Selenium diff --git a/lib/capybara/driver/base.rb b/lib/capybara/driver/base.rb index 4b0a63d1..bd830758 100644 --- a/lib/capybara/driver/base.rb +++ b/lib/capybara/driver/base.rb @@ -57,8 +57,4 @@ class Capybara::Driver::Base def needs_server? false end - - def supports_query_format?(format) - format==:xpath - end end diff --git a/lib/capybara/node/finders.rb b/lib/capybara/node/finders.rb index 84ebccab..62aecb02 100644 --- a/lib/capybara/node/finders.rb +++ b/lib/capybara/node/finders.rb @@ -146,10 +146,10 @@ module Capybara def resolve_query(query, exact=nil) elements = synchronize do # base.find(query.xpath(exact)).map do |node| - if query.selector.preferred_format==:css and driver.supports_query_format?(:css) + if query.selector.preferred_format==:css base.find(:css, query.locator) else - base.find(query.xpath(exact)) + base.find(:xpath, query.xpath(exact)) end.map do |node| Capybara::Node::Element.new(session, node, self, query) end diff --git a/lib/capybara/rack_test/browser.rb b/lib/capybara/rack_test/browser.rb index 90803667..6219cd68 100644 --- a/lib/capybara/rack_test/browser.rb +++ b/lib/capybara/rack_test/browser.rb @@ -82,14 +82,7 @@ class Capybara::RackTest::Browser def find(format=:xpath, selector) if format==:css - dom.css(selector, Class.new { - def disabled list - list.find_all { |node| node.has_attribute? 'disabled' } - end - def enabled list - list.find_all { |node| !node.has_attribute? 'disabled' } - end - }.new) + dom.css(selector, Capybara::RackTest::CSSHandlers.new) else dom.xpath(selector) end.map { |node| Capybara::RackTest::Node.new(self, node) } @@ -104,7 +97,7 @@ class Capybara::RackTest::Browser def title dom.xpath("//title").text end - + protected def build_rack_mock_session diff --git a/lib/capybara/rack_test/node.rb b/lib/capybara/rack_test/node.rb index cc7f7888..23ec915e 100644 --- a/lib/capybara/rack_test/node.rb +++ b/lib/capybara/rack_test/node.rb @@ -76,8 +76,12 @@ class Capybara::RackTest::Node < Capybara::Driver::Node native.path end - def find(locator) - native.xpath(locator).map { |n| self.class.new(driver, n) } + def find(format=:xpath, locator) + if format==:css + native.css(locator, Capybara::RackTest::CSSHandlers.new) + else + native.xpath(locator) + end.map { |n| self.class.new(driver, n) } end def ==(other) diff --git a/lib/capybara/selector.rb b/lib/capybara/selector.rb index 02479c84..1bcb7b65 100644 --- a/lib/capybara/selector.rb +++ b/lib/capybara/selector.rb @@ -8,8 +8,8 @@ module Capybara @selectors ||= {} end - def add(name, preferred_format=:xpath, &block) - all[name.to_sym] = Capybara::Selector.new(name.to_sym, preferred_format, &block) + def add(name, &block) + all[name.to_sym] = Capybara::Selector.new(name.to_sym, &block) end def remove(name) @@ -17,13 +17,13 @@ module Capybara end end - def initialize(name, preferred_format, &block) + def initialize(name, &block) @name = name @custom_filters = {} @match = nil @label = nil @failure_message = nil - @preferred_format = preferred_format + @preferred_format = :xpath instance_eval(&block) end @@ -34,6 +34,7 @@ module Capybara # Same as xpath, but wrap in XPath.css(). def css(&block) + @preferred_format = :css if block @xpath = xpath { |*args| XPath.css(block.call(*args)) } end @@ -68,7 +69,7 @@ Capybara.add_selector(:xpath) do xpath { |xpath| xpath } end -Capybara.add_selector(:css, :css) do +Capybara.add_selector(:css) do css { |css| css } end diff --git a/lib/capybara/selenium/driver.rb b/lib/capybara/selenium/driver.rb index 6ac63fe9..70d0ee57 100644 --- a/lib/capybara/selenium/driver.rb +++ b/lib/capybara/selenium/driver.rb @@ -128,7 +128,4 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base [Selenium::WebDriver::Error::StaleElementReferenceError, Selenium::WebDriver::Error::UnhandledError, Selenium::WebDriver::Error::ElementNotVisibleError] end - def supports_query_format?(format) - [:xpath, :css].include? format - end end diff --git a/lib/capybara/spec/session/find_spec.rb b/lib/capybara/spec/session/find_spec.rb index dd83aa79..54cc7228 100644 --- a/lib/capybara/spec/session/find_spec.rb +++ b/lib/capybara/spec/session/find_spec.rb @@ -44,9 +44,6 @@ Capybara::SpecHelper.spec '#find' do 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 @@ -308,10 +305,6 @@ Capybara::SpecHelper.spec '#find' do 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 From f53b83227f46f802a16a08e0c5c1b66a04b72eb5 Mon Sep 17 00:00:00 2001 From: Thomas Walpole Date: Mon, 18 Feb 2013 14:46:37 -0800 Subject: [PATCH 5/9] Add the CSSHandlers file --- lib/capybara/rack_test/css_handlers.rb | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 lib/capybara/rack_test/css_handlers.rb diff --git a/lib/capybara/rack_test/css_handlers.rb b/lib/capybara/rack_test/css_handlers.rb new file mode 100644 index 00000000..0d5b2374 --- /dev/null +++ b/lib/capybara/rack_test/css_handlers.rb @@ -0,0 +1,8 @@ +class Capybara::RackTest::CSSHandlers + def disabled list + list.find_all { |node| node.has_attribute? 'disabled' } + end + def enabled list + list.find_all { |node| !node.has_attribute? 'disabled' } + end +end From 5ff2e65680d0f7aa9d9f2d42861853998491ce35 Mon Sep 17 00:00:00 2001 From: Thomas Walpole Date: Mon, 18 Feb 2013 16:01:52 -0800 Subject: [PATCH 6/9] remove unused XPath.css conversion --- lib/capybara/node/finders.rb | 2 +- lib/capybara/node/simple.rb | 6 +++++- lib/capybara/query.rb | 4 ++++ lib/capybara/selector.rb | 4 +--- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/capybara/node/finders.rb b/lib/capybara/node/finders.rb index 62aecb02..2c0b73dd 100644 --- a/lib/capybara/node/finders.rb +++ b/lib/capybara/node/finders.rb @@ -147,7 +147,7 @@ module Capybara elements = synchronize do # base.find(query.xpath(exact)).map do |node| if query.selector.preferred_format==:css - base.find(:css, query.locator) + base.find(:css, query.css) else base.find(:xpath, query.xpath(exact)) end.map do |node| diff --git a/lib/capybara/node/simple.rb b/lib/capybara/node/simple.rb index bb5abab6..070d200f 100644 --- a/lib/capybara/node/simple.rb +++ b/lib/capybara/node/simple.rb @@ -154,7 +154,11 @@ module Capybara private def resolve_query(query, exact=nil) - elements = native.xpath(query.xpath(exact)).map do |node| + elements = if query.selector.preferred_format == :css + native.css(query.css) + else + native.xpath(query.xpath(exact)) + end.map do |node| self.class.new(node) end Capybara::Result.new(elements, query) diff --git a/lib/capybara/query.rb b/lib/capybara/query.rb index 88ec0031..3fa86d5d 100644 --- a/lib/capybara/query.rb +++ b/lib/capybara/query.rb @@ -91,6 +91,10 @@ module Capybara @xpath.to_s end end + + def css + @xpath + end private diff --git a/lib/capybara/selector.rb b/lib/capybara/selector.rb index 1bcb7b65..159e1fec 100644 --- a/lib/capybara/selector.rb +++ b/lib/capybara/selector.rb @@ -35,9 +35,7 @@ module Capybara # Same as xpath, but wrap in XPath.css(). def css(&block) @preferred_format = :css - if block - @xpath = xpath { |*args| XPath.css(block.call(*args)) } - end + @xpath = block if block @xpath end From eba8eaba409222fa0feaf82684611a09e26b8155 Mon Sep 17 00:00:00 2001 From: Thomas Walpole Date: Tue, 19 Feb 2013 09:03:26 -0800 Subject: [PATCH 7/9] change node and driver api to use find_xpath and find_css --- lib/capybara/driver/base.rb | 6 +++++- lib/capybara/node/finders.rb | 4 ++-- lib/capybara/rack_test/browser.rb | 2 +- lib/capybara/rack_test/driver.rb | 8 ++++++-- lib/capybara/rack_test/node.rb | 18 +++++++++--------- lib/capybara/selenium/driver.rb | 8 ++++++-- lib/capybara/selenium/node.rb | 12 ++++++++---- spec/rack_test_spec.rb | 4 ++-- 8 files changed, 39 insertions(+), 23 deletions(-) diff --git a/lib/capybara/driver/base.rb b/lib/capybara/driver/base.rb index bd830758..83fd58e2 100644 --- a/lib/capybara/driver/base.rb +++ b/lib/capybara/driver/base.rb @@ -7,7 +7,11 @@ class Capybara::Driver::Base raise NotImplementedError end - def find(query_format=:xpath, query) + def find_xpath(query) + raise NotImplementedError + end + + def find_css(query) raise NotImplementedError end diff --git a/lib/capybara/node/finders.rb b/lib/capybara/node/finders.rb index 2c0b73dd..2f4e1c29 100644 --- a/lib/capybara/node/finders.rb +++ b/lib/capybara/node/finders.rb @@ -147,9 +147,9 @@ module Capybara elements = synchronize do # base.find(query.xpath(exact)).map do |node| if query.selector.preferred_format==:css - base.find(:css, query.css) + base.find_css(query.css) else - base.find(:xpath, query.xpath(exact)) + base.find_xpath(query.xpath(exact)) end.map do |node| Capybara::Node::Element.new(session, node, self, query) end diff --git a/lib/capybara/rack_test/browser.rb b/lib/capybara/rack_test/browser.rb index 6219cd68..5c92df8d 100644 --- a/lib/capybara/rack_test/browser.rb +++ b/lib/capybara/rack_test/browser.rb @@ -80,7 +80,7 @@ class Capybara::RackTest::Browser @dom ||= Nokogiri::HTML(html) end - def find(format=:xpath, selector) + def find(format, selector) if format==:css dom.css(selector, Capybara::RackTest::CSSHandlers.new) else diff --git a/lib/capybara/rack_test/driver.rb b/lib/capybara/rack_test/driver.rb index d2c504ee..35c38ffc 100644 --- a/lib/capybara/rack_test/driver.rb +++ b/lib/capybara/rack_test/driver.rb @@ -62,8 +62,12 @@ class Capybara::RackTest::Driver < Capybara::Driver::Base response.status end - def find(format=:xpath, selector) - browser.find(format, selector) + def find_xpath(selector) + browser.find(:xpath, selector) + end + + def find_css(selector) + browser.find(:css,selector) end def html diff --git a/lib/capybara/rack_test/node.rb b/lib/capybara/rack_test/node.rb index 23ec915e..2af07382 100644 --- a/lib/capybara/rack_test/node.rb +++ b/lib/capybara/rack_test/node.rb @@ -29,7 +29,7 @@ class Capybara::RackTest::Node < Capybara::Driver::Node def select_option if select_node['multiple'] != 'multiple' - select_node.find(".//option[@selected]").each { |node| node.native.remove_attribute("selected") } + select_node.find_xpath(".//option[@selected]").each { |node| node.native.remove_attribute("selected") } end native["selected"] = 'selected' end @@ -76,14 +76,14 @@ class Capybara::RackTest::Node < Capybara::Driver::Node native.path end - def find(format=:xpath, locator) - if format==:css - native.css(locator, Capybara::RackTest::CSSHandlers.new) - else - native.xpath(locator) - end.map { |n| self.class.new(driver, n) } + def find_xpath(locator) + native.xpath(locator).map { |n| self.class.new(driver, n) } end - + + def find_css(locator) + native.css(locator, Capybara::RackTest::CSSHandlers.new).map { |n| self.class.new(driver, n) } + end + def ==(other) native == other.native end @@ -112,7 +112,7 @@ private # a reference to the select node if this is an option node def select_node - find('./ancestor::select').first + find_xpath('./ancestor::select').first end def type diff --git a/lib/capybara/selenium/driver.rb b/lib/capybara/selenium/driver.rb index 70d0ee57..36aebc3b 100644 --- a/lib/capybara/selenium/driver.rb +++ b/lib/capybara/selenium/driver.rb @@ -46,8 +46,12 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base browser.current_url end - def find(selector_format=:xpath, selector) - browser.find_elements(selector_format, selector).map { |node| Capybara::Selenium::Node.new(self, node) } + def find_xpath(selector) + browser.find_elements(:xpath, 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 diff --git a/lib/capybara/selenium/node.rb b/lib/capybara/selenium/node.rb index 1ba7cd99..8f5c431a 100644 --- a/lib/capybara/selenium/node.rb +++ b/lib/capybara/selenium/node.rb @@ -76,10 +76,14 @@ class Capybara::Selenium::Node < Capybara::Driver::Node alias :checked? :selected? - def find(locator_format=:xpath, locator) - native.find_elements(locator_format, locator).map { |n| self.class.new(driver, n) } + def find_xpath(locator) + native.find_elements(:xpath, locator).map { |n| self.class.new(driver, n) } end - + + def find_css(locator) + native.find_elements(:css, locator).map { |n| self.class.new(driver, n) } + end + def ==(other) native == other.native end @@ -88,6 +92,6 @@ private # a reference to the select node if this is an option node def select_node - find('./ancestor::select').first + find_xpath('./ancestor::select').first end end diff --git a/spec/rack_test_spec.rb b/spec/rack_test_spec.rb index 71dd4567..53ce9e8e 100644 --- a/spec/rack_test_spec.rb +++ b/spec/rack_test_spec.rb @@ -84,14 +84,14 @@ describe Capybara::RackTest::Driver do it 'should keep headers on link clicks' do @driver = Capybara::RackTest::Driver.new(TestApp, :headers => {'HTTP_FOO' => 'foobar'}) @driver.visit('/header_links') - @driver.find('.//a').first.click + @driver.find_xpath('.//a').first.click @driver.html.should include('foobar') end it 'should keep headers on form submit' do @driver = Capybara::RackTest::Driver.new(TestApp, :headers => {'HTTP_FOO' => 'foobar'}) @driver.visit('/header_links') - @driver.find('.//input').first.click + @driver.find_xpath('.//input').first.click @driver.html.should include('foobar') end From 88242b7a1274631028c32bd7005a21b221bd1aad Mon Sep 17 00:00:00 2001 From: Thomas Walpole Date: Tue, 19 Feb 2013 09:30:16 -0800 Subject: [PATCH 8/9] cleanup Selector variable naming --- lib/capybara/node/finders.rb | 2 +- lib/capybara/node/simple.rb | 2 +- lib/capybara/selector.rb | 16 ++++++++++------ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/capybara/node/finders.rb b/lib/capybara/node/finders.rb index 2f4e1c29..d763d6b1 100644 --- a/lib/capybara/node/finders.rb +++ b/lib/capybara/node/finders.rb @@ -146,7 +146,7 @@ module Capybara def resolve_query(query, exact=nil) elements = synchronize do # base.find(query.xpath(exact)).map do |node| - if query.selector.preferred_format==:css + if query.selector.format==:css base.find_css(query.css) else base.find_xpath(query.xpath(exact)) diff --git a/lib/capybara/node/simple.rb b/lib/capybara/node/simple.rb index 070d200f..3bfec606 100644 --- a/lib/capybara/node/simple.rb +++ b/lib/capybara/node/simple.rb @@ -154,7 +154,7 @@ module Capybara private def resolve_query(query, exact=nil) - elements = if query.selector.preferred_format == :css + elements = if query.selector.format == :css native.css(query.css) else native.xpath(query.xpath(exact)) diff --git a/lib/capybara/selector.rb b/lib/capybara/selector.rb index 159e1fec..03d3987b 100644 --- a/lib/capybara/selector.rb +++ b/lib/capybara/selector.rb @@ -1,6 +1,6 @@ module Capybara class Selector - attr_reader :name, :custom_filters, :preferred_format + attr_reader :name, :custom_filters, :format class << self @@ -23,20 +23,20 @@ module Capybara @match = nil @label = nil @failure_message = nil - @preferred_format = :xpath instance_eval(&block) end def xpath(&block) + @format = :xpath @xpath = block if block @xpath end # Same as xpath, but wrap in XPath.css(). def css(&block) - @preferred_format = :css - @xpath = block if block - @xpath + @format = :css + @css = block if block + @css end def match(&block) @@ -50,7 +50,11 @@ module Capybara end def call(locator) - @xpath.call(locator) + if @format==:css + @css.call(locator) + else + @xpath.call(locator) + end end def match?(locator) From 9cfac0418abe5c311b8282d51ef1ebb330e30df4 Mon Sep 17 00:00:00 2001 From: Thomas Walpole Date: Tue, 19 Feb 2013 09:39:22 -0800 Subject: [PATCH 9/9] tests dont need to be optional since native css support in driver is now expected --- lib/capybara/spec/session/find_spec.rb | 14 +++++--------- spec/dsl_spec.rb | 3 +-- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/lib/capybara/spec/session/find_spec.rb b/lib/capybara/spec/session/find_spec.rb index 54cc7228..6734563d 100644 --- a/lib/capybara/spec/session/find_spec.rb +++ b/lib/capybara/spec/session/find_spec.rb @@ -42,10 +42,8 @@ Capybara::SpecHelper.spec '#find' do @session.find(:css, "input[id='test_field']")[:value].should == 'monkey' end - context "with native css query", requires: [:native_css] do - it "should support pseudo selectors" do - @session.find(:css, 'input:disabled').value.should == 'This is disabled' - end + it "should support pseudo selectors" do + @session.find(:css, 'input:disabled').value.should == 'This is disabled' end end @@ -303,11 +301,9 @@ Capybara::SpecHelper.spec '#find' do end end - context "with native css query", requires: [:native_css] do - it "should find an element using the given css locator" do - @session.within(:xpath, "//div[@id='for_bar']") do - @session.find(:css, 'input:disabled').value.should == 'James' - end + it "should support pseudo selectors" do + @session.within(:xpath, "//div[@id='for_bar']") do + @session.find(:css, 'input:disabled').value.should == 'James' end end end diff --git a/spec/dsl_spec.rb b/spec/dsl_spec.rb index 50a6990e..7bb7a531 100644 --- a/spec/dsl_spec.rb +++ b/spec/dsl_spec.rb @@ -10,8 +10,7 @@ Capybara::SpecHelper.run_specs TestClass.new, "DSL", :skip => [ :screenshot, :frames, :windows, - :server, - :native_css + :server ] describe Capybara::DSL do