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/utils'
|
||||
require 'mime/types'
|
||||
|
@ -11,28 +12,11 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
|
|||
end
|
||||
|
||||
def [](name)
|
||||
attr_name = name.to_s
|
||||
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
|
||||
string_node[name]
|
||||
end
|
||||
|
||||
def value
|
||||
if tag_name == 'textarea'
|
||||
native.content
|
||||
else
|
||||
self[:value]
|
||||
end
|
||||
string_node.value
|
||||
end
|
||||
|
||||
def set(value)
|
||||
|
@ -82,7 +66,7 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
|
|||
end
|
||||
|
||||
def visible?
|
||||
native.xpath("./ancestor-or-self::*[contains(@style, 'display:none') or contains(@style, 'display: none')]").size == 0
|
||||
string_node.visible?
|
||||
end
|
||||
|
||||
def path
|
||||
|
@ -95,6 +79,10 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
|
|||
|
||||
private
|
||||
|
||||
def string_node
|
||||
@string_node ||= Capybara::StringNode.new(native)
|
||||
end
|
||||
|
||||
# a reference to the select node if this is an option node
|
||||
def select_node
|
||||
find('./ancestor::select').first
|
||||
|
|
|
@ -38,6 +38,10 @@ module Capybara
|
|||
|
||||
protected
|
||||
|
||||
def wait?
|
||||
driver.wait?
|
||||
end
|
||||
|
||||
def driver
|
||||
session.driver
|
||||
end
|
||||
|
|
|
@ -114,7 +114,7 @@ module Capybara
|
|||
options = if args.last.is_a?(Hash) then args.pop else {} end
|
||||
|
||||
results = Capybara::Selector.normalize(*args).map do |path|
|
||||
base.find(path)
|
||||
find_in_base(path)
|
||||
end.flatten
|
||||
|
||||
if text = options[:text]
|
||||
|
@ -127,13 +127,21 @@ module Capybara
|
|||
results = results.select { |node| node.visible? }
|
||||
end
|
||||
|
||||
results.map { |n| Capybara::Element.new(session, n) }
|
||||
convert_elements(results)
|
||||
end
|
||||
|
||||
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
|
||||
if driver.wait? then session.wait_until { yield } else yield end
|
||||
if wait? then session.wait_until { yield } else yield 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