Skip to content

Commit

Permalink
Merge branch 'css' of git://github.com/twalpole/capybara into twalpol…
Browse files Browse the repository at this point in the history
…e-css

Conflicts:
	lib/capybara/query.rb
  • Loading branch information
jnicklas committed Feb 19, 2013
2 parents aed8746 + 9cfac04 commit 2380ba8
Show file tree
Hide file tree
Showing 17 changed files with 102 additions and 35 deletions.
1 change: 1 addition & 0 deletions lib/capybara.rb
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ module RackTest
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
Expand Down
6 changes: 5 additions & 1 deletion lib/capybara/driver/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ def visit(path)
raise NotImplementedError
end

def find(query)
def find_xpath(query)
raise NotImplementedError
end

def find_css(query)
raise NotImplementedError
end

Expand Down
7 changes: 6 additions & 1 deletion lib/capybara/node/finders.rb
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,12 @@ def first(*args)

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
Expand Down
6 changes: 5 additions & 1 deletion lib/capybara/node/simple.rb
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,11 @@ def has_no_title?(content)
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)
Expand Down
15 changes: 9 additions & 6 deletions lib/capybara/query.rb
Original file line number Diff line number Diff line change
@@ -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]

Expand All @@ -21,7 +21,7 @@ def initialize(*args)
@options[:exact] = true
end

@xpath = @selector.call(@locator)
@expression = @selector.call(@locator)
assert_valid_keys!
end

Expand Down Expand Up @@ -90,14 +90,17 @@ def match

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!
Expand Down
10 changes: 7 additions & 3 deletions lib/capybara/rack_test/browser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,12 @@ def dom
@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
Expand All @@ -93,7 +97,7 @@ def html
def title
dom.xpath("//title").text
end

protected

def build_rack_mock_session
Expand Down
8 changes: 8 additions & 0 deletions lib/capybara/rack_test/css_handlers.rb
Original file line number Diff line number Diff line change
@@ -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
10 changes: 7 additions & 3 deletions lib/capybara/rack_test/driver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,14 @@ def status_code
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
browser.html
end
Expand Down
12 changes: 8 additions & 4 deletions lib/capybara/rack_test/node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def set(value)

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
Expand Down Expand Up @@ -80,10 +80,14 @@ def path
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
Expand Down Expand Up @@ -112,7 +116,7 @@ def string_node

# 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
Expand Down
16 changes: 10 additions & 6 deletions lib/capybara/selector.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module Capybara
class Selector
attr_reader :name, :custom_filters
attr_reader :name, :custom_filters, :format


class << self
Expand All @@ -27,16 +27,16 @@ def initialize(name, &block)
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)
Expand All @@ -50,7 +50,11 @@ def label(label=nil)
end

def call(locator)
@xpath.call(locator)
if @format==:css
@css.call(locator)
else
@xpath.call(locator)
end
end

def match?(locator)
Expand Down
9 changes: 7 additions & 2 deletions lib/capybara/selenium/driver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,14 @@ def current_url
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

Expand Down Expand Up @@ -127,4 +131,5 @@ def quit
def invalid_element_errors
[Selenium::WebDriver::Error::StaleElementReferenceError, Selenium::WebDriver::Error::UnhandledError, Selenium::WebDriver::Error::ElementNotVisibleError]
end

end
10 changes: 7 additions & 3 deletions lib/capybara/selenium/node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,14 @@ def disabled?

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
Expand All @@ -93,6 +97,6 @@ def ==(other)

# 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
10 changes: 10 additions & 0 deletions lib/capybara/spec/session/find_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@
@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
Expand Down Expand Up @@ -296,5 +300,11 @@
@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
6 changes: 3 additions & 3 deletions lib/capybara/spec/session/within_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

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')
Expand Down Expand Up @@ -46,7 +46,7 @@

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')
Expand All @@ -58,7 +58,7 @@
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')
Expand Down
2 changes: 2 additions & 0 deletions lib/capybara/spec/views/with_html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -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"/>
5 changes: 5 additions & 0 deletions lib/capybara/spec/views/with_scope.erb
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand All @@ -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>
Expand Down
4 changes: 2 additions & 2 deletions spec/rack_test_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,14 @@ module TestSessions
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

Expand Down

0 comments on commit 2380ba8

Please sign in to comment.