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

Merge branch 'css' of git://github.com/twalpole/capybara into twalpole-css

Conflicts:
	lib/capybara/query.rb
This commit is contained in:
Jonas Nicklas 2013-02-19 19:56:49 +01:00
commit 2380ba854c
17 changed files with 102 additions and 35 deletions

View file

@ -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

View file

@ -7,7 +7,11 @@ class Capybara::Driver::Base
raise NotImplementedError
end
def find(query)
def find_xpath(query)
raise NotImplementedError
end
def find_css(query)
raise NotImplementedError
end

View file

@ -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.format==:css
base.find_css(query.css)
else
base.find_xpath(query.xpath(exact))
end.map do |node|
Capybara::Node::Element.new(session, node, self, query)
end
end

View file

@ -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.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)

View file

@ -1,6 +1,6 @@
module Capybara
class Query
attr_accessor :selector, :locator, :options, :xpath, :find, :negative
attr_accessor :selector, :locator, :options, :expression, :find, :negative
VALID_KEYS = [:text, :visible, :between, :count, :maximum, :minimum, :exact, :match]
@ -21,7 +21,7 @@ module Capybara
@options[:exact] = true
end
@xpath = @selector.call(@locator)
@expression = @selector.call(@locator)
assert_valid_keys!
end
@ -90,14 +90,17 @@ module Capybara
def xpath(exact=nil)
exact = self.exact? if exact == nil
if @xpath.respond_to?(:to_xpath) and exact
@xpath.to_xpath(:exact)
if @expression.respond_to?(:to_xpath) and exact
@expression.to_xpath(:exact)
else
@xpath.to_s
@expression.to_s
end
end
def css
@expression
end
private
def assert_valid_keys!

View file

@ -80,8 +80,12 @@ 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(format, selector)
if format==:css
dom.css(selector, Capybara::RackTest::CSSHandlers.new)
else
dom.xpath(selector)
end.map { |node| Capybara::RackTest::Node.new(self, node) }
end
def html

View file

@ -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

View file

@ -62,8 +62,12 @@ class Capybara::RackTest::Driver < Capybara::Driver::Base
response.status
end
def find(selector)
browser.find(selector)
def find_xpath(selector)
browser.find(:xpath, selector)
end
def find_css(selector)
browser.find(:css,selector)
end
def html

View file

@ -33,7 +33,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
@ -80,10 +80,14 @@ class Capybara::RackTest::Node < Capybara::Driver::Node
native.path
end
def find(locator)
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 +116,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

View file

@ -1,6 +1,6 @@
module Capybara
class Selector
attr_reader :name, :custom_filters
attr_reader :name, :custom_filters, :format
class << self
@ -27,16 +27,16 @@ module Capybara
end
def xpath(&block)
@format = :xpath
@xpath = block if block
@xpath
end
# Same as xpath, but wrap in XPath.css().
def css(&block)
if block
@xpath = xpath { |*args| XPath.css(block.call(*args)) }
end
@xpath
@format = :css
@css = block if block
@css
end
def match(&block)
@ -50,8 +50,12 @@ module Capybara
end
def call(locator)
if @format==:css
@css.call(locator)
else
@xpath.call(locator)
end
end
def match?(locator)
@match and @match.call(locator)

View file

@ -46,10 +46,14 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
browser.current_url
end
def find(selector)
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
def needs_server?; true; end
@ -127,4 +131,5 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
def invalid_element_errors
[Selenium::WebDriver::Error::StaleElementReferenceError, Selenium::WebDriver::Error::UnhandledError, Selenium::WebDriver::Error::ElementNotVisibleError]
end
end

View file

@ -81,10 +81,14 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
alias :checked? :selected?
def find(locator)
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
@ -93,6 +97,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

View file

@ -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
@ -296,5 +300,11 @@ Capybara::SpecHelper.spec '#find' do
@session.find('.//li[1]').text.should =~ /With Simple HTML/
end
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
end

View file

@ -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')

View file

@ -93,3 +93,5 @@ banana</textarea>
<div class="almost_singular but_not_quite">almost singular but not quite</div>
<div class="almost_singular">almost singular</div>
</div>
<input type="text" disabled name="disabled_text" value="This is disabled"/>

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

@ -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