Document Built-in Selectors
This commit is contained in:
parent
17479d7cd0
commit
f706b123d0
|
@ -0,0 +1,33 @@
|
|||
<div id="selectors">
|
||||
<h2>Built-in Selectors</h2>
|
||||
<ul>
|
||||
<% @selectors.each do |name, selector| %>
|
||||
<li>
|
||||
<h3>:<%= name %></h3>
|
||||
<div class="tags">
|
||||
<p class="inline">Locator:</p>
|
||||
<% if locator=selector.tag('locator') %>
|
||||
<p class="inline"><%= locator.text %></p>
|
||||
<% end %>
|
||||
<% if selector.has_tag?('filter') %>
|
||||
<p>Filters:</p>
|
||||
<ul class="param">
|
||||
<% selector.tags('filter').each do |filter| %>
|
||||
<li>
|
||||
<span class="name"><%= filter.name %></span>
|
||||
<% if filter.types %>
|
||||
<span class="type">(<tt><%= filter.types.join(', ') %></tt>)</span>
|
||||
<% end %>
|
||||
<% if filter.text %>
|
||||
—
|
||||
<div class="inline"><p><%= filter.text %></p></div>
|
||||
<% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
</div
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
</div>
|
|
@ -0,0 +1,17 @@
|
|||
def init
|
||||
super
|
||||
sections.place(:builtins).before(:subclasses)
|
||||
end
|
||||
|
||||
def builtins
|
||||
return if object.path != "Capybara::Selector" # only show built-in selectors for Selector class
|
||||
|
||||
@selectors = Registry.all(:selector)
|
||||
return if @selectors.nil? || @selectors.empty?
|
||||
|
||||
@selectors = @selectors.map do |selector|
|
||||
[selector.name, selector]
|
||||
end
|
||||
|
||||
erb(:selectors)
|
||||
end
|
|
@ -0,0 +1,81 @@
|
|||
YARD::Templates::Engine.register_template_path Pathname.new('./.yard/templates_custom')
|
||||
|
||||
YARD::Tags::Library.define_tag "Locator", :locator
|
||||
YARD::Tags::Library.define_tag "Filter", :filter, :with_types_and_name
|
||||
|
||||
class SelectorObject < YARD::CodeObjects::Base
|
||||
def path
|
||||
"__Capybara" + sep + super
|
||||
end
|
||||
end
|
||||
|
||||
class AddSelectorHandler < YARD::Handlers::Ruby::Base
|
||||
handles method_call(:add_selector)
|
||||
namespace_only
|
||||
process do
|
||||
name = statement.parameters.first.jump(:tstring_content, :ident).source
|
||||
# object = YARD::CodeObjects::MethodObject.new(namespace, name.to_sym)
|
||||
# object = SelectorObject.new(YARD::Registry.resolve(P("Capybara"), "#add_selector", false, true), name.to_sym)
|
||||
object = SelectorObject.new(namespace, name)
|
||||
register(object)
|
||||
parse_block(statement.last.last, :owner => object)
|
||||
|
||||
# modify the object
|
||||
object.dynamic = true
|
||||
|
||||
# add custom metadata to the object
|
||||
object['custom_field'] = 'Generated by add_selector'
|
||||
end
|
||||
end
|
||||
|
||||
class AddExpressionFilterHandler < YARD::Handlers::Ruby::Base
|
||||
handles method_call(:xpath)
|
||||
handles method_call(:css)
|
||||
|
||||
process do
|
||||
return unless owner.is_a?(SelectorObject)
|
||||
return if statement.parameters.empty?
|
||||
# names = statement.parameters.children.map { |p| p.jump(:tstring_content, :ident).source.sub(/^:/, '') }
|
||||
names = statement.parameters.children.map &:source
|
||||
current_names = owner.tags(:filter).map(&:name)
|
||||
(names-current_names).each do |name|
|
||||
owner.add_tag(YARD::Tags::Tag.new(:filter, nil, nil, name))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class AddFilterHandler < YARD::Handlers::Ruby::Base
|
||||
handles method_call(:filter)
|
||||
|
||||
process do
|
||||
return unless owner.is_a?(SelectorObject)
|
||||
return if statement.parameters.empty?
|
||||
name = statement.parameters.first.source
|
||||
type = if statement.parameters[1] && statement.parameters[1].source == ':boolean'
|
||||
'Boolean'
|
||||
else
|
||||
nil
|
||||
end
|
||||
if owner.tags(:filter).none? {|tag| tag.name == name }
|
||||
filter_tag = YARD::Tags::Tag.new(:filter, nil, type, name)
|
||||
owner.add_tag(filter_tag)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class FilterSetHandler < YARD::Handlers::Ruby::Base
|
||||
handles method_call(:filter_set)
|
||||
|
||||
process do
|
||||
return unless owner.is_a?(SelectorObject)
|
||||
return if statement.parameters.empty? || !statement.parameters[1]
|
||||
|
||||
names = statement.parameters[1].flatten.map { |name| ":#{name}" }
|
||||
names.each do |name|
|
||||
if owner.tags(:filter).none? {|tag| tag.name == name }
|
||||
filter_tag = YARD::Tags::Tag.new(:filter, nil, nil, name)
|
||||
owner.add_tag(filter_tag)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
1
Rakefile
1
Rakefile
|
@ -2,6 +2,7 @@ require 'rubygems'
|
|||
require 'rspec/core/rake_task'
|
||||
require 'cucumber/rake/task'
|
||||
require 'yard'
|
||||
require_relative './.yard/yard_extensions'
|
||||
|
||||
desc "Run all examples"
|
||||
RSpec::Core::RakeTask.new(:spec) do |t|
|
||||
|
|
|
@ -39,7 +39,6 @@ else
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
def self.feature(*args, &block)
|
||||
options = if args.last.is_a?(Hash) then args.pop else {} end
|
||||
options[:capybara_feature] = true
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
require 'capybara/selector/selector'
|
||||
|
||||
Capybara::Selector::FilterSet.add(:_field) do
|
||||
filter(:checked, :boolean) { |node, value| not(value ^ node.checked?) }
|
||||
filter(:unchecked, :boolean) { |node, value| (value ^ node.checked?) }
|
||||
|
@ -19,18 +18,40 @@ Capybara::Selector::FilterSet.add(:_field) do
|
|||
end
|
||||
end
|
||||
|
||||
#
|
||||
# @locator An XPath expression
|
||||
#
|
||||
Capybara.add_selector(:xpath) do
|
||||
xpath { |xpath| xpath }
|
||||
end
|
||||
|
||||
#
|
||||
# @locator A CSS selector
|
||||
#
|
||||
Capybara.add_selector(:css) do
|
||||
css { |css| css }
|
||||
end
|
||||
|
||||
#
|
||||
# @locator The id of the element to match
|
||||
#
|
||||
Capybara.add_selector(:id) do
|
||||
xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] }
|
||||
end
|
||||
|
||||
#
|
||||
# @locator Matches against the id, name, or placeholder
|
||||
# @filter [String] :id Matches the id attribute
|
||||
# @filter [String] :name Matches the name attribute
|
||||
# @filter [String] :placeholder Matches the placeholder attribute
|
||||
# @filter [String] :type Matches the type attribute of the field or element type for 'textarea' and 'select'
|
||||
# @filter [Boolean] :readonly
|
||||
# @filter [String] :with Matches the current value of the field
|
||||
# @filter [String, Array<String>] :class Matches the class(es) provided
|
||||
# @filter [Boolean] :checked Match checked fields?
|
||||
# @filter [Boolean] :unchecked Match unchecked fields?
|
||||
# @filter [Boolean] :disabled Match disabled field?
|
||||
# @filter [Boolean] :multiple Match fields that accept multiple values
|
||||
Capybara.add_selector(:field) do
|
||||
xpath(:id, :name, :placeholder, :type, :class) do |locator, options|
|
||||
xpath = XPath.descendant(:input, :textarea, :select)[~XPath.attr(:type).one_of('submit', 'image', 'hidden')]
|
||||
|
@ -61,6 +82,13 @@ Capybara.add_selector(:field) do
|
|||
end
|
||||
end
|
||||
|
||||
#
|
||||
# @locator Matches id or contents of wrapped legend
|
||||
#
|
||||
# @filter [String] :id Matches id attribute
|
||||
# @filter [String] :legend Matches contents of wrapped legend
|
||||
# @filter [String, Array<String>] :class Matches the class(es) provided
|
||||
#
|
||||
Capybara.add_selector(:fieldset) do
|
||||
xpath(:id, :legend, :class) do |locator, options|
|
||||
xpath = XPath.descendant(:fieldset)
|
||||
|
@ -71,7 +99,15 @@ Capybara.add_selector(:fieldset) do
|
|||
xpath
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# @locator Matches the id or title attributes, or the string content of the link, or the alt attribute of a contained img element
|
||||
#
|
||||
# @filter [String] :id Matches the id attribute
|
||||
# @filter [String] :title Matches the title attribute
|
||||
# @filter [String] :alt Matches the alt attribute of a contained img element
|
||||
# @filter [String] :class Matches the class(es) provided
|
||||
# @filter [String, Regexp] :href Matches the normalized href of the link
|
||||
#
|
||||
Capybara.add_selector(:link) do
|
||||
xpath(:id, :title, :alt, :class) do |locator, options={}|
|
||||
xpath = XPath.descendant(:a)[XPath.attr(:href)]
|
||||
|
|
|
@ -157,14 +157,15 @@ module Capybara
|
|||
|
||||
##
|
||||
#
|
||||
# Define a non-expression filter for use with this selector
|
||||
# @overload filter(name, *types, options={}, &block)
|
||||
# @param [Symbol] name The filter name
|
||||
# @param [Array<Symbol>] types The types of the filter - currently valid types are [:boolean]
|
||||
# @param [Hash] options ({}) Options of the filter
|
||||
# @option options [Array<>] :valid_values Valid values for this filter
|
||||
# @option options :default The default value of the filter (if any)
|
||||
# @option options :skip_if Value of the filter that will cause it to be skipped
|
||||
# Define a non-expression filter for use with this selector
|
||||
#
|
||||
# @overload filter(name, *types, options={}, &block)
|
||||
# @param [Symbol] name The filter name
|
||||
# @param [Array<Symbol>] types The types of the filter - currently valid types are [:boolean]
|
||||
# @param [Hash] options ({}) Options of the filter
|
||||
# @option options [Array<>] :valid_values Valid values for this filter
|
||||
# @option options :default The default value of the filter (if any)
|
||||
# @option options :skip_if Value of the filter that will cause it to be skipped
|
||||
#
|
||||
def filter(name, *types_and_options, &block)
|
||||
options = types_and_options.last.is_a?(Hash) ? types_and_options.pop.dup : {}
|
||||
|
|
Loading…
Reference in New Issue