Add support for `focused:` filter
[Follow-up to #2489][], adds support for filtering fields, links, and buttons based on whether or not they're focused. [Follow-up to #2489]: https://github.com/teamcapybara/capybara/pull/2489
This commit is contained in:
parent
ed3c947130
commit
c3b601ebc3
|
@ -10,6 +10,7 @@ Release date: unreleased
|
|||
* `allow_label_click` accepts click options to be used when clicking an associated label
|
||||
* Deprecated `allow_gumbo=` in favor of `use_html5_parsing=` to enable use of Nokogiri::HTL5 when available
|
||||
* `Session#active_element` returns the element with focus - Not supported by the `RackTest` driver [Sean Doyle]
|
||||
* Support `focused:` filter for finding interactive elements - Not supported by the `RackTest` driver [Sean Doyle]
|
||||
|
||||
### Fixed
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ module Capybara
|
|||
|
||||
SPATIAL_KEYS = %i[above below left_of right_of near].freeze
|
||||
VALID_KEYS = SPATIAL_KEYS + COUNT_KEYS +
|
||||
%i[text id class style visible obscured exact exact_text normalize_ws match wait filter_set]
|
||||
%i[text id class style visible obscured exact exact_text normalize_ws match wait filter_set focused]
|
||||
VALID_MATCH = %i[first smart prefer_exact one].freeze
|
||||
|
||||
def initialize(*args,
|
||||
|
@ -73,6 +73,8 @@ module Capybara
|
|||
|
||||
desc << " with id #{options[:id]}" if options[:id]
|
||||
desc << " with classes [#{Array(options[:class]).join(',')}]" if options[:class]
|
||||
desc << ' that is focused' if options[:focused]
|
||||
desc << ' that is not focused' if options[:focused] == false
|
||||
|
||||
desc << case options[:style]
|
||||
when String
|
||||
|
@ -435,6 +437,7 @@ module Capybara
|
|||
matches_id_filter?(node) &&
|
||||
matches_class_filter?(node) &&
|
||||
matches_style_filter?(node) &&
|
||||
matches_focused_filter?(node) &&
|
||||
matches_text_filter?(node) &&
|
||||
matches_exact_text_filter?(node)
|
||||
end
|
||||
|
@ -494,6 +497,16 @@ module Capybara
|
|||
end
|
||||
end
|
||||
|
||||
def matches_focused_filter?(node)
|
||||
if options.key?(:focused)
|
||||
node_is_focused = node == node.session.active_element
|
||||
|
||||
node_is_focused == options[:focused]
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
def need_to_process_classes?
|
||||
case options[:class]
|
||||
when Regexp then true
|
||||
|
|
|
@ -14,6 +14,7 @@ require 'capybara/selector/definition'
|
|||
# * :left_of (Element) - Match elements left of the passed element on the page
|
||||
# * :right_of (Element) - Match elements right of the passed element on the page
|
||||
# * :near (Element) - Match elements near (within 50px) the passed element on the page
|
||||
# * :focused (Boolean) - Match elements with focus (requires JavaScript)
|
||||
#
|
||||
# ### Built-in Selectors
|
||||
#
|
||||
|
|
|
@ -65,6 +65,18 @@ Capybara::SpecHelper.spec '#has_button?' do
|
|||
it 'should not affect other selectors when enable_aria_role: false' do
|
||||
expect(@session).to have_button('Click me!', enable_aria_role: false)
|
||||
end
|
||||
|
||||
context 'with focused:', requires: [:js] do
|
||||
it 'should be true if a field has focus when focused: true' do
|
||||
@session.send_keys(:tab)
|
||||
|
||||
expect(@session).to have_button('A Button', focused: true)
|
||||
end
|
||||
|
||||
it 'should be false if a field does not have focus when focused: false' do
|
||||
expect(@session).not_to have_button('A Button', focused: false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Capybara::SpecHelper.spec '#has_no_button?' do
|
||||
|
@ -117,4 +129,16 @@ Capybara::SpecHelper.spec '#has_no_button?' do
|
|||
it 'should not affect other selectors when enable_aria_role: false' do
|
||||
expect(@session).to have_no_button('Junk button that does not exist', enable_aria_role: false)
|
||||
end
|
||||
|
||||
context 'with focused:', requires: [:js] do
|
||||
it 'should be true if a field has focus when focused: true' do
|
||||
expect(@session).to have_no_button('A Button', focused: false)
|
||||
end
|
||||
|
||||
it 'should be false if a field does not have focus when focused: false' do
|
||||
@session.send_keys(:tab)
|
||||
|
||||
expect(@session).to have_no_button('A Button', focused: true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -110,6 +110,18 @@ Capybara::SpecHelper.spec '#has_field' do
|
|||
end
|
||||
end
|
||||
|
||||
context 'with focused', requires: [:js] do
|
||||
it 'should be true if a field has focus' do
|
||||
2.times { @session.send_keys(:tab) }
|
||||
|
||||
expect(@session).to have_field('An Input', focused: true)
|
||||
end
|
||||
|
||||
it 'should be false if a field does not have focus' do
|
||||
expect(@session).to have_field('An Input', focused: false)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with valid', requires: [:js] do
|
||||
it 'should be true if field is valid' do
|
||||
@session.fill_in 'required', with: 'something'
|
||||
|
@ -184,6 +196,18 @@ Capybara::SpecHelper.spec '#has_no_field' do
|
|||
expect(@session).to have_no_field('Languages', type: 'textarea')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with focused', requires: [:js] do
|
||||
it 'should be true if a field does not have focus' do
|
||||
expect(@session).to have_field('An Input', focused: true)
|
||||
end
|
||||
|
||||
it 'should be false if a field has focus' do
|
||||
2.times { @session.send_keys(:tab) }
|
||||
|
||||
expect(@session).to have_field('An Input', focused: false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Capybara::SpecHelper.spec '#has_checked_field?' do
|
||||
|
|
|
@ -18,6 +18,18 @@ Capybara::SpecHelper.spec '#has_link?' do
|
|||
expect(@session).not_to have_link('A link', href: '/nonexistent-href')
|
||||
expect(@session).not_to have_link('A link', href: /nonexistent/)
|
||||
end
|
||||
|
||||
context 'with focused:', requires: [:js] do
|
||||
it 'should be true if the given link is on the page and has focus' do
|
||||
@session.send_keys(:tab)
|
||||
|
||||
expect(@session).to have_link('labore', focused: true)
|
||||
end
|
||||
|
||||
it 'should be false if the given link is on the page and does not have focus' do
|
||||
expect(@session).to have_link('labore', focused: false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Capybara::SpecHelper.spec '#has_no_link?' do
|
||||
|
@ -36,4 +48,16 @@ Capybara::SpecHelper.spec '#has_no_link?' do
|
|||
expect(@session).to have_no_link('A link', href: '/nonexistent-href')
|
||||
expect(@session).to have_no_link('A link', href: %r{/nonexistent-href})
|
||||
end
|
||||
|
||||
context 'with focused:', requires: [:js] do
|
||||
it 'should be true if the given link is on the page and has focus' do
|
||||
expect(@session).to have_no_link('labore', focused: true)
|
||||
end
|
||||
|
||||
it 'should be false if the given link is on the page and does not have focus' do
|
||||
@session.send_keys(:tab)
|
||||
|
||||
expect(@session).to have_no_link('labore', focused: false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
<h1>Form</h1>
|
||||
|
||||
<button type="button" tabindex="1">A Button</button>
|
||||
|
||||
<label>
|
||||
An Input
|
||||
<input type="text" tabindex="2">
|
||||
</label>
|
||||
|
||||
<form action="/form" method="post" novalidate>
|
||||
|
||||
<p>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
<p class="para" id="first" data-random="abc\def" style="line-height: 25px;">
|
||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
||||
tempor incididunt ut <a href="/with_simple_html" title="awesome title" class="simple">labore</a>
|
||||
tempor incididunt ut <a href="/with_simple_html" title="awesome title" class="simple" tabindex="1">labore</a>
|
||||
et dolore magna aliqua. Ut enim ad minim veniam,
|
||||
quis nostrud exercitation <a href="/foo" id="foo" data-test-id="test-foo">ullamco</a> laboris nisi
|
||||
ut aliquip ex ea commodo consequat.
|
||||
|
|
|
@ -12,7 +12,6 @@ skipped_tests = %i[
|
|||
screenshot
|
||||
frames
|
||||
windows
|
||||
active_element
|
||||
send_keys
|
||||
server
|
||||
hover
|
||||
|
|
Loading…
Reference in New Issue