Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support :target filter option on :link selector #2656

Merged
merged 1 commit into from
Apr 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions History.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Version 3.39.0
Release date: unreleased

### Added

* Support `:target` filter option on `:link` selector [Yudai Takada]

### Changed

* Dropped support for rack 1.x
Expand Down
2 changes: 2 additions & 0 deletions lib/capybara/node/finders.rb
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ def find_field(locator = nil, **options, &optional_filter_block)
# @option options [String, Regexp] id Match links with the id provided
# @option options [String] title Match links with the title provided
# @option options [String] alt Match links with a contained img element whose alt matches
# @option options [String, Boolean] download Match links with the download provided
# @option options [String] target Match links with the target provided
# @option options [String, Array<String>, Regexp] class Match links that match the class(es) provided
# @return [Capybara::Node::Element] The found element
#
Expand Down
3 changes: 2 additions & 1 deletion lib/capybara/selector/definition/link.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# frozen_string_literal: true

Capybara.add_selector(:link, locator_type: [String, Symbol]) do
xpath do |locator, href: true, alt: nil, title: nil, **|
xpath do |locator, href: true, alt: nil, title: nil, target: nil, **|
xpath = XPath.descendant(:a)
xpath = builder(xpath).add_attribute_conditions(href: href) unless href == false

Expand All @@ -25,6 +25,7 @@

xpath = xpath[find_by_attr(:title, title)]
xpath = xpath[XPath.descendant(:img)[XPath.attr(:alt) == alt]] if alt
xpath = xpath[find_by_attr(:target, target)] if target

xpath
end
Expand Down
11 changes: 11 additions & 0 deletions lib/capybara/spec/session/click_link_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,17 @@
end
end

context 'with :target option given' do
it 'should find links with valid target' do
@session.click_link('labore', target: '_self')
expect(@session).to have_content('Bar')
end

it "should raise error if link wasn't found" do
expect { @session.click_link('labore', target: '_blank') }.to raise_error(Capybara::ElementNotFound, /Unable to find link "labore"/)
end
end

it 'should follow relative links' do
@session.visit('/')
@session.click_link('Relative')
Expand Down
10 changes: 10 additions & 0 deletions lib/capybara/spec/session/find_link_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,14 @@
expect { @session.find_link(download: 37) }.to raise_error ArgumentError
end
end

context 'with :target option' do
it 'should accept partial matches when false' do
expect(@session.find_link(target: '_self').text).to eq('labore')
end

it 'should not accept partial matches when true' do
expect { @session.find_link(target: '_blank') }.to raise_error Capybara::ElementNotFound
end
end
end
6 changes: 5 additions & 1 deletion lib/capybara/spec/session/has_link_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@
expect(@session).to have_link('A link', href: '/with_simple_html')
expect(@session).to have_link(:'A link', href: :'/with_simple_html')
expect(@session).to have_link('A link', href: %r{/with_simple_html})
expect(@session).to have_link('labore', target: '_self')
end

it 'should be false if the given link is not on the page' do
expect(@session).not_to have_link('monkey')
expect(@session).not_to have_link('A link', href: '/nonexistent-href')
expect(@session).not_to have_link('A link', href: /nonexistent/)
expect(@session).not_to have_link('labore', target: '_blank')
end

it 'should notify if an invalid locator is specified' do
Expand All @@ -40,7 +42,7 @@
it 'should raise an error if an invalid option is passed' do
expect do
expect(@session).to have_link('labore', invalid: true)
end.to raise_error(ArgumentError, 'Invalid option(s) :invalid, should be one of :above, :below, :left_of, :right_of, :near, :count, :minimum, :maximum, :between, :text, :id, :class, :style, :visible, :obscured, :exact, :exact_text, :normalize_ws, :match, :wait, :filter_set, :focused, :href, :alt, :title, :download')
end.to raise_error(ArgumentError, 'Invalid option(s) :invalid, should be one of :above, :below, :left_of, :right_of, :near, :count, :minimum, :maximum, :between, :text, :id, :class, :style, :visible, :obscured, :exact, :exact_text, :normalize_ws, :match, :wait, :filter_set, :focused, :href, :alt, :title, :target, :download')
end
end

Expand All @@ -53,12 +55,14 @@
expect(@session).not_to have_no_link('foo')
expect(@session).not_to have_no_link('awesome title')
expect(@session).not_to have_no_link('A link', href: '/with_simple_html')
expect(@session).not_to have_no_link('labore', target: '_self')
end

it 'should be true if the given link is not on the page' do
expect(@session).to have_no_link('monkey')
expect(@session).to have_no_link('A link', href: '/nonexistent-href')
expect(@session).to have_no_link('A link', href: %r{/nonexistent-href})
expect(@session).not_to have_no_link('labore', target: '_blank')
end

context 'with focused:', requires: [:active_element] do
Expand Down
2 changes: 1 addition & 1 deletion lib/capybara/spec/views/with_html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -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" tabindex="1">labore</a>
tempor incididunt ut <a href="/with_simple_html" title="awesome title" class="simple" tabindex="1" target="_self">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.
Expand Down