mirror of
https://github.com/teamcapybara/capybara.git
synced 2022-11-09 12:08:07 -05:00
Support negated classes in the :class filter option
This commit is contained in:
parent
cc9629645d
commit
6995982268
3 changed files with 26 additions and 5 deletions
|
@ -202,7 +202,11 @@ module Capybara
|
|||
XPath.attr(:class)[options[:class]]
|
||||
else
|
||||
Array(options[:class]).map do |klass|
|
||||
XPath.attr(:class).contains_word(klass)
|
||||
if klass.start_with?('!')
|
||||
!XPath.attr(:class).contains_word(klass.slice(1))
|
||||
else
|
||||
XPath.attr(:class).contains_word(klass)
|
||||
end
|
||||
end.reduce(:&)
|
||||
end
|
||||
expr = "(#{expr})[#{class_xpath}]"
|
||||
|
@ -224,12 +228,18 @@ module Capybara
|
|||
css_selectors = expr.split(',').map(&:rstrip)
|
||||
expr = css_selectors.map do |sel|
|
||||
sel += "##{Capybara::Selector::CSS.escape(options[:id])}" if process_id
|
||||
sel += Array(options[:class]).map { |k| ".#{Capybara::Selector::CSS.escape(k)}" }.join if process_class
|
||||
sel += css_from_classes(Array(options[:class])) if process_class
|
||||
sel
|
||||
end.join(", ")
|
||||
expr
|
||||
end
|
||||
|
||||
def css_from_classes(classes)
|
||||
classes = classes.group_by { |c| c.start_with? '!' }
|
||||
(classes[false].to_a.map { |c| ".#{Capybara::Selector::CSS.escape(c)}" } +
|
||||
classes[true].to_a.map { |c| ":not(.#{Capybara::Selector::CSS.escape(c.slice(1))})" }).join
|
||||
end
|
||||
|
||||
def apply_expression_filters(expr)
|
||||
unapplied_options = options.keys - valid_keys
|
||||
expression_filters.inject(expr) do |memo, (name, ef)|
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# rubocop:disable Style/AsciiComments
|
||||
|
||||
require 'capybara/selector/filter_set'
|
||||
require 'capybara/selector/css'
|
||||
|
||||
|
@ -426,3 +428,5 @@ module Capybara
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
# rubocop:enable Style/AsciiComments
|
||||
|
|
|
@ -16,8 +16,8 @@ RSpec.describe Capybara do
|
|||
<h1 class="a">Totally awesome</h1>
|
||||
<p>Yes it is</p>
|
||||
</div>
|
||||
<p class="b">Some Content</p>
|
||||
<p class="b"></p>
|
||||
<p class="b c">Some Content</p>
|
||||
<p class="b d"></p>
|
||||
</div>
|
||||
<div id="#special">
|
||||
</div>
|
||||
|
@ -64,7 +64,7 @@ RSpec.describe Capybara do
|
|||
it "supports `filter` as an alias for `node_filter`" do
|
||||
expect do
|
||||
Capybara.add_selector :filter_alias_selector do
|
||||
css { |_unused| "div"}
|
||||
css { |_unused| "div" }
|
||||
filter(:something) { |_node, _value| true }
|
||||
end
|
||||
end.not_to raise_error
|
||||
|
@ -155,6 +155,13 @@ RSpec.describe Capybara do
|
|||
expect(string.all(:custom_css_selector, "h1, div", class: 'a').size).to eq 2
|
||||
end
|
||||
|
||||
it "handles negated classes" do
|
||||
expect(string.all(:custom_css_selector, "div, p", class: ['b', '!c']).size).to eq 2
|
||||
expect(string.all(:custom_css_selector, "div, p", class: ['!c', '!d', 'b']).size).to eq 1
|
||||
expect(string.all(:custom_xpath_selector, XPath.descendant(:div, :p), class: ['b', '!c']).size).to eq 2
|
||||
expect(string.all(:custom_xpath_selector, XPath.descendant(:div, :p), class: ['!c', '!d', 'b']).size).to eq 1
|
||||
end
|
||||
|
||||
it "works with 'special' characters" do
|
||||
expect(string.find(:custom_css_selector, "input", class: ".special")[:id]).to eq 'file'
|
||||
expect(string.find(:custom_css_selector, "input", class: "2checkbox")[:id]).to eq '2checkbox'
|
||||
|
|
Loading…
Add table
Reference in a new issue