mirror of
https://github.com/teamcapybara/capybara.git
synced 2022-11-09 12:08:07 -05:00
Move expression builder methods to instance
This commit is contained in:
parent
cb89ff8b67
commit
d5caddda74
8 changed files with 188 additions and 188 deletions
|
@ -237,7 +237,7 @@ module Capybara
|
|||
conditions = {}
|
||||
conditions[:id] = options[:id] if use_default_id_filter?
|
||||
conditions[:class] = options[:class] if use_default_class_filter?
|
||||
builder.add_attribute_conditions(expr, conditions)
|
||||
builder(expr).add_attribute_conditions(conditions)
|
||||
end
|
||||
|
||||
def use_default_id_filter?
|
||||
|
@ -359,8 +359,8 @@ module Capybara
|
|||
@selector.default_visibility(session_options.ignore_hidden_elements, options)
|
||||
end
|
||||
|
||||
def builder
|
||||
selector.builder
|
||||
def builder(expr)
|
||||
selector.builder(expr)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -34,7 +34,7 @@ Capybara.add_selector(:css) do
|
|||
end
|
||||
|
||||
Capybara.add_selector(:id) do
|
||||
xpath { |id| builder.add_attribute_conditions(XPath.descendant, id: id) }
|
||||
xpath { |id| builder(XPath.descendant).add_attribute_conditions(id: id) }
|
||||
locator_filter { |node, id| id.is_a?(Regexp) ? node[:id] =~ id : true }
|
||||
end
|
||||
|
||||
|
@ -92,8 +92,7 @@ end
|
|||
|
||||
Capybara.add_selector(:link) do
|
||||
xpath do |locator, href: true, alt: nil, title: nil, **|
|
||||
xpath = XPath.descendant(:a)
|
||||
xpath = xpath[@href_conditions = builder.attribute_conditions(href: href)]
|
||||
xpath = builder(XPath.descendant(:a)).add_attribute_conditions(href: href)
|
||||
|
||||
unless locator.nil?
|
||||
locator = locator.to_s
|
||||
|
@ -119,25 +118,18 @@ Capybara.add_selector(:link) do
|
|||
end
|
||||
|
||||
expression_filter(:download, valid_values: [true, false, String]) do |expr, download|
|
||||
builder.add_attribute_conditions(expr, download: download)
|
||||
builder(expr).add_attribute_conditions(download: download)
|
||||
end
|
||||
|
||||
describe_expression_filters do |**options|
|
||||
desc = +''
|
||||
if (href = options[:href])
|
||||
if !href.is_a?(Regexp)
|
||||
desc << " with href #{href.inspect}"
|
||||
elsif @href_conditions
|
||||
desc << " with href matching #{href.inspect}"
|
||||
end
|
||||
desc << " with href #{'matching ' if href.is_a? Regexp}#{href.inspect}"
|
||||
elsif options.key?(:href) # is nil/false specified?
|
||||
desc << ' with no href attribute'
|
||||
end
|
||||
desc << ' with no href attribute' if options.fetch(:href, true).nil?
|
||||
desc
|
||||
end
|
||||
|
||||
describe_node_filters do |href: nil, **|
|
||||
" with href matching #{href.inspect}" if href.is_a?(Regexp) && @href_conditions.nil?
|
||||
end
|
||||
end
|
||||
|
||||
Capybara.add_selector(:button) do
|
||||
|
@ -489,7 +481,7 @@ Capybara.add_selector(:element) do
|
|||
end
|
||||
|
||||
expression_filter(:attributes, matcher: /.+/) do |xpath, name, val|
|
||||
builder.add_attribute_conditions(xpath, name => val)
|
||||
builder(xpath).add_attribute_conditions(name => val)
|
||||
end
|
||||
|
||||
node_filter(:attributes, matcher: /.+/) do |node, name, val|
|
||||
|
|
|
@ -6,69 +6,73 @@ module Capybara
|
|||
class Selector
|
||||
# @api private
|
||||
class CSSBuilder
|
||||
class << self
|
||||
def attribute_conditions(attributes)
|
||||
attributes.map do |attribute, value|
|
||||
case value
|
||||
when XPath::Expression
|
||||
raise ArgumentError, "XPath expressions are not supported for the :#{attribute} filter with CSS based selectors"
|
||||
when Regexp
|
||||
Selector::RegexpDisassembler.new(value).substrings.map do |str|
|
||||
"[#{attribute}*='#{str}'#{' i' if value.casefold?}]"
|
||||
end.join
|
||||
when true
|
||||
"[#{attribute}]"
|
||||
when false
|
||||
':not([attribute])'
|
||||
else
|
||||
if attribute == :id
|
||||
"##{::Capybara::Selector::CSS.escape(value)}"
|
||||
else
|
||||
"[#{attribute}='#{value}']"
|
||||
end
|
||||
end
|
||||
end.join
|
||||
end
|
||||
def initialize(expression)
|
||||
@expression = expression || ''
|
||||
end
|
||||
|
||||
def add_attribute_conditions(selector, **attributes)
|
||||
attributes.inject(selector) do |css, (name, value)|
|
||||
conditions = if name == :class
|
||||
class_conditions(value)
|
||||
elsif value.is_a? Regexp
|
||||
Selector::RegexpDisassembler.new(value).alternated_substrings.map do |strs|
|
||||
strs.map do |str|
|
||||
"[#{name}*='#{str}'#{' i' if value.casefold?}]"
|
||||
end.join
|
||||
end
|
||||
else
|
||||
[attribute_conditions(name => value)]
|
||||
end
|
||||
attr_reader :expression
|
||||
|
||||
::Capybara::Selector::CSS.split(css).map do |sel|
|
||||
next sel if conditions.empty?
|
||||
|
||||
conditions.map { |cond| sel + cond }.join(', ')
|
||||
end.join(', ')
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def class_conditions(classes)
|
||||
case classes
|
||||
when XPath::Expression
|
||||
raise ArgumentError, 'XPath expressions are not supported for the :class filter with CSS based selectors'
|
||||
when Regexp
|
||||
Selector::RegexpDisassembler.new(classes).alternated_substrings.map do |strs|
|
||||
def add_attribute_conditions(**attributes)
|
||||
@expression = attributes.inject(expression) do |css, (name, value)|
|
||||
conditions = if name == :class
|
||||
class_conditions(value)
|
||||
elsif value.is_a? Regexp
|
||||
Selector::RegexpDisassembler.new(value).alternated_substrings.map do |strs|
|
||||
strs.map do |str|
|
||||
"[class*='#{str}'#{' i' if classes.casefold?}]"
|
||||
"[#{name}*='#{str}'#{' i' if value.casefold?}]"
|
||||
end.join
|
||||
end
|
||||
else
|
||||
cls = Array(classes).group_by { |cl| cl.start_with?('!') && !cl.start_with?('!!!') }
|
||||
[(cls[false].to_a.map { |cl| ".#{Capybara::Selector::CSS.escape(cl.sub(/^!!/, ''))}" } +
|
||||
cls[true].to_a.map { |cl| ":not(.#{Capybara::Selector::CSS.escape(cl.slice(1..-1))})" }).join]
|
||||
[attribute_conditions(name => value)]
|
||||
end
|
||||
|
||||
::Capybara::Selector::CSS.split(css).map do |sel|
|
||||
next sel if conditions.empty?
|
||||
|
||||
conditions.map { |cond| sel + cond }.join(', ')
|
||||
end.join(', ')
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def attribute_conditions(attributes)
|
||||
attributes.map do |attribute, value|
|
||||
case value
|
||||
when XPath::Expression
|
||||
raise ArgumentError, "XPath expressions are not supported for the :#{attribute} filter with CSS based selectors"
|
||||
when Regexp
|
||||
Selector::RegexpDisassembler.new(value).substrings.map do |str|
|
||||
"[#{attribute}*='#{str}'#{' i' if value.casefold?}]"
|
||||
end.join
|
||||
when true
|
||||
"[#{attribute}]"
|
||||
when false
|
||||
':not([attribute])'
|
||||
else
|
||||
if attribute == :id
|
||||
"##{::Capybara::Selector::CSS.escape(value)}"
|
||||
else
|
||||
"[#{attribute}='#{value}']"
|
||||
end
|
||||
end
|
||||
end.join
|
||||
end
|
||||
|
||||
def class_conditions(classes)
|
||||
case classes
|
||||
when XPath::Expression
|
||||
raise ArgumentError, 'XPath expressions are not supported for the :class filter with CSS based selectors'
|
||||
when Regexp
|
||||
Selector::RegexpDisassembler.new(classes).alternated_substrings.map do |strs|
|
||||
strs.map do |str|
|
||||
"[class*='#{str}'#{' i' if classes.casefold?}]"
|
||||
end.join
|
||||
end
|
||||
else
|
||||
cls = Array(classes).group_by { |cl| cl.start_with?('!') && !cl.start_with?('!!!') }
|
||||
[(cls[false].to_a.map { |cl| ".#{Capybara::Selector::CSS.escape(cl.sub(/^!!/, ''))}" } +
|
||||
cls[true].to_a.map { |cl| ":not(.#{Capybara::Selector::CSS.escape(cl.slice(1..-1))})" }).join]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,59 +6,63 @@ module Capybara
|
|||
class Selector
|
||||
# @api private
|
||||
class XPathBuilder
|
||||
class << self
|
||||
def attribute_conditions(attributes)
|
||||
attributes.map do |attribute, value|
|
||||
case value
|
||||
when XPath::Expression
|
||||
XPath.attr(attribute)[value]
|
||||
when Regexp
|
||||
XPath.attr(attribute)[regexp_to_xpath_conditions(value)]
|
||||
when true
|
||||
XPath.attr(attribute)
|
||||
when false, nil
|
||||
!XPath.attr(attribute)
|
||||
def initialize(expression)
|
||||
@expression = expression || ''
|
||||
end
|
||||
|
||||
attr_reader :expression
|
||||
|
||||
def add_attribute_conditions(**conditions)
|
||||
@expression = conditions.inject(expression) do |xp, (name, value)|
|
||||
conditions = name == :class ? class_conditions(value) : attribute_conditions(name => value)
|
||||
if xp.is_a? XPath::Expression
|
||||
xp[conditions]
|
||||
else
|
||||
"(#{xp})[#{conditions}]"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def attribute_conditions(attributes)
|
||||
attributes.map do |attribute, value|
|
||||
case value
|
||||
when XPath::Expression
|
||||
XPath.attr(attribute)[value]
|
||||
when Regexp
|
||||
XPath.attr(attribute)[regexp_to_xpath_conditions(value)]
|
||||
when true
|
||||
XPath.attr(attribute)
|
||||
when false, nil
|
||||
!XPath.attr(attribute)
|
||||
else
|
||||
XPath.attr(attribute) == value.to_s
|
||||
end
|
||||
end.reduce(:&)
|
||||
end
|
||||
|
||||
def class_conditions(classes)
|
||||
case classes
|
||||
when XPath::Expression, Regexp
|
||||
attribute_conditions(class: classes)
|
||||
else
|
||||
Array(classes).map do |klass|
|
||||
if klass.start_with?('!') && !klass.start_with?('!!!')
|
||||
!XPath.attr(:class).contains_word(klass.slice(1..-1))
|
||||
else
|
||||
XPath.attr(attribute) == value.to_s
|
||||
XPath.attr(:class).contains_word(klass.sub(/^!!/, ''))
|
||||
end
|
||||
end.reduce(:&)
|
||||
end
|
||||
end
|
||||
|
||||
def add_attribute_conditions(xpath, **conditions)
|
||||
conditions.inject(xpath) do |xp, (name, value)|
|
||||
conditions = name == :class ? class_conditions(value) : attribute_conditions(name => value)
|
||||
if xp.is_a? XPath::Expression
|
||||
xp[conditions]
|
||||
else
|
||||
"(#{xp})[#{conditions}]"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def class_conditions(classes)
|
||||
case classes
|
||||
when XPath::Expression, Regexp
|
||||
attribute_conditions(class: classes)
|
||||
else
|
||||
Array(classes).map do |klass|
|
||||
if klass.start_with?('!') && !klass.start_with?('!!!')
|
||||
!XPath.attr(:class).contains_word(klass.slice(1..-1))
|
||||
else
|
||||
XPath.attr(:class).contains_word(klass.sub(/^!!/, ''))
|
||||
end
|
||||
end.reduce(:&)
|
||||
end
|
||||
end
|
||||
|
||||
def regexp_to_xpath_conditions(regexp)
|
||||
condition = XPath.current
|
||||
condition = condition.uppercase if regexp.casefold?
|
||||
Selector::RegexpDisassembler.new(regexp).alternated_substrings.map do |strs|
|
||||
strs.map { |str| condition.contains(str) }.reduce(:&)
|
||||
end.reduce(:|)
|
||||
end
|
||||
def regexp_to_xpath_conditions(regexp)
|
||||
condition = XPath.current
|
||||
condition = condition.uppercase if regexp.casefold?
|
||||
Selector::RegexpDisassembler.new(regexp).alternated_substrings.map do |strs|
|
||||
strs.map { |str| condition.contains(str) }.reduce(:&)
|
||||
end.reduce(:|)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -409,7 +409,7 @@ module Capybara
|
|||
end
|
||||
|
||||
# @api private
|
||||
def builder
|
||||
def builder(expr = nil)
|
||||
case format
|
||||
when :css
|
||||
Capybara::Selector::CSSBuilder
|
||||
|
@ -417,7 +417,7 @@ module Capybara
|
|||
Capybara::Selector::XPathBuilder
|
||||
else
|
||||
raise NotImplementedError, "No builder exists for selector of type #{format}"
|
||||
end
|
||||
end.new(expr)
|
||||
end
|
||||
|
||||
# @api private
|
||||
|
|
|
@ -83,7 +83,7 @@ Capybara::SpecHelper.spec '#click_link' do
|
|||
end
|
||||
|
||||
it "should raise error if link wasn't found" do
|
||||
expect { @session.click_link('labore', href: 'invalid_href') }.to raise_error(Capybara::ElementNotFound)
|
||||
expect { @session.click_link('labore', href: 'invalid_href') }.to raise_error(Capybara::ElementNotFound, /with href "invalid_href/)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -104,8 +104,8 @@ Capybara::SpecHelper.spec '#click_link' do
|
|||
end
|
||||
|
||||
it "should raise an error if no link's href matched the pattern" do
|
||||
expect { @session.click_link('labore', href: /invalid_pattern/) }.to raise_error(Capybara::ElementNotFound)
|
||||
expect { @session.click_link('labore', href: /.+d+/) }.to raise_error(Capybara::ElementNotFound)
|
||||
expect { @session.click_link('labore', href: /invalid_pattern/) }.to raise_error(Capybara::ElementNotFound, %r{with href matching /invalid_pattern/})
|
||||
expect { @session.click_link('labore', href: /.+d+/) }.to raise_error(Capybara::ElementNotFound, /#{Regexp.quote "with href matching /.+d+/"}/)
|
||||
end
|
||||
|
||||
context 'href: nil' do
|
||||
|
@ -114,8 +114,8 @@ Capybara::SpecHelper.spec '#click_link' do
|
|||
end
|
||||
|
||||
it 'should raise an error if href attribute exists' do
|
||||
expect { @session.click_link('Blank Href', href: nil) }.to raise_error(Capybara::ElementNotFound)
|
||||
expect { @session.click_link('Normal Anchor', href: nil) }.to raise_error(Capybara::ElementNotFound)
|
||||
expect { @session.click_link('Blank Href', href: nil) }.to raise_error(Capybara::ElementNotFound, /with no href attribute/)
|
||||
expect { @session.click_link('Normal Anchor', href: nil) }.to raise_error(Capybara::ElementNotFound, /with no href attribute/)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,94 +4,94 @@ require 'spec_helper'
|
|||
|
||||
RSpec.describe Capybara::Selector::CSSBuilder do
|
||||
let :builder do
|
||||
::Capybara::Selector::CSSBuilder
|
||||
::Capybara::Selector::CSSBuilder.new(@css)
|
||||
end
|
||||
|
||||
context 'add_attribute_conditions' do
|
||||
it 'adds a single string condition to a single selector' do
|
||||
css = 'div'
|
||||
selector = builder.add_attribute_conditions(css, random: 'abc')
|
||||
@css = 'div'
|
||||
selector = builder.add_attribute_conditions(random: 'abc')
|
||||
expect(selector).to eq %(div[random='abc'])
|
||||
end
|
||||
|
||||
it 'adds multiple string conditions to a single selector' do
|
||||
css = 'div'
|
||||
selector = builder.add_attribute_conditions(css, random: 'abc', other: 'def')
|
||||
@css = 'div'
|
||||
selector = builder.add_attribute_conditions(random: 'abc', other: 'def')
|
||||
expect(selector).to eq %(div[random='abc'][other='def'])
|
||||
end
|
||||
|
||||
it 'adds a single string condition to a multiple selector' do
|
||||
css = 'div, ul'
|
||||
selector = builder.add_attribute_conditions(css, random: 'abc')
|
||||
@css = 'div, ul'
|
||||
selector = builder.add_attribute_conditions(random: 'abc')
|
||||
expect(selector).to eq %(div[random='abc'], ul[random='abc'])
|
||||
end
|
||||
|
||||
it 'adds multiple string conditions to a multiple selector' do
|
||||
css = 'div, ul'
|
||||
selector = builder.add_attribute_conditions(css, random: 'abc', other: 'def')
|
||||
@css = 'div, ul'
|
||||
selector = builder.add_attribute_conditions(random: 'abc', other: 'def')
|
||||
expect(selector).to eq %(div[random='abc'][other='def'], ul[random='abc'][other='def'])
|
||||
end
|
||||
|
||||
it 'adds simple regexp conditions to a single selector' do
|
||||
css = 'div'
|
||||
selector = builder.add_attribute_conditions(css, random: /abc/, other: /def/)
|
||||
@css = 'div'
|
||||
selector = builder.add_attribute_conditions(random: /abc/, other: /def/)
|
||||
expect(selector).to eq %(div[random*='abc'][other*='def'])
|
||||
end
|
||||
|
||||
it 'adds wildcard regexp conditions to a single selector' do
|
||||
css = 'div'
|
||||
selector = builder.add_attribute_conditions(css, random: /abc.*def/, other: /def.*ghi/)
|
||||
@css = 'div'
|
||||
selector = builder.add_attribute_conditions(random: /abc.*def/, other: /def.*ghi/)
|
||||
expect(selector).to eq %(div[random*='abc'][random*='def'][other*='def'][other*='ghi'])
|
||||
end
|
||||
|
||||
it 'adds alternated regexp conditions to a single selector' do
|
||||
css = 'div'
|
||||
selector = builder.add_attribute_conditions(css, random: /abc|def/, other: /def|ghi/)
|
||||
@css = 'div'
|
||||
selector = builder.add_attribute_conditions(random: /abc|def/, other: /def|ghi/)
|
||||
expect(selector).to eq %(div[random*='abc'][other*='def'], div[random*='abc'][other*='ghi'], div[random*='def'][other*='def'], div[random*='def'][other*='ghi'])
|
||||
end
|
||||
|
||||
it 'adds alternated regexp conditions to a multiple selector' do
|
||||
css = 'div,ul'
|
||||
selector = builder.add_attribute_conditions(css, other: /def.*ghi|jkl/)
|
||||
@css = 'div,ul'
|
||||
selector = builder.add_attribute_conditions(other: /def.*ghi|jkl/)
|
||||
expect(selector).to eq %(div[other*='def'][other*='ghi'], div[other*='jkl'], ul[other*='def'][other*='ghi'], ul[other*='jkl'])
|
||||
end
|
||||
|
||||
it "returns original selector when regexp can't be substringed" do
|
||||
css = 'div'
|
||||
selector = builder.add_attribute_conditions(css, other: /.+/)
|
||||
@css = 'div'
|
||||
selector = builder.add_attribute_conditions(other: /.+/)
|
||||
expect(selector).to eq 'div'
|
||||
end
|
||||
|
||||
context ':class' do
|
||||
it 'handles string with CSS .' do
|
||||
css = 'a'
|
||||
selector = builder.add_attribute_conditions(css, class: 'my_class')
|
||||
@css = 'a'
|
||||
selector = builder.add_attribute_conditions(class: 'my_class')
|
||||
expect(selector).to eq 'a.my_class'
|
||||
end
|
||||
|
||||
it 'handles negated string with CSS .' do
|
||||
css = 'a'
|
||||
selector = builder.add_attribute_conditions(css, class: '!my_class')
|
||||
@css = 'a'
|
||||
selector = builder.add_attribute_conditions(class: '!my_class')
|
||||
expect(selector).to eq 'a:not(.my_class)'
|
||||
end
|
||||
|
||||
it 'handles array of string with CSS .' do
|
||||
css = 'a'
|
||||
selector = builder.add_attribute_conditions(css, class: %w[my_class my_other_class])
|
||||
@css = 'a'
|
||||
selector = builder.add_attribute_conditions(class: %w[my_class my_other_class])
|
||||
expect(selector).to eq 'a.my_class.my_other_class'
|
||||
end
|
||||
|
||||
it 'handles array of string with CSS . when negated included' do
|
||||
css = 'a'
|
||||
selector = builder.add_attribute_conditions(css, class: %w[my_class !my_other_class])
|
||||
@css = 'a'
|
||||
selector = builder.add_attribute_conditions(class: %w[my_class !my_other_class])
|
||||
expect(selector).to eq 'a.my_class:not(.my_other_class)'
|
||||
end
|
||||
end
|
||||
|
||||
context ':id' do
|
||||
it 'handles string with CSS #' do
|
||||
css = 'ul'
|
||||
selector = builder.add_attribute_conditions(css, id: 'my_id')
|
||||
@css = 'ul'
|
||||
selector = builder.add_attribute_conditions(id: 'my_id')
|
||||
expect(selector).to eq 'ul#my_id'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,87 +4,87 @@ require 'spec_helper'
|
|||
|
||||
RSpec.describe Capybara::Selector::XPathBuilder do
|
||||
let :builder do
|
||||
::Capybara::Selector::XPathBuilder
|
||||
::Capybara::Selector::XPathBuilder.new(@xpath)
|
||||
end
|
||||
|
||||
context 'add_attribute_conditions' do
|
||||
it 'adds a single string condition to a single selector' do
|
||||
xpath = './/div'
|
||||
selector = builder.add_attribute_conditions(xpath, random: 'abc')
|
||||
@xpath = './/div'
|
||||
selector = builder.add_attribute_conditions(random: 'abc')
|
||||
expect(selector).to eq %((.//div)[(./@random = 'abc')])
|
||||
end
|
||||
|
||||
it 'adds multiple string conditions to a single selector' do
|
||||
xpath = './/div'
|
||||
selector = builder.add_attribute_conditions(xpath, random: 'abc', other: 'def')
|
||||
@xpath = './/div'
|
||||
selector = builder.add_attribute_conditions(random: 'abc', other: 'def')
|
||||
expect(selector).to eq %(((.//div)[(./@random = 'abc')])[(./@other = 'def')])
|
||||
end
|
||||
|
||||
it 'adds a single string condition to a multiple selector' do
|
||||
xpath = XPath.descendant(:div, :ul)
|
||||
selector = builder.add_attribute_conditions(xpath, random: 'abc')
|
||||
expect(selector.to_s).to eq xpath[XPath.attr(:random) == 'abc'].to_s
|
||||
@xpath = XPath.descendant(:div, :ul)
|
||||
selector = builder.add_attribute_conditions(random: 'abc')
|
||||
expect(selector.to_s).to eq @xpath[XPath.attr(:random) == 'abc'].to_s
|
||||
end
|
||||
|
||||
it 'adds multiple string conditions to a multiple selector' do
|
||||
xpath = XPath.descendant(:div, :ul)
|
||||
selector = builder.add_attribute_conditions(xpath, random: 'abc', other: 'def')
|
||||
@xpath = XPath.descendant(:div, :ul)
|
||||
selector = builder.add_attribute_conditions(random: 'abc', other: 'def')
|
||||
expect(selector.to_s).to eq %(.//*[self::div | self::ul][(./@random = 'abc')][(./@other = 'def')])
|
||||
end
|
||||
|
||||
it 'adds simple regexp conditions to a single selector' do
|
||||
xpath = XPath.descendant(:div)
|
||||
selector = builder.add_attribute_conditions(xpath, random: /abc/, other: /def/)
|
||||
@xpath = XPath.descendant(:div)
|
||||
selector = builder.add_attribute_conditions(random: /abc/, other: /def/)
|
||||
expect(selector.to_s).to eq %(.//div[./@random[contains(., 'abc')]][./@other[contains(., 'def')]])
|
||||
end
|
||||
|
||||
it 'adds wildcard regexp conditions to a single selector' do
|
||||
xpath = './/div'
|
||||
selector = builder.add_attribute_conditions(xpath, random: /abc.*def/, other: /def.*ghi/)
|
||||
@xpath = './/div'
|
||||
selector = builder.add_attribute_conditions(random: /abc.*def/, other: /def.*ghi/)
|
||||
expect(selector).to eq %(((.//div)[./@random[(contains(., 'abc') and contains(., 'def'))]])[./@other[(contains(., 'def') and contains(., 'ghi'))]])
|
||||
end
|
||||
|
||||
it 'adds alternated regexp conditions to a single selector' do
|
||||
xpath = XPath.descendant(:div)
|
||||
selector = builder.add_attribute_conditions(xpath, random: /abc|def/, other: /def|ghi/)
|
||||
@xpath = XPath.descendant(:div)
|
||||
selector = builder.add_attribute_conditions(random: /abc|def/, other: /def|ghi/)
|
||||
expect(selector.to_s).to eq %(.//div[./@random[(contains(., 'abc') or contains(., 'def'))]][./@other[(contains(., 'def') or contains(., 'ghi'))]])
|
||||
end
|
||||
|
||||
it 'adds alternated regexp conditions to a multiple selector' do
|
||||
xpath = XPath.descendant(:div, :ul)
|
||||
selector = builder.add_attribute_conditions(xpath, other: /def.*ghi|jkl/)
|
||||
@xpath = XPath.descendant(:div, :ul)
|
||||
selector = builder.add_attribute_conditions(other: /def.*ghi|jkl/)
|
||||
expect(selector.to_s).to eq %(.//*[self::div | self::ul][./@other[((contains(., 'def') and contains(., 'ghi')) or contains(., 'jkl'))]])
|
||||
end
|
||||
|
||||
it "returns original selector when regexp can't be substringed" do
|
||||
xpath = './/div'
|
||||
selector = builder.add_attribute_conditions(xpath, other: /.+/)
|
||||
@xpath = './/div'
|
||||
selector = builder.add_attribute_conditions(other: /.+/)
|
||||
expect(selector).to eq '(.//div)[./@other]'
|
||||
end
|
||||
|
||||
context ':class' do
|
||||
it 'handles string' do
|
||||
xpath = './/a'
|
||||
selector = builder.add_attribute_conditions(xpath, class: 'my_class')
|
||||
@xpath = './/a'
|
||||
selector = builder.add_attribute_conditions(class: 'my_class')
|
||||
expect(selector).to eq %((.//a)[contains(concat(' ', normalize-space(./@class), ' '), ' my_class ')])
|
||||
end
|
||||
|
||||
it 'handles negated strings' do
|
||||
xpath = XPath.descendant(:a)
|
||||
selector = builder.add_attribute_conditions(xpath, class: '!my_class')
|
||||
expect(selector.to_s).to eq xpath[!XPath.attr(:class).contains_word('my_class')].to_s
|
||||
@xpath = XPath.descendant(:a)
|
||||
selector = builder.add_attribute_conditions(class: '!my_class')
|
||||
expect(selector.to_s).to eq @xpath[!XPath.attr(:class).contains_word('my_class')].to_s
|
||||
end
|
||||
|
||||
it 'handles array of strings' do
|
||||
xpath = './/a'
|
||||
selector = builder.add_attribute_conditions(xpath, class: %w[my_class my_other_class])
|
||||
@xpath = './/a'
|
||||
selector = builder.add_attribute_conditions(class: %w[my_class my_other_class])
|
||||
expect(selector).to eq %((.//a)[(contains(concat(' ', normalize-space(./@class), ' '), ' my_class ') and contains(concat(' ', normalize-space(./@class), ' '), ' my_other_class '))])
|
||||
end
|
||||
|
||||
it 'handles array of string when negated included' do
|
||||
xpath = XPath.descendant(:a)
|
||||
selector = builder.add_attribute_conditions(xpath, class: %w[my_class !my_other_class])
|
||||
expect(selector.to_s).to eq xpath[XPath.attr(:class).contains_word('my_class') & !XPath.attr(:class).contains_word('my_other_class')].to_s
|
||||
@xpath = XPath.descendant(:a)
|
||||
selector = builder.add_attribute_conditions(class: %w[my_class !my_other_class])
|
||||
expect(selector.to_s).to eq @xpath[XPath.attr(:class).contains_word('my_class') & !XPath.attr(:class).contains_word('my_other_class')].to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue