Skip to content

Commit

Permalink
Add support :target filter option on :link selector (#2656)
Browse files Browse the repository at this point in the history
This PR adds support  for `:target` filter option on `:link` selector.
  • Loading branch information
ydah committed Apr 2, 2023
1 parent 0ef62a8 commit 7cdbe96
Show file tree
Hide file tree
Showing 7 changed files with 35 additions and 3 deletions.
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

0 comments on commit 7cdbe96

Please sign in to comment.