diff --git a/.yard/templates_custom/default/class/html/selectors.erb b/.yard/templates_custom/default/class/html/selectors.erb deleted file mode 100644 index 8180ec21..00000000 --- a/.yard/templates_custom/default/class/html/selectors.erb +++ /dev/null @@ -1,38 +0,0 @@ -
-

Built-in Selectors

- -
diff --git a/.yard/templates_custom/default/class/html/setup.rb b/.yard/templates_custom/default/class/html/setup.rb deleted file mode 100644 index 91fbec56..00000000 --- a/.yard/templates_custom/default/class/html/setup.rb +++ /dev/null @@ -1,17 +0,0 @@ -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 \ No newline at end of file diff --git a/.yard/yard_extensions.rb b/.yard/yard_extensions.rb deleted file mode 100644 index cc5bbbd2..00000000 --- a/.yard/yard_extensions.rb +++ /dev/null @@ -1,78 +0,0 @@ -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 - 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 diff --git a/.yardopts b/.yardopts deleted file mode 100644 index 6b4ed802..00000000 --- a/.yardopts +++ /dev/null @@ -1 +0,0 @@ ---load ./.yard/yard_extensions.rb diff --git a/lib/capybara/selector.rb b/lib/capybara/selector.rb index 8a89fd7e..f375b851 100644 --- a/lib/capybara/selector.rb +++ b/lib/capybara/selector.rb @@ -26,52 +26,18 @@ end # rubocop:disable Metrics/BlockLength # rubocop:disable Metrics/ParameterLists -## -# -# Select elements by XPath expression -# -# @locator An XPath expression -# Capybara.add_selector(:xpath) do xpath { |xpath| xpath } end -## -# -# Select elements by CSS selector -# -# @locator A CSS selector -# Capybara.add_selector(:css) do css { |css| css } end -## -# -# Select element by id -# -# @locator The id of the element to match -# Capybara.add_selector(:id) do xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] } end -## -# -# Select field elements (input [not of type submit, image, or hidden], textarea, select) -# -# @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] :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 do |locator, **options| xpath = XPath.descendant(:input, :textarea, :select)[!XPath.attr(:type).one_of('submit', 'image', 'hidden')] @@ -102,16 +68,6 @@ Capybara.add_selector(:field) do end end -## -# -# Select fieldset elements -# -# @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] :class Matches the class(es) provided -# Capybara.add_selector(:fieldset) do xpath(:legend) do |locator, legend: nil, **_options| xpath = XPath.descendant(:fieldset) @@ -121,18 +77,6 @@ Capybara.add_selector(:fieldset) do end end -## -# -# Find links ( elements with an href attribute ) -# -# @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,nil] :href Matches the normalized href of the link, if nil will find elements with no href attribute -# Capybara.add_selector(:link) do xpath(:title, :alt) do |locator, href: true, enable_aria_label: false, alt: nil, title: nil, **_options| xpath = XPath.descendant(:a) @@ -176,17 +120,6 @@ Capybara.add_selector(:link) do end end -## -# -# Find buttons ( input [of type submit, reset, image, button] or button elements ) -# -# @locator Matches the id, value, or title attributes, string content of a button, or the alt attribute of an image type button or of a descendant image of a button -# -# @filter [String] :id Matches the id attribute -# @filter [String] :title Matches the title attribute -# @filter [String] :class Matches the class(es) provided -# @filter [String] :value Matches the value of an input button -# Capybara.add_selector(:button) do xpath(:value, :title, :type) do |locator, enable_aria_label: false, **options| input_btn_xpath = XPath.descendant(:input)[XPath.attr(:type).one_of('submit', 'reset', 'image', 'button')] @@ -224,10 +157,6 @@ Capybara.add_selector(:button) do end end -## -# -# Find links or buttons -# Capybara.add_selector(:link_or_button) do label "link or button" xpath do |locator, **options| @@ -239,20 +168,6 @@ Capybara.add_selector(:link_or_button) do describe { |disabled: nil, **_options| " that is disabled" if disabled == true } end -## -# -# Find text fillable fields ( textarea, input [not of type submit, image, radio, checkbox, hidden, file] ) -# -# @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] :with Matches the current value of the field -# @filter [String] :type Matches the type attribute of the field or element type for 'textarea' -# @filter [String, Array] :class Matches the class(es) provided -# @filter [Boolean] :disabled Match disabled field? -# @filter [Boolean] :multiple Match fields that accept multiple values -# Capybara.add_selector(:fillable_field) do label "field" @@ -284,19 +199,6 @@ Capybara.add_selector(:fillable_field) do end end -## -# -# Find radio buttons -# -# @locator Match id, name, or associated label text -# @filter [String] :id Matches the id attribute -# @filter [String] :name Matches the name attribute -# @filter [String, Array] :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 [String] :option Match the value -# Capybara.add_selector(:radio_button) do label "radio button" @@ -317,19 +219,6 @@ Capybara.add_selector(:radio_button) do end end -## -# -# Find checkboxes -# -# @locator Match id, name, or associated label text -# @filter [String] :id Matches the id attribute -# @filter [String] :name Matches the name attribute -# @filter [String, Array] :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 [String] :option Match the value -# Capybara.add_selector(:checkbox) do xpath do |locator, **options| xpath = XPath.descendant(:input)[XPath.attr(:type) == 'checkbox'] @@ -348,22 +237,6 @@ Capybara.add_selector(:checkbox) do end end -## -# -# Find select elements -# -# @locator Match id, name, placeholder, or associated label text -# @filter [String] :id Matches the id attribute -# @filter [String] :name Matches the name attribute -# @filter [String] :placeholder Matches the placeholder attribute -# @filter [String, Array] :class Matches the class(es) provided -# @filter [Boolean] :disabled Match disabled field? -# @filter [Boolean] :multiple Match fields that accept multiple values -# @filter [Array] :options Exact match options -# @filter [Array] :with_options Partial match options -# @filter [String, Array] :selected Match the selection(s) -# @filter [String, Array] :with_selected Partial match the selection(s) -# Capybara.add_selector(:select) do label "select box" @@ -440,14 +313,6 @@ Capybara.add_selector(:datalist_input) do end end -## -# -# Find option elements -# -# @locator Match text of option -# @filter [Boolean] :disabled Match disabled option -# @filter [Boolean] :selected Match selected option -# Capybara.add_selector(:option) do xpath do |locator| xpath = XPath.descendant(:option) @@ -485,17 +350,6 @@ Capybara.add_selector(:datalist_option) do end end -## -# -# Find file input elements -# -# @locator Match id, name, or associated label text -# @filter [String] :id Matches the id attribute -# @filter [String] :name Matches the name attribute -# @filter [String, Array] :class Matches the class(es) provided -# @filter [Boolean] :disabled Match disabled field? -# @filter [Boolean] :multiple Match field that accepts multiple values -# Capybara.add_selector(:file_field) do label "file field" xpath do |locator, options| @@ -512,13 +366,6 @@ Capybara.add_selector(:file_field) do end end -## -# -# Find label elements -# -# @locator Match id or text contents -# @filter [Element, String] :for The element or id of the element associated with the label -# Capybara.add_selector(:label) do label "label" xpath(:for) do |locator, options| @@ -553,15 +400,6 @@ Capybara.add_selector(:label) do end end -## -# -# Find table elements -# -# @locator id or caption text of table -# @filter [String] :id Match id attribute of table -# @filter [String] :caption Match text of associated caption -# @filter [String, Array] :class Matches the class(es) provided -# Capybara.add_selector(:table) do xpath(:caption) do |locator, caption: nil, **_options| xpath = XPath.descendant(:table) @@ -577,15 +415,6 @@ Capybara.add_selector(:table) do end end -## -# -# Find frame/iframe elements -# -# @locator Match id or name -# @filter [String] :id Match id attribute -# @filter [String] :name Match name attribute -# @filter [String, Array] :class Matches the class(es) provided -# Capybara.add_selector(:frame) do xpath(:name) do |locator, **options| xpath = XPath.descendant(:iframe).union(XPath.descendant(:frame)) diff --git a/lib/capybara/selector/selector.rb b/lib/capybara/selector/selector.rb index dff16174..afdc0d6a 100644 --- a/lib/capybara/selector/selector.rb +++ b/lib/capybara/selector/selector.rb @@ -4,6 +4,157 @@ require 'capybara/selector/filter_set' require 'capybara/selector/css' module Capybara + # + # ## Built-in Selectors + # + # * **:xpath** - Select elements by XPath expression + # * Locator: An XPath expression + # + # * **:css** - Select elements by CSS selector + # * Locator: A CSS selector + # + # * **:id** - Select element by id + # * Locator: The id of the element to match + # + # * **:field** - Select field elements (input [not of type submit, image, or hidden], textarea, select) + # * Locator: Matches against the id, name, or placeholder + # * Filters: + # * :id (String) — Matches the id attribute + # * :name (String) — Matches the name attribute + # * :placeholder (String) — Matches the placeholder attribute + # * :type (String) — Matches the type attribute of the field or element type for 'textarea' and 'select' + # * :readonly (Boolean) + # * :with (String) — Matches the current value of the field + # * :class (String, Array) — Matches the class(es) provided + # * :checked (Boolean) — Match checked fields? + # * :unchecked (Boolean) — Match unchecked fields? + # * :disabled (Boolean) — Match disabled field? + # * :multiple (Boolean) — Match fields that accept multiple values + # + # * **:fieldset** - Select fieldset elements + # * Locator: Matches id or contents of wrapped legend + # * Filters: + # * :id (String) — Matches id attribute + # * :legend (String) — Matches contents of wrapped legend + # * :class (String, Array) — Matches the class(es) provided + # + # * **:link** - Find links ( elements with an href attribute ) + # * Locator: Matches the id or title attributes, or the string content of the link, or the alt attribute of a contained img element + # * Filters: + # * :id (String) — Matches the id attribute + # * :title (String) — Matches the title attribute + # * :alt (String) — Matches the alt attribute of a contained img element + # * :class (String) — Matches the class(es) provided + # * :href (String, Regexp, nil) — Matches the normalized href of the link, if nil will find elements with no href attribute + # + # * **:button** - Find buttons ( input [of type submit, reset, image, button] or button elements ) + # * Locator: Matches the id, value, or title attributes, string content of a button, or the alt attribute of an image type button or of a descendant image of a button + # * Filters: + # * :id (String) — Matches the id attribute + # * :title (String) — Matches the title attribute + # * :class (String) — Matches the class(es) provided + # * :value (String) — Matches the value of an input button + # * :type + # + # * **:link_or_button** - Find links or buttons + # * Locator: See :link and :button selectors + # + # * **:fillable_field** - Find text fillable fields ( textarea, input [not of type submit, image, radio, checkbox, hidden, file] ) + # * Locator: Matches against the id, name, or placeholder + # * Filters: + # * :id (String) — Matches the id attribute + # * :name (String) — Matches the name attribute + # * :placeholder (String) — Matches the placeholder attribute + # * :with (String) — Matches the current value of the field + # * :type (String) — Matches the type attribute of the field or element type for 'textarea' + # * :class (String, Array) — Matches the class(es) provided + # * :disabled (Boolean) — Match disabled field? + # * :multiple (Boolean) — Match fields that accept multiple values + # + # * **:radio_button** - Find radio buttons + # * Locator: Match id, name, or associated label text + # * Filters: + # * :id (String) — Matches the id attribute + # * :name (String) — Matches the name attribute + # * :class (String, Array) — Matches the class(es) provided + # * :checked (Boolean) — Match checked fields? + # * :unchecked (Boolean) — Match unchecked fields? + # * :disabled (Boolean) — Match disabled field? + # * :option (String) — Match the value + # + # * **:checkbox** - Find checkboxes + # * Locator: Match id, name, or associated label text + # * Filters: + # * *:id (String) — Matches the id attribute + # * *:name (String) — Matches the name attribute + # * *:class (String, Array) — Matches the class(es) provided + # * *:checked (Boolean) — Match checked fields? + # * *:unchecked (Boolean) — Match unchecked fields? + # * *:disabled (Boolean) — Match disabled field? + # * *:option (String) — Match the value + # + # * **:select** - Find select elements + # * Locator: Match id, name, placeholder, or associated label text + # * Filters: + # * :id (String) — Matches the id attribute + # * :name (String) — Matches the name attribute + # * :placeholder (String) — Matches the placeholder attribute + # * :class (String, Array) — Matches the class(es) provided + # * :disabled (Boolean) — Match disabled field? + # * :multiple (Boolean) — Match fields that accept multiple values + # * :options (Array) — Exact match options + # * :with_options (Array) — Partial match options + # * :selected (String, Array) — Match the selection(s) + # * :with_selected (String, Array) — Partial match the selection(s) + # + # * **:option** - Find option elements + # * Locator: Match text of option + # * Filters: + # * :disabled (Boolean) — Match disabled option + # * :selected (Boolean) — Match selected option + # + # * **:datalist_input** + # * Locator: + # * Filters: + # * :disabled + # * :name + # * :placeholder + # + # * **:datalist_option** + # * Locator: + # + # * **:file_field** - Find file input elements + # * Locator: Match id, name, or associated label text + # * Filters: + # * :id (String) — Matches the id attribute + # * :name (String) — Matches the name attribute + # * :class (String, Array) — Matches the class(es) provided + # * :disabled (Boolean) — Match disabled field? + # * :multiple (Boolean) — Match field that accepts multiple values + # + # * **:label** - Find label elements + # * Locator: Match id or text contents + # * Filters: + # * :for (Element, String) — The element or id of the element associated with the label + # + # * **:table** - Find table elements + # * Locator: id or caption text of table + # * Filters: + # * :id (String) — Match id attribute of table + # * :caption (String) — Match text of associated caption + # * :class (String, Array) — Matches the class(es) provided + # + # * **:frame** - Find frame/iframe elements + # * Locator: Match id or name + # * Filters: + # * :id (String) — Match id attribute + # * :name (String) — Match name attribute + # * :class (String, Array) — Matches the class(es) provided + # + # * **:element** + # * Locator: Type of element ('div', 'a', etc) - if not specified defaults to '*' + # * Filters: Matches on any element attribute + # class Selector attr_reader :name, :format extend Forwardable @@ -129,14 +280,10 @@ module Capybara # # Description of the selector # - # @param [Hash] options The options of the query used to generate the description - # @return [String] Description of the selector when used with the options passed - # - + # @!method description(options) + # @param [Hash] options The options of the query used to generate the description + # @return [String] Description of the selector when used with the options passed def_delegator :@filter_set, :description - def description(**options) - @filter_set.description(options) - end def call(locator, **options) if format @@ -163,7 +310,7 @@ module Capybara # # Define a node filter for use with this selector # - # @overload filter(name, *types, options={}, &block) + # @!method node_filter(name, *types, options={}, &block) # @param [Symbol, Regexp] name The filter name # @param [Array] types The types of the filter - currently valid types are [:boolean] # @param [Hash] options ({}) Options of the filter @@ -176,11 +323,14 @@ module Capybara # is passed for the name the block should accept | node, option_name, option_value |. In either case # the block should return `true` if the node passes the filer or `false` if it doesn't + # @!method filter + # See {Selector#node_filter} + ## # # Define an expression filter for use with this selector # - # @overload expression_filter(name, *types, options={}, &block) + # @!method expression_filter(name, *types, options={}, &block) # @param [Symbol, Regexp] name The filter name # @param [Regexp] matcher (nil) A Regexp used to check whether a specific option is handled by this filter # @param [Array] types The types of the filter - currently valid types are [:boolean]