mirror of
https://github.com/teamcapybara/capybara.git
synced 2022-11-09 12:08:07 -05:00
add match_xxx methods and matchers to check whether an element matches css, xpath, selector
This commit is contained in:
parent
f44f1e45aa
commit
8715327c43
15 changed files with 435 additions and 141 deletions
|
@ -419,10 +419,12 @@ module Capybara
|
|||
require 'capybara/version'
|
||||
|
||||
require 'capybara/queries/base_query'
|
||||
require 'capybara/query'
|
||||
require 'capybara/queries/selector_query'
|
||||
require 'capybara/queries/text_query'
|
||||
require 'capybara/queries/title_query'
|
||||
require 'capybara/queries/current_path_query'
|
||||
require 'capybara/queries/match_query'
|
||||
require 'capybara/query'
|
||||
|
||||
require 'capybara/node/finders'
|
||||
require 'capybara/node/matchers'
|
||||
|
|
|
@ -29,7 +29,7 @@ module Capybara
|
|||
# @raise [Capybara::ElementNotFound] If the element can't be found before time expires
|
||||
#
|
||||
def find(*args)
|
||||
query = Capybara::Query.new(*args)
|
||||
query = Capybara::Queries::SelectorQuery.new(*args)
|
||||
synchronize(query.wait) do
|
||||
if query.match == :smart or query.match == :prefer_exact
|
||||
result = query.resolve_for(self, true)
|
||||
|
@ -178,7 +178,7 @@ module Capybara
|
|||
# @return [Capybara::Result] A collection of found elements
|
||||
#
|
||||
def all(*args)
|
||||
query = Capybara::Query.new(*args)
|
||||
query = Capybara::Queries::SelectorQuery.new(*args)
|
||||
synchronize(query.wait) do
|
||||
result = query.resolve_for(self)
|
||||
raise Capybara::ExpectationNotMet, result.failure_message unless result.matches_count?
|
||||
|
|
|
@ -56,6 +56,36 @@ module Capybara
|
|||
return false
|
||||
end
|
||||
|
||||
##
|
||||
#
|
||||
# Checks if the current node matches given selector
|
||||
# Usage is identical to Capybara::Node::Matchers#has_selector?
|
||||
#
|
||||
# @param (see Capybara::Node::Finders#has_selector?)
|
||||
# @return [Boolean]
|
||||
#
|
||||
def match_selector?(*args)
|
||||
assert_match_selector(*args)
|
||||
rescue Capybara::ExpectationNotMet
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
##
|
||||
#
|
||||
# Checks if the current node does not match given selector
|
||||
# Usage is identical to Capybara::Node::Matchers#has_selector?
|
||||
#
|
||||
# @param (see Capybara::Node::Finders#has_selector?)
|
||||
# @return [Boolean]
|
||||
#
|
||||
def not_match_selector?(*args)
|
||||
assert_not_match_selector(*args)
|
||||
rescue Capybara::ExpectationNotMet
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
##
|
||||
#
|
||||
# Asserts that a given selector is on the page or current node.
|
||||
|
@ -90,7 +120,7 @@ module Capybara
|
|||
# @raise [Capybara::ExpectationNotMet] If the selector does not exist
|
||||
#
|
||||
def assert_selector(*args)
|
||||
query = Capybara::Query.new(*args)
|
||||
query = Capybara::Queries::SelectorQuery.new(*args)
|
||||
synchronize(query.wait) do
|
||||
result = query.resolve_for(self)
|
||||
matches_count = Capybara::Helpers.matches_count?(result.size, query.options)
|
||||
|
@ -118,7 +148,7 @@ module Capybara
|
|||
# @raise [Capybara::ExpectationNotMet] If the selector exists
|
||||
#
|
||||
def assert_no_selector(*args)
|
||||
query = Capybara::Query.new(*args)
|
||||
query = Capybara::Queries::SelectorQuery.new(*args)
|
||||
synchronize(query.wait) do
|
||||
result = query.resolve_for(self)
|
||||
matches_count = Capybara::Helpers.matches_count?(result.size, query.options)
|
||||
|
@ -130,6 +160,45 @@ module Capybara
|
|||
end
|
||||
alias_method :refute_selector, :assert_no_selector
|
||||
|
||||
##
|
||||
#
|
||||
# Asserts that the current_node matches a given selector
|
||||
#
|
||||
# node.assert_match_selector('p#foo')
|
||||
# node.assert_match_selector(:xpath, '//p[@id="foo"]')
|
||||
# node.assert_match_selector(:foo)
|
||||
#
|
||||
# It also accepts all options that {Capybara::Node::Finders#all} accepts,
|
||||
# such as :text and :visible.
|
||||
#
|
||||
# node.assert_match_selector('li', :text => 'Horse', :visible => true)
|
||||
#
|
||||
# @param (see Capybara::Node::Finders#all)
|
||||
# @raise [Capybara::ExpectationNotMet] If the selector does not match
|
||||
#
|
||||
def assert_match_selector(*args)
|
||||
query = Capybara::Queries::MatchQuery.new(*args)
|
||||
synchronize(query.wait) do
|
||||
result = query.resolve_for(self.parent)
|
||||
unless result.include? self
|
||||
raise Capybara::ExpectationNotMet, "Item does not match the provided selector"
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
def assert_not_match_selector(*args)
|
||||
query = Capybara::Queries::MatchQuery.new(*args)
|
||||
synchronize(query.wait) do
|
||||
result = query.resolve_for(self.parent)
|
||||
if result.include? self
|
||||
raise Capybara::ExpectationNotMet, 'Item matched the provided selector'
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
alias_method :refute_match_selector, :assert_not_match_selector
|
||||
|
||||
##
|
||||
#
|
||||
# Checks if a given XPath expression is on the page or current node.
|
||||
|
|
21
lib/capybara/queries/match_query.rb
Normal file
21
lib/capybara/queries/match_query.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
module Capybara
|
||||
module Queries
|
||||
class MatchQuery < Capybara::Queries::SelectorQuery
|
||||
VALID_KEYS = [:text, :visible, :exact, :wait]
|
||||
|
||||
def visible
|
||||
if options.has_key?(:visible)
|
||||
super
|
||||
else
|
||||
:all
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def valid_keys
|
||||
[:text, :visible, :exact, :wait] + @selector.custom_filters.keys
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
136
lib/capybara/queries/selector_query.rb
Normal file
136
lib/capybara/queries/selector_query.rb
Normal file
|
@ -0,0 +1,136 @@
|
|||
# frozen_string_literal: true
|
||||
module Capybara
|
||||
module Queries
|
||||
class SelectorQuery < Queries::BaseQuery
|
||||
attr_accessor :selector, :locator, :options, :expression, :find, :negative
|
||||
|
||||
VALID_KEYS = [:text, :visible, :between, :count, :maximum, :minimum, :exact, :match, :wait]
|
||||
VALID_MATCH = [:first, :smart, :prefer_exact, :one]
|
||||
|
||||
def initialize(*args)
|
||||
@options = if args.last.is_a?(Hash) then args.pop.dup else {} end
|
||||
|
||||
if args[0].is_a?(Symbol)
|
||||
@selector = Selector.all[args[0]]
|
||||
@locator = args[1]
|
||||
else
|
||||
@selector = Selector.all.values.find { |s| s.match?(args[0]) }
|
||||
@locator = args[0]
|
||||
end
|
||||
@selector ||= Selector.all[Capybara.default_selector]
|
||||
|
||||
# for compatibility with Capybara 2.0
|
||||
if Capybara.exact_options and @selector == Selector.all[:option]
|
||||
@options[:exact] = true
|
||||
end
|
||||
|
||||
@expression = @selector.call(@locator)
|
||||
assert_valid_keys
|
||||
end
|
||||
|
||||
def name; selector.name; end
|
||||
def label; selector.label or selector.name; end
|
||||
|
||||
def description
|
||||
@description = String.new("#{label} #{locator.inspect}")
|
||||
@description << " with text #{options[:text].inspect}" if options[:text]
|
||||
@description << selector.description(options)
|
||||
@description
|
||||
end
|
||||
|
||||
def matches_filters?(node)
|
||||
if options[:text]
|
||||
regexp = options[:text].is_a?(Regexp) ? options[:text] : Regexp.escape(options[:text].to_s)
|
||||
return false if not node.text(visible).match(regexp)
|
||||
end
|
||||
case visible
|
||||
when :visible then return false unless node.visible?
|
||||
when :hidden then return false if node.visible?
|
||||
end
|
||||
selector.custom_filters.each do |name, filter|
|
||||
if options.has_key?(name)
|
||||
return false unless filter.matches?(node, options[name])
|
||||
elsif filter.default?
|
||||
return false unless filter.matches?(node, filter.default)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def visible
|
||||
if options.has_key?(:visible)
|
||||
case @options[:visible]
|
||||
when true then :visible
|
||||
when false then :all
|
||||
else @options[:visible]
|
||||
end
|
||||
else
|
||||
if Capybara.ignore_hidden_elements
|
||||
:visible
|
||||
else
|
||||
:all
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def exact?
|
||||
if options.has_key?(:exact)
|
||||
@options[:exact]
|
||||
else
|
||||
Capybara.exact
|
||||
end
|
||||
end
|
||||
|
||||
def match
|
||||
if options.has_key?(:match)
|
||||
@options[:match]
|
||||
else
|
||||
Capybara.match
|
||||
end
|
||||
end
|
||||
|
||||
def xpath(exact=nil)
|
||||
exact = self.exact? if exact == nil
|
||||
if @expression.respond_to?(:to_xpath) and exact
|
||||
@expression.to_xpath(:exact)
|
||||
else
|
||||
@expression.to_s
|
||||
end
|
||||
end
|
||||
|
||||
def css
|
||||
@expression
|
||||
end
|
||||
|
||||
# @api private
|
||||
def resolve_for(node, exact = nil)
|
||||
node.synchronize do
|
||||
children = if selector.format == :css
|
||||
node.find_css(self.css)
|
||||
else
|
||||
node.find_xpath(self.xpath(exact))
|
||||
end.map do |child|
|
||||
if node.is_a?(Capybara::Node::Base)
|
||||
Capybara::Node::Element.new(node.session, child, node, self)
|
||||
else
|
||||
Capybara::Node::Simple.new(child)
|
||||
end
|
||||
end
|
||||
Capybara::Result.new(children, self)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def valid_keys
|
||||
COUNT_KEYS + [:text, :visible, :exact, :match, :wait] + @selector.custom_filters.keys
|
||||
end
|
||||
|
||||
def assert_valid_keys
|
||||
super
|
||||
unless VALID_MATCH.include?(match)
|
||||
raise ArgumentError, "invalid option #{match.inspect} for :match, should be one of #{VALID_MATCH.map(&:inspect).join(", ")}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,136 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
require 'capybara/queries/selector_query'
|
||||
module Capybara
|
||||
# @deprecated This class and its methods are not supposed to be used by users of Capybara's public API.
|
||||
# It may be removed in future versions of Capybara.
|
||||
class Query < Queries::BaseQuery
|
||||
attr_accessor :selector, :locator, :options, :expression, :find, :negative
|
||||
|
||||
VALID_KEYS = [:text, :visible, :between, :count, :maximum, :minimum, :exact, :match, :wait]
|
||||
VALID_MATCH = [:first, :smart, :prefer_exact, :one]
|
||||
|
||||
def initialize(*args)
|
||||
@options = if args.last.is_a?(Hash) then args.pop.dup else {} end
|
||||
|
||||
if args[0].is_a?(Symbol)
|
||||
@selector = Selector.all[args[0]]
|
||||
@locator = args[1]
|
||||
else
|
||||
@selector = Selector.all.values.find { |s| s.match?(args[0]) }
|
||||
@locator = args[0]
|
||||
end
|
||||
@selector ||= Selector.all[Capybara.default_selector]
|
||||
|
||||
# for compatibility with Capybara 2.0
|
||||
if Capybara.exact_options and @selector == Selector.all[:option]
|
||||
@options[:exact] = true
|
||||
end
|
||||
|
||||
@expression = @selector.call(@locator)
|
||||
assert_valid_keys
|
||||
end
|
||||
|
||||
def name; selector.name; end
|
||||
def label; selector.label or selector.name; end
|
||||
|
||||
def description
|
||||
@description = String.new("#{label} #{locator.inspect}")
|
||||
@description << " with text #{options[:text].inspect}" if options[:text]
|
||||
@description << selector.description(options)
|
||||
@description
|
||||
end
|
||||
|
||||
def matches_filters?(node)
|
||||
if options[:text]
|
||||
regexp = options[:text].is_a?(Regexp) ? options[:text] : Regexp.escape(options[:text].to_s)
|
||||
return false if not node.text(visible).match(regexp)
|
||||
end
|
||||
case visible
|
||||
when :visible then return false unless node.visible?
|
||||
when :hidden then return false if node.visible?
|
||||
end
|
||||
selector.custom_filters.each do |name, filter|
|
||||
if options.has_key?(name)
|
||||
return false unless filter.matches?(node, options[name])
|
||||
elsif filter.default?
|
||||
return false unless filter.matches?(node, filter.default)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def visible
|
||||
if options.has_key?(:visible)
|
||||
case @options[:visible]
|
||||
when true then :visible
|
||||
when false then :all
|
||||
else @options[:visible]
|
||||
end
|
||||
else
|
||||
if Capybara.ignore_hidden_elements
|
||||
:visible
|
||||
else
|
||||
:all
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def exact?
|
||||
if options.has_key?(:exact)
|
||||
@options[:exact]
|
||||
else
|
||||
Capybara.exact
|
||||
end
|
||||
end
|
||||
|
||||
def match
|
||||
if options.has_key?(:match)
|
||||
@options[:match]
|
||||
else
|
||||
Capybara.match
|
||||
end
|
||||
end
|
||||
|
||||
def xpath(exact=nil)
|
||||
exact = self.exact? if exact == nil
|
||||
if @expression.respond_to?(:to_xpath) and exact
|
||||
@expression.to_xpath(:exact)
|
||||
else
|
||||
@expression.to_s
|
||||
end
|
||||
end
|
||||
|
||||
def css
|
||||
@expression
|
||||
end
|
||||
|
||||
# @api private
|
||||
def resolve_for(node, exact = nil)
|
||||
node.synchronize do
|
||||
children = if selector.format == :css
|
||||
node.find_css(self.css)
|
||||
else
|
||||
node.find_xpath(self.xpath(exact))
|
||||
end.map do |child|
|
||||
if node.is_a?(Capybara::Node::Base)
|
||||
Capybara::Node::Element.new(node.session, child, node, self)
|
||||
else
|
||||
Capybara::Node::Simple.new(child)
|
||||
end
|
||||
end
|
||||
Capybara::Result.new(children, self)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def valid_keys
|
||||
COUNT_KEYS + [:text, :visible, :exact, :match, :wait] + @selector.custom_filters.keys
|
||||
end
|
||||
|
||||
def assert_valid_keys
|
||||
super
|
||||
unless VALID_MATCH.include?(match)
|
||||
raise ArgumentError, "invalid option #{match.inspect} for :match, should be one of #{VALID_MATCH.map(&:inspect).join(", ")}"
|
||||
end
|
||||
end
|
||||
end
|
||||
Query = Queries::SelectorQuery
|
||||
end
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
module Capybara
|
||||
module RSpecMatchers
|
||||
class Matcher
|
||||
include ::RSpec::Matchers::Composable if defined?(::RSpec::Expectations::Version) && RSpec::Expectations::Version::STRING.to_f >= 3.0
|
||||
include ::RSpec::Matchers::Composable if defined?(::RSpec::Expectations::Version) && (Gem::Version.new(RSpec::Expectations::Version::STRING) >= Gem::Version.new('3.0'))
|
||||
|
||||
def wrap(actual)
|
||||
if actual.respond_to?("has_selector?")
|
||||
|
@ -39,7 +39,7 @@ module Capybara
|
|||
end
|
||||
|
||||
def query
|
||||
@query ||= Capybara::Query.new(*@args)
|
||||
@query ||= Capybara::Queries::SelectorQuery.new(*@args)
|
||||
end
|
||||
|
||||
# RSpec 2 compatibility:
|
||||
|
@ -161,7 +161,7 @@ module Capybara
|
|||
|
||||
class BecomeClosed
|
||||
def initialize(options)
|
||||
@wait_time = Capybara::Query.new(options).wait
|
||||
@wait_time = Capybara::Queries::SelectorQuery.new(options).wait
|
||||
end
|
||||
|
||||
def matches?(window)
|
||||
|
@ -187,18 +187,68 @@ module Capybara
|
|||
alias_method :failure_message_for_should_not, :failure_message_when_negated
|
||||
end
|
||||
|
||||
class MatchSelector < Matcher
|
||||
attr_reader :failure_message, :failure_message_when_negated
|
||||
|
||||
def initialize(*args)
|
||||
@args = args
|
||||
end
|
||||
|
||||
def matches?(actual)
|
||||
actual.assert_match_selector(*@args)
|
||||
rescue Capybara::ExpectationNotMet => e
|
||||
@failure_message = e.message
|
||||
return false
|
||||
end
|
||||
|
||||
def does_not_match?(actual)
|
||||
actual.assert_not_match_selector(*@args)
|
||||
rescue Capybara::ExpectationNotMet => e
|
||||
@failure_message_when_negated = e.message
|
||||
return false
|
||||
end
|
||||
|
||||
def description
|
||||
"match #{query.description}"
|
||||
end
|
||||
|
||||
def query
|
||||
@query ||= Capybara::Queries::MatchQuery.new(*@args)
|
||||
end
|
||||
|
||||
# RSpec 2 compatibility:
|
||||
alias_method :failure_message_for_should, :failure_message
|
||||
alias_method :failure_message_for_should_not, :failure_message_when_negated
|
||||
end
|
||||
|
||||
def have_selector(*args)
|
||||
HaveSelector.new(*args)
|
||||
end
|
||||
|
||||
def match_selector(*args)
|
||||
MatchSelector.new(*args)
|
||||
end
|
||||
# defined_negated_matcher was added in RSpec 3.1 - it's syntactic sugar only since a user can do
|
||||
# expect(page).not_to match_selector, so not sure we really need to support not_match_selector for prior to RSpec 3.1
|
||||
::RSpec::Matchers.define_negated_matcher :not_match_selector, :match_selector if defined?(::RSpec::Expectations::Version) && (Gem::Version.new(RSpec::Expectations::Version::STRING) >= Gem::Version.new('3.1'))
|
||||
|
||||
|
||||
def have_xpath(xpath, options={})
|
||||
HaveSelector.new(:xpath, xpath, options)
|
||||
end
|
||||
|
||||
def match_xpath(xpath, options={})
|
||||
MatchSelector.new(:xpath, xpath, options)
|
||||
end
|
||||
|
||||
def have_css(css, options={})
|
||||
HaveSelector.new(:css, css, options)
|
||||
end
|
||||
|
||||
def match_css(css, options={})
|
||||
MatchSelector.new(:css, css, options)
|
||||
end
|
||||
|
||||
def have_text(*args)
|
||||
HaveText.new(*args)
|
||||
end
|
||||
|
|
|
@ -404,7 +404,7 @@ module Capybara
|
|||
driver.switch_to_window(window.handle)
|
||||
window
|
||||
else
|
||||
wait_time = Capybara::Query.new(options).wait
|
||||
wait_time = Capybara::Queries::SelectorQuery.new(options).wait
|
||||
document.synchronize(wait_time, errors: [Capybara::WindowError]) do
|
||||
original_window_handle = driver.current_window_handle
|
||||
begin
|
||||
|
@ -501,7 +501,7 @@ module Capybara
|
|||
old_handles = driver.window_handles
|
||||
block.call
|
||||
|
||||
wait_time = Capybara::Query.new(options).wait
|
||||
wait_time = Capybara::Queries::SelectorQuery.new(options).wait
|
||||
document.synchronize(wait_time, errors: [Capybara::WindowError]) do
|
||||
opened_handles = (driver.window_handles - old_handles)
|
||||
if opened_handles.size != 1
|
||||
|
|
|
@ -117,4 +117,10 @@ $(function() {
|
|||
$('#with-key-events').keydown(function(e){
|
||||
$('#key-events-output').append('keydown:'+e.which+' ')
|
||||
});
|
||||
$('#disable-on-click').click(function(e){
|
||||
var input = this
|
||||
setTimeout(function() {
|
||||
input.disabled = true;
|
||||
}, 500)
|
||||
})
|
||||
});
|
||||
|
|
31
lib/capybara/spec/session/element/assert_match_selector.rb
Normal file
31
lib/capybara/spec/session/element/assert_match_selector.rb
Normal file
|
@ -0,0 +1,31 @@
|
|||
Capybara::SpecHelper.spec '#assert_match_selector' do
|
||||
before do
|
||||
@session.visit('/with_html')
|
||||
@element = @session.find(:css, 'span', text: '42')
|
||||
end
|
||||
|
||||
it "should be true if the given selector matches the element" do
|
||||
expect(@element.assert_match_selector(:css, '.number')).to be true
|
||||
end
|
||||
|
||||
it "should be false if the given selector does not match the element" do
|
||||
expect { @element.assert_match_selector(:css, '.not_number') }.to raise_error(Capybara::ElementNotFound)
|
||||
end
|
||||
|
||||
it "should not be callable on the session" do
|
||||
expect { @session.assert_match_selector(:css, '.number') }.to raise_error(NoMethodError)
|
||||
end
|
||||
|
||||
it "should wait for match to occur", requires: [:js] do
|
||||
@session.visit('/with_js')
|
||||
input = @session.find(:css, '#disable-on-click')
|
||||
|
||||
expect(input.assert_match_selector(:css, 'input:enabled')).to be true
|
||||
input.click
|
||||
expect(input.assert_match_selector(:css, 'input:disabled')).to be true
|
||||
end
|
||||
|
||||
it "should not accept count options" do
|
||||
expect { @element.assert_match_selector(:css, '.number', count: 1) }.to raise_error(ArgumentError)
|
||||
end
|
||||
end
|
17
lib/capybara/spec/session/element/match_css_spec.rb
Normal file
17
lib/capybara/spec/session/element/match_css_spec.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
Capybara::SpecHelper.spec '#match_css?' do
|
||||
before do
|
||||
@session.visit('/with_html')
|
||||
@element = @session.find(:css, 'span', text: '42')
|
||||
end
|
||||
|
||||
it "should be true if the given selector matches the element" do
|
||||
expect(@element).to match_css("span")
|
||||
expect(@element).to match_css("span.number")
|
||||
end
|
||||
|
||||
it "should be false if the given selector does not match" do
|
||||
expect(@element).not_to match_css("div")
|
||||
expect(@element).not_to match_css("p a#doesnotexist")
|
||||
expect(@element).not_to match_css("p.nosuchclass")
|
||||
end
|
||||
end
|
23
lib/capybara/spec/session/element/match_xpath_spec.rb
Normal file
23
lib/capybara/spec/session/element/match_xpath_spec.rb
Normal file
|
@ -0,0 +1,23 @@
|
|||
Capybara::SpecHelper.spec '#match_xpath?' do
|
||||
before do
|
||||
@session.visit('/with_html')
|
||||
@element = @session.find(:css, 'span.number')
|
||||
end
|
||||
|
||||
it "should be true if the given selector is on the page" do
|
||||
expect(@element).to match_xpath("//span")
|
||||
expect(@element).to match_xpath("//span[@class='number']")
|
||||
end
|
||||
|
||||
it "should be false if the given selector is not on the page" do
|
||||
expect(@element).not_to match_xpath("//abbr")
|
||||
expect(@element).not_to match_xpath("//div")
|
||||
expect(@element).not_to match_xpath("//span[@class='not_a_number']")
|
||||
end
|
||||
|
||||
it "should use xpath even if default selector is CSS" do
|
||||
Capybara.default_selector = :css
|
||||
expect(@element).not_to have_xpath("//span[@class='not_a_number']")
|
||||
expect(@element).not_to have_xpath("//div[@class='number']")
|
||||
end
|
||||
end
|
63
lib/capybara/spec/session/element/matches_selector_spec.rb
Normal file
63
lib/capybara/spec/session/element/matches_selector_spec.rb
Normal file
|
@ -0,0 +1,63 @@
|
|||
Capybara::SpecHelper.spec '#match_xpath?' do
|
||||
before do
|
||||
@session.visit('/with_html')
|
||||
@element = @session.find('//span', text: '42')
|
||||
end
|
||||
|
||||
it "should be true if the element matches the given selector" do
|
||||
expect(@element).to match_selector(:xpath, "//span")
|
||||
expect(@element).to match_selector(:css, 'span.number')
|
||||
expect(@element.match_selector?(:css, 'span.number')).to be true
|
||||
end
|
||||
|
||||
it "should be false if the element does not match the given selector" do
|
||||
expect(@element).not_to match_selector(:xpath, "//div")
|
||||
expect(@element).not_to match_selector(:css, "span.not_a_number")
|
||||
expect(@element.match_selector?(:css, "span.not_a_number")).to be false
|
||||
end
|
||||
|
||||
it "should use default selector" do
|
||||
Capybara.default_selector = :css
|
||||
expect(@element).not_to match_selector("span.not_a_number")
|
||||
expect(@element).to match_selector("span.number")
|
||||
end
|
||||
|
||||
context "with text" do
|
||||
it "should discard all matches where the given string is not contained" do
|
||||
expect(@element).to match_selector("//span", :text => "42")
|
||||
expect(@element).not_to match_selector("//span", :text => "Doesnotexist")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Capybara::SpecHelper.spec '#not_match_selector?' do
|
||||
before do
|
||||
@session.visit('/with_html')
|
||||
@element = @session.find(:css, "span", text: 42)
|
||||
end
|
||||
|
||||
it "should be false if the given selector matches the element" do
|
||||
expect(@element).not_to not_match_selector(:xpath, "//span")
|
||||
expect(@element).not_to not_match_selector(:css, "span.number")
|
||||
expect(@element.not_match_selector?(:css, "span.number")).to be false
|
||||
end
|
||||
|
||||
it "should be true if the given selector does not match the element" do
|
||||
expect(@element).to not_match_selector(:xpath, "//abbr")
|
||||
expect(@element).to not_match_selector(:css, "p a#doesnotexist")
|
||||
expect(@element.not_match_selector?(:css, "p a#doesnotexist")).to be true
|
||||
end
|
||||
|
||||
it "should use default selector" do
|
||||
Capybara.default_selector = :css
|
||||
expect(@element).to not_match_selector("p a#doesnotexist")
|
||||
expect(@element).not_to not_match_selector("span.number")
|
||||
end
|
||||
|
||||
context "with text" do
|
||||
it "should discard all matches where the given string is contained" do
|
||||
expect(@element).not_to not_match_selector(:css, "span.number", :text => "42")
|
||||
expect(@element).to not_match_selector(:css, "span.number", :text => "Doesnotexist")
|
||||
end
|
||||
end
|
||||
end if Gem::Version.new(RSpec::Expectations::Version::STRING) >= Gem::Version.new('3.1')
|
|
@ -11,6 +11,7 @@
|
|||
<h2 class="head">Header Class Test Five</h2>
|
||||
|
||||
<span class="number">42</span>
|
||||
<span>Other span</span>
|
||||
|
||||
<p class="para" id="first">
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
||||
|
|
|
@ -94,6 +94,10 @@
|
|||
<a href="#" id="open-prompt">Open prompt</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<input id="disable-on-click"/>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a href="#" id="delayed-page-change">Change page</a>
|
||||
<a href="/with_html?options[]=things">Non-escaped query options</a>
|
||||
|
|
Loading…
Reference in a new issue