mirror of
https://github.com/teamcapybara/capybara.git
synced 2022-11-09 12:08:07 -05:00
first swipe at filter sets
This commit is contained in:
parent
d624cbd552
commit
3331f8b3c4
4 changed files with 108 additions and 9 deletions
|
@ -4,7 +4,7 @@ module Capybara
|
|||
class SelectorQuery < Queries::BaseQuery
|
||||
attr_accessor :selector, :locator, :options, :expression, :find, :negative
|
||||
|
||||
VALID_KEYS = [:text, :visible, :between, :count, :maximum, :minimum, :exact, :match, :wait]
|
||||
VALID_KEYS = [:text, :visible, :between, :count, :maximum, :minimum, :exact, :match, :wait, :filter_set]
|
||||
VALID_MATCH = [:first, :smart, :prefer_exact, :one]
|
||||
|
||||
def initialize(*args)
|
||||
|
@ -49,7 +49,7 @@ module Capybara
|
|||
when :visible then return false unless node.visible?
|
||||
when :hidden then return false if node.visible?
|
||||
end
|
||||
selector.custom_filters.each do |name, filter|
|
||||
query_filters.each do |name, filter|
|
||||
if options.has_key?(name)
|
||||
return false unless filter.matches?(node, options[name])
|
||||
elsif filter.default?
|
||||
|
@ -124,7 +124,20 @@ module Capybara
|
|||
private
|
||||
|
||||
def valid_keys
|
||||
COUNT_KEYS + [:text, :visible, :exact, :match, :wait] + @selector.custom_filters.keys
|
||||
vk = COUNT_KEYS + [:text, :visible, :exact, :match, :wait, :filter_set]
|
||||
vk + custom_keys
|
||||
end
|
||||
|
||||
def query_filters
|
||||
if options.has_key?(:filter_set)
|
||||
Capybara::Selector::FilterSet.all[options[:filter_set]].filters
|
||||
else
|
||||
@selector.custom_filters
|
||||
end
|
||||
end
|
||||
|
||||
def custom_keys
|
||||
query_filters.keys
|
||||
end
|
||||
|
||||
def assert_valid_keys
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
require 'capybara/selector/filter'
|
||||
require 'capybara/selector/filter_set'
|
||||
|
||||
module Capybara
|
||||
class Selector
|
||||
|
||||
attr_reader :name, :custom_filters, :format
|
||||
attr_reader :name, :format
|
||||
|
||||
class << self
|
||||
def all
|
||||
|
@ -26,7 +26,7 @@ module Capybara
|
|||
|
||||
def initialize(name, &block)
|
||||
@name = name
|
||||
@custom_filters = {}
|
||||
@filter_set = FilterSet.add(name){}
|
||||
@match = nil
|
||||
@label = nil
|
||||
@failure_message = nil
|
||||
|
@ -36,6 +36,10 @@ module Capybara
|
|||
instance_eval(&block)
|
||||
end
|
||||
|
||||
def custom_filters
|
||||
@filter_set.filters
|
||||
end
|
||||
|
||||
def xpath(&block)
|
||||
@format, @expression = :xpath, block if block
|
||||
format == :xpath ? @expression : nil
|
||||
|
@ -57,7 +61,7 @@ module Capybara
|
|||
end
|
||||
|
||||
def description(options={})
|
||||
(@description && @description.call(options)).to_s
|
||||
@filter_set.description(options)
|
||||
end
|
||||
|
||||
def call(locator)
|
||||
|
@ -73,11 +77,19 @@ module Capybara
|
|||
end
|
||||
|
||||
def filter(name, options={}, &block)
|
||||
@custom_filters[name] = Filter.new(name, block, options)
|
||||
custom_filters[name] = Filter.new(name, block, options)
|
||||
end
|
||||
|
||||
def filter_set(name)
|
||||
f_set = FilterSet.all[name]
|
||||
f_set.filters.each do | name, filter |
|
||||
custom_filters[name] = filter
|
||||
end
|
||||
f_set.descriptions.each { |desc| @filter_set.describe &desc }
|
||||
end
|
||||
|
||||
def describe &block
|
||||
@description = block
|
||||
@filter_set.describe &block
|
||||
end
|
||||
|
||||
private
|
||||
|
|
46
lib/capybara/selector/filter_set.rb
Normal file
46
lib/capybara/selector/filter_set.rb
Normal file
|
@ -0,0 +1,46 @@
|
|||
# frozen_string_literal: true
|
||||
require 'capybara/selector/filter'
|
||||
|
||||
module Capybara
|
||||
class Selector
|
||||
class FilterSet
|
||||
attr_reader :descriptions
|
||||
|
||||
def initialize(name, &block)
|
||||
@name = name
|
||||
@descriptions = []
|
||||
instance_eval(&block)
|
||||
end
|
||||
|
||||
def filter(name, options={}, &block)
|
||||
filters[name] = Filter.new(name, block, options)
|
||||
end
|
||||
|
||||
def describe(&block)
|
||||
descriptions.push block
|
||||
end
|
||||
|
||||
def description(options={})
|
||||
@descriptions.map {|desc| desc.call(options).to_s }.join
|
||||
end
|
||||
|
||||
def filters
|
||||
@filters ||= {}
|
||||
end
|
||||
|
||||
class << self
|
||||
def all
|
||||
@filter_sets ||= {}
|
||||
end
|
||||
|
||||
def add(name, &block)
|
||||
all[name.to_sym] = FilterSet.new(name.to_sym, &block)
|
||||
end
|
||||
|
||||
def remove(name)
|
||||
all.delete(name.to_sym)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -165,6 +165,34 @@ Capybara::SpecHelper.spec '#find' do
|
|||
end
|
||||
end
|
||||
|
||||
context "with alternate filter set" do
|
||||
before do
|
||||
Capybara::Selector::FilterSet.add(:value) do
|
||||
filter(:with) { |node, with| node.value == with.to_s }
|
||||
end
|
||||
|
||||
Capybara.add_selector(:id_with_field_filters) do
|
||||
xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] }
|
||||
filter_set(:field)
|
||||
end
|
||||
end
|
||||
|
||||
it "should allow use of filters from custom filter set" do
|
||||
expect(@session.find(:id, 'test_field', filter_set: :value, with: 'monkey').value).to eq('monkey')
|
||||
expect{ @session.find(:id, 'test_field', filter_set: :value, with: 'not_monkey') }.to raise_error(Capybara::ElementNotFound)
|
||||
end
|
||||
|
||||
it "should allow use of filter set from a different selector" do
|
||||
expect(@session.find(:id, 'test_field', filter_set: :field, with: 'monkey').value).to eq('monkey')
|
||||
expect{ @session.find(:id, 'test_field', filter_set: :field, with: 'not_monkey') }.to raise_error(Capybara::ElementNotFound)
|
||||
end
|
||||
|
||||
it "should allow importing of filter set into selector" do
|
||||
expect(@session.find(:id_with_field_filters, 'test_field', with: 'monkey').value).to eq('monkey')
|
||||
expect{ @session.find(:id_with_field_filters, 'test_field', with: 'not_monkey') }.to raise_error(Capybara::ElementNotFound)
|
||||
end
|
||||
end
|
||||
|
||||
context "with css as default selector" do
|
||||
before { Capybara.default_selector = :css }
|
||||
it "should find the first element using the given locator" do
|
||||
|
|
Loading…
Reference in a new issue