Support Regexp for `exact_text` option
This commit is contained in:
parent
2fece8d516
commit
5c8e975d5c
|
@ -10,6 +10,7 @@ Release date: unreleased
|
|||
* [Beta] CSP nonces inserted into animation disabler additions - Issue #2542
|
||||
* Support `<base>` element in rack-test driver - ISsue #2544
|
||||
* [Beta] `Element#shadow_root` support. Requires selenium-webdriver 4.1+. Only currently supported with Chrome when using the selenium driver. Note: only CSS can be used to find elements from the shadow root. Therefore you won't be able to use most Capybara helper methods (`fill_in`, `click_link`, `find_field`, etc) directly from the shadow root since those locators are built using XPath. If you first locate a descendant from the shadow root using CSS then you should be able to use all the Capybara methods from there.
|
||||
* Regexp now supported for `exact_text` finder option
|
||||
|
||||
### Fixed
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ module Capybara
|
|||
#
|
||||
# @!macro system_filters
|
||||
# @option options [String, Regexp] text Only find elements which contain this text or match this regexp
|
||||
# @option options [String, Boolean] exact_text
|
||||
# @option options [String, Regexp, String] exact_text
|
||||
# When String the elements contained text must match exactly, when Boolean controls whether the `text` option must match exactly.
|
||||
# Defaults to {Capybara.configure exact_text}.
|
||||
# @option options [Boolean] normalize_ws
|
||||
|
|
|
@ -27,6 +27,12 @@ module Capybara
|
|||
@order = order
|
||||
@filter_cache = Hash.new { |hsh, key| hsh[key] = {} }
|
||||
|
||||
if @options[:text].is_a?(Regexp) && [true, false].include?(@options[:exact_text])
|
||||
Capybara::Helpers.warn(
|
||||
"Boolean 'exact_text' option is not supported when 'text' option is a Regexp - ignoring"
|
||||
)
|
||||
end
|
||||
|
||||
super(@options)
|
||||
self.session_options = session_options
|
||||
|
||||
|
@ -541,16 +547,19 @@ module Capybara
|
|||
def matches_text_filter?(node)
|
||||
value = options[:text]
|
||||
return true unless value
|
||||
return matches_text_exactly?(node, value) if exact_text == true
|
||||
return matches_text_exactly?(node, value) if exact_text == true && !value.is_a?(Regexp)
|
||||
|
||||
regexp = value.is_a?(Regexp) ? value : Regexp.escape(value.to_s)
|
||||
matches_text_regexp?(node, regexp)
|
||||
end
|
||||
|
||||
def matches_exact_text_filter?(node)
|
||||
return true unless exact_text.is_a?(String)
|
||||
|
||||
matches_text_exactly?(node, exact_text)
|
||||
case exact_text
|
||||
when String, Regexp
|
||||
matches_text_exactly?(node, exact_text)
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
def matches_visibility_filters?(node)
|
||||
|
@ -578,17 +587,21 @@ module Capybara
|
|||
|
||||
def matches_text_exactly?(node, value)
|
||||
regexp = value.is_a?(Regexp) ? value : /\A#{Regexp.escape(value.to_s)}\z/
|
||||
matches_text_regexp?(node, regexp)
|
||||
matches_text_regexp(node, regexp).then { |m| m&.pre_match == '' && m&.post_match == '' }
|
||||
end
|
||||
|
||||
def normalize_ws
|
||||
options.fetch(:normalize_ws, session_options.default_normalize_ws)
|
||||
end
|
||||
|
||||
def matches_text_regexp?(node, regexp)
|
||||
def matches_text_regexp(node, regexp)
|
||||
text_visible = visible
|
||||
text_visible = :all if text_visible == :hidden
|
||||
node.text(text_visible, normalize_ws: normalize_ws).match?(regexp)
|
||||
node.text(text_visible, normalize_ws: normalize_ws).match(regexp)
|
||||
end
|
||||
|
||||
def matches_text_regexp?(node, regexp)
|
||||
!matches_text_regexp(node, regexp).nil?
|
||||
end
|
||||
|
||||
def default_visibility
|
||||
|
|
|
@ -117,6 +117,21 @@ Capybara::SpecHelper.spec '#has_selector?' do
|
|||
expect(@session).to have_selector(:id, 'h2one', text: 'Header Class Test One', exact_text: false)
|
||||
expect(@session).to have_selector(:id, 'h2one', text: 'Header Class Test', exact_text: false)
|
||||
end
|
||||
|
||||
it 'should warn if text option is a regexp that it is ignoring exact_text' do
|
||||
allow(Capybara::Helpers).to receive(:warn)
|
||||
expect(@session).to have_selector(:id, 'h2one', text: /Class Test/, exact_text: true)
|
||||
expect(Capybara::Helpers).to have_received(:warn).with(/'exact_text' option is not supported/)
|
||||
end
|
||||
end
|
||||
|
||||
context 'regexp' do
|
||||
it 'should only match when it fully matches' do
|
||||
expect(@session).to have_selector(:id, 'h2one', exact_text: /Header Class Test One/)
|
||||
expect(@session).to have_no_selector(:id, 'h2one', exact_text: /Header Class Test/)
|
||||
expect(@session).to have_no_selector(:id, 'h2one', exact_text: /Class Test One/)
|
||||
expect(@session).to have_no_selector(:id, 'h2one', exact_text: /Class Test/)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue