mirror of
https://github.com/teamcapybara/capybara.git
synced 2022-11-09 12:08:07 -05:00
Util function for applying matchers to strings
This commit is contained in:
parent
b4c228f799
commit
f2fb04f14a
5 changed files with 173 additions and 23 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
require 'capybara/util/string'
|
||||||
require 'rack/test'
|
require 'rack/test'
|
||||||
require 'rack/utils'
|
require 'rack/utils'
|
||||||
require 'mime/types'
|
require 'mime/types'
|
||||||
|
@ -11,28 +12,11 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def [](name)
|
def [](name)
|
||||||
attr_name = name.to_s
|
string_node[name]
|
||||||
case
|
|
||||||
when 'select' == tag_name && 'value' == attr_name
|
|
||||||
if native['multiple'] == 'multiple'
|
|
||||||
native.xpath(".//option[@selected='selected']").map { |option| option[:value] || option.content }
|
|
||||||
else
|
|
||||||
option = native.xpath(".//option[@selected='selected']").first || native.xpath(".//option").first
|
|
||||||
option[:value] || option.content if option
|
|
||||||
end
|
|
||||||
when 'input' == tag_name && 'checkbox' == type && 'checked' == attr_name
|
|
||||||
native[attr_name] == 'checked' ? true : false
|
|
||||||
else
|
|
||||||
native[attr_name]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def value
|
def value
|
||||||
if tag_name == 'textarea'
|
string_node.value
|
||||||
native.content
|
|
||||||
else
|
|
||||||
self[:value]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def set(value)
|
def set(value)
|
||||||
|
@ -82,7 +66,7 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def visible?
|
def visible?
|
||||||
native.xpath("./ancestor-or-self::*[contains(@style, 'display:none') or contains(@style, 'display: none')]").size == 0
|
string_node.visible?
|
||||||
end
|
end
|
||||||
|
|
||||||
def path
|
def path
|
||||||
|
@ -95,6 +79,10 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def string_node
|
||||||
|
@string_node ||= Capybara::StringNode.new(native)
|
||||||
|
end
|
||||||
|
|
||||||
# a reference to the select node if this is an option node
|
# a reference to the select node if this is an option node
|
||||||
def select_node
|
def select_node
|
||||||
find('./ancestor::select').first
|
find('./ancestor::select').first
|
||||||
|
|
|
@ -38,6 +38,10 @@ module Capybara
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
|
def wait?
|
||||||
|
driver.wait?
|
||||||
|
end
|
||||||
|
|
||||||
def driver
|
def driver
|
||||||
session.driver
|
session.driver
|
||||||
end
|
end
|
||||||
|
|
|
@ -114,7 +114,7 @@ module Capybara
|
||||||
options = if args.last.is_a?(Hash) then args.pop else {} end
|
options = if args.last.is_a?(Hash) then args.pop else {} end
|
||||||
|
|
||||||
results = Capybara::Selector.normalize(*args).map do |path|
|
results = Capybara::Selector.normalize(*args).map do |path|
|
||||||
base.find(path)
|
find_in_base(path)
|
||||||
end.flatten
|
end.flatten
|
||||||
|
|
||||||
if text = options[:text]
|
if text = options[:text]
|
||||||
|
@ -127,13 +127,21 @@ module Capybara
|
||||||
results = results.select { |node| node.visible? }
|
results = results.select { |node| node.visible? }
|
||||||
end
|
end
|
||||||
|
|
||||||
results.map { |n| Capybara::Element.new(session, n) }
|
convert_elements(results)
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
|
def find_in_base(xpath)
|
||||||
|
base.find(xpath)
|
||||||
|
end
|
||||||
|
|
||||||
|
def convert_elements(elements)
|
||||||
|
elements.map { |element| Capybara::Element.new(session, element) }
|
||||||
|
end
|
||||||
|
|
||||||
def wait_conditionally_until
|
def wait_conditionally_until
|
||||||
if driver.wait? then session.wait_until { yield } else yield end
|
if wait? then session.wait_until { yield } else yield end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
72
lib/capybara/util/string.rb
Normal file
72
lib/capybara/util/string.rb
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
module Capybara
|
||||||
|
def self.string(html)
|
||||||
|
StringNode.new(Nokogiri::HTML(html))
|
||||||
|
end
|
||||||
|
|
||||||
|
class StringNode
|
||||||
|
include Capybara::Node::Finders
|
||||||
|
include Capybara::Node::Matchers
|
||||||
|
|
||||||
|
attr_reader :native
|
||||||
|
|
||||||
|
def initialize(native)
|
||||||
|
@native = native
|
||||||
|
end
|
||||||
|
|
||||||
|
def text
|
||||||
|
native.text
|
||||||
|
end
|
||||||
|
|
||||||
|
def [](name)
|
||||||
|
attr_name = name.to_s
|
||||||
|
if attr_name == 'value'
|
||||||
|
value
|
||||||
|
elsif 'input' == tag_name and 'checkbox' == native[:type] and 'checked' == attr_name
|
||||||
|
native['checked'] == 'checked'
|
||||||
|
else
|
||||||
|
native[attr_name]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def tag_name
|
||||||
|
native.node_name
|
||||||
|
end
|
||||||
|
|
||||||
|
def path
|
||||||
|
native.path
|
||||||
|
end
|
||||||
|
|
||||||
|
def value
|
||||||
|
if tag_name == 'textarea'
|
||||||
|
native.content
|
||||||
|
elsif tag_name == 'select'
|
||||||
|
if native['multiple'] == 'multiple'
|
||||||
|
native.xpath(".//option[@selected='selected']").map { |option| option[:value] || option.content }
|
||||||
|
else
|
||||||
|
option = native.xpath(".//option[@selected='selected']").first || native.xpath(".//option").first
|
||||||
|
option[:value] || option.content if option
|
||||||
|
end
|
||||||
|
else
|
||||||
|
native[:value]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def visible?
|
||||||
|
native.xpath("./ancestor-or-self::*[contains(@style, 'display:none') or contains(@style, 'display: none')]").size == 0
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def find_in_base(xpath)
|
||||||
|
native.xpath(xpath).map { |node| StringNode.new(node) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def convert_elements(elements)
|
||||||
|
elements
|
||||||
|
end
|
||||||
|
|
||||||
|
def wait?
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
78
spec/util/string_spec.rb
Normal file
78
spec/util/string_spec.rb
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
require 'capybara/util/string'
|
||||||
|
|
||||||
|
describe Capybara do
|
||||||
|
describe '.string' do
|
||||||
|
let :string do
|
||||||
|
Capybara.string <<-STRING
|
||||||
|
<div id="page">
|
||||||
|
<div id="content">
|
||||||
|
<h1 data="fantastic">Awesome</h1>
|
||||||
|
<p>Yes it is</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="footer" style="display: none">
|
||||||
|
<p>c2010</p>
|
||||||
|
<p>Jonas Nicklas</p>
|
||||||
|
<input type="text" name="foo" value="bar"/>
|
||||||
|
<select name="animal">
|
||||||
|
<option>Monkey</option>
|
||||||
|
<option selected="selected">Capybara</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
STRING
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows using matchers" do
|
||||||
|
string.should have_css('#page')
|
||||||
|
string.should_not have_css('#does-not-exist')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows using custom matchers" do
|
||||||
|
Capybara.add_selector :lifeform do
|
||||||
|
xpath { |name| "//option[contains(.,'#{name}')]" }
|
||||||
|
end
|
||||||
|
string.should have_selector(:page)
|
||||||
|
string.should_not have_selector(:'does-not-exist')
|
||||||
|
string.should have_selector(:lifeform, "Monkey")
|
||||||
|
string.should_not have_selector(:lifeform, "Gorilla")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows using matchers with text option" do
|
||||||
|
string.should have_css('h1', :text => 'Awesome')
|
||||||
|
string.should_not have_css('h1', :text => 'Not so awesome')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows finding only visible nodes" do
|
||||||
|
string.all('//p', :text => 'c2010', :visible => true).should be_empty
|
||||||
|
string.all('//p', :text => 'c2010', :visible => false).should have(1).element
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows finding elements and extracting text from them" do
|
||||||
|
string.find('//h1').text.should == 'Awesome'
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows finding elements and extracting attributes from them" do
|
||||||
|
string.find('//h1')[:data].should == 'fantastic'
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows finding elements and extracting the tag name from them" do
|
||||||
|
string.find('//h1').tag_name.should == 'h1'
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows finding elements and extracting the path" do
|
||||||
|
string.find('//h1').path.should == '/html/body/div/div[1]/h1'
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows finding elements and extracting the path" do
|
||||||
|
string.find('//input').value.should == 'bar'
|
||||||
|
string.find('//select').value.should == 'Capybara'
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows finding elements and checking if they are visible" do
|
||||||
|
string.find('//h1').should be_visible
|
||||||
|
string.find('//input').should_not be_visible
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Add table
Reference in a new issue