class Capybara::Selector

## 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, Capybara.test_id attribute, 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<String>) — 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<String>) — Matches the class(es) provided

* **:link** - Find links ( <a> 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 <a> elements with no href attribute

* **:button** - Find buttons ( input [of type submit, reset, image, button] or button elements )
  * Locator: Matches the id, Capybara.test_id attribute, 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, Capybara.test_id attribute, 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<String>) — 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, Capybara.test_id attribute, name, or associated label text
  * Filters:
    * :id (String) — Matches the id attribute
    * :name (String) — Matches the name attribute
    * :class (String, Array<String>) — 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, Capybara.test_id attribute, name, or associated label text
  * Filters:
    * *:id (String) — Matches the id attribute
    * *:name (String) — Matches the name attribute
    * *:class (String, Array<String>) — 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, Capybara.test_id attribute, 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<String>) — Matches the class(es) provided
    * :disabled (Boolean) — Match disabled field?
    * :multiple (Boolean) — Match fields that accept multiple values
    * :options (Array<String>) — Exact match options
    * :with_options (Array<String>) — Partial match options
    * :selected (String, Array<String>) — Match the selection(s)
    * :with_selected (String, Array<String>) — 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, Capybara.test_id attribute, name, or associated label text
  * Filters:
    * :id (String) — Matches the id attribute
    * :name (String) — Matches the name attribute
    * :class (String, Array<String>) — 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<String>) — 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<String>) — Matches the class(es) provided

* **:element**
  * Locator: Type of element ('div', 'a', etc) - if not specified defaults to '*'
  * Filters: Matches on any element attribute

Attributes

format[R]
name[R]

Public Class Methods

add(name, &block) click to toggle source
# File lib/capybara/selector/selector.rb, line 168
def add(name, &block)
  all[name.to_sym] = Capybara::Selector.new(name.to_sym, &block)
end
all() click to toggle source
# File lib/capybara/selector/selector.rb, line 164
def all
  @selectors ||= {} # rubocop:disable Naming/MemoizedInstanceVariableName
end
new(name, &block) click to toggle source
# File lib/capybara/selector/selector.rb, line 181
def initialize(name, &block)
  @name = name
  @filter_set = FilterSet.add(name) {}
  @match = nil
  @label = nil
  @failure_message = nil
  @format = nil
  @expression = nil
  @expression_filters = {}
  @default_visibility = nil
  @config = {
    enable_aria_label: false,
    test_id: nil
  }
  instance_eval(&block)
end
remove(name) click to toggle source
# File lib/capybara/selector/selector.rb, line 176
def remove(name)
  all.delete(name.to_sym)
end
update(name, &block) click to toggle source
# File lib/capybara/selector/selector.rb, line 172
def update(name, &block)
  all[name.to_sym].instance_eval(&block)
end

Public Instance Methods

@filter_set() click to toggle source

Description of the selector

@!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
# File lib/capybara/selector/selector.rb, line 290
def_delegator :@filter_set, :description
call(locator, selector_config: {}, **options) click to toggle source
# File lib/capybara/selector/selector.rb, line 292
def call(locator, selector_config: {}, **options)
  @config.merge! selector_config
  if format
    @expression.call(locator, options)
  else
    warn 'Selector has no format'
  end
end
css(*allowed_filters, &block) click to toggle source

Define a selector by a CSS selector

@overload css(*expression_filters, &block)

@param [Array<Symbol>] expression_filters ([])  Names of filters that can be implemented via this CSS selector
@yield [locator, options]                   The block to use to generate the CSS selector
@yieldparam [String] locator               The locator string passed to the query
@yieldparam [Hash] options                 The options hash passed to the query
@yieldreturn [#to_s]                        An object that can produce a CSS selector

@overload css() @return [#call] The block that will be called to generate the CSS selector

# File lib/capybara/selector/selector.rb, line 247
def css(*allowed_filters, &block)
  if block
    @format, @expression = :css, block
    allowed_filters.flatten.each { |ef| expression_filters[ef] = nil }
  end
  format == :css ? @expression : nil
end
custom_filters() click to toggle source
# File lib/capybara/selector/selector.rb, line 198
def custom_filters
  warn "Deprecated: Selector#custom_filters is not valid when same named expression and node filter exist - don't use"
  node_filters.merge(expression_filters).freeze
end
default_visibility(fallback = Capybara.ignore_hidden_elements) click to toggle source
# File lib/capybara/selector/selector.rb, line 387
def default_visibility(fallback = Capybara.ignore_hidden_elements)
  return @default_visibility unless @default_visibility.nil?
  fallback
end
describe_expression_filters(&block) click to toggle source
# File lib/capybara/selector/selector.rb, line 360
def describe_expression_filters(&block)
  if block_given?
    describe(:expression_filters, &block)
  else
    describe(:expression_filters) do |**options|
      describe_all_expression_filters(options)
    end
  end
end
describe_node_filters(&block) click to toggle source
# File lib/capybara/selector/selector.rb, line 370
def describe_node_filters(&block)
  describe(:node_filters, &block)
end
expression_filters() click to toggle source
# File lib/capybara/selector/selector.rb, line 207
def expression_filters
  @filter_set.expression_filters
end
filter_set(name, filters_to_use = nil) click to toggle source
# File lib/capybara/selector/selector.rb, line 354
def filter_set(name, filters_to_use = nil)
  @filter_set.import(name, filters_to_use)
end
label(label = nil) click to toggle source

Set/get a descriptive label for the selector

@overload label(label)

@param [String] label            A descriptive label for this selector - used in error messages

@overload label() @return [String] The currently set label

# File lib/capybara/selector/selector.rb, line 278
def label(label = nil)
  @label = label if label
  @label
end
match(&block) click to toggle source

Automatic selector detection

@yield [locator] This block takes the passed in locator string and returns whether or not it matches the selector @yieldparam [String], locator The locator string used to determin if it matches the selector @yieldreturn [Boolean] Whether this selector matches the locator string @return [#call] The block that will be used to detect selector match

# File lib/capybara/selector/selector.rb, line 264
def match(&block)
  @match = block if block
  @match
end
match?(locator) click to toggle source
Should this selector be used for the passed in locator

This is used by the automatic selector selection mechanism when no selector type is passed to a selector query

@param [String] locator The locator passed to the query @return [Boolean] Whether or not to use this selector

# File lib/capybara/selector/selector.rb, line 310
def match?(locator)
  @match&.call(locator)
end
node_filters() click to toggle source
# File lib/capybara/selector/selector.rb, line 203
def node_filters
  @filter_set.node_filters
end
visible(default_visibility) click to toggle source

Set the default visibility mode that shouble be used if no visibile option is passed when using the selector. If not specified will default to the behavior indicated by Capybara.ignore_hidden_elements

@param [Symbol] #default_visibility Only find elements with the specified visibility:

* :all - finds visible and invisible elements.
* :hidden - only finds invisible elements.
* :visible - only finds visible elements.
# File lib/capybara/selector/selector.rb, line 383
def visible(default_visibility)
  @default_visibility = default_visibility
end
xpath(*allowed_filters, &block) click to toggle source

Define a selector by an xpath expression

@overload xpath(*expression_filters, &block)

@param [Array<Symbol>] expression_filters ([])  Names of filters that can be implemented via this expression
@yield [locator, options]                       The block to use to generate the XPath expression
@yieldparam [String] locator                    The locator string passed to the query
@yieldparam [Hash] options                      The options hash passed to the query
@yieldreturn [#to_xpath, #to_s]                 An object that can produce an xpath expression

@overload xpath() @return [#call] The block that will be called to generate the XPath expression

# File lib/capybara/selector/selector.rb, line 225
def xpath(*allowed_filters, &block)
  if block
    @format, @expression = :xpath, block
    allowed_filters.flatten.each { |ef| expression_filters[ef] = Filters::IdentityExpressionFilter.new(ef) }
  end
  format == :xpath ? @expression : nil
end

Private Instance Methods

describe_all_expression_filters(**opts) click to toggle source
# File lib/capybara/selector/selector.rb, line 417
def describe_all_expression_filters(**opts)
  expression_filters.map do |ef_name, ef|
    if ef.matcher?
      opts.keys.map do |key|
        " with #{ef_name}[#{key} => #{opts[key]}]" if ef.handles_option?(key) && !::Capybara::Queries::SelectorQuery::VALID_KEYS.include?(key)
      end.join
    elsif opts.key?(ef_name)
      " with #{ef_name} #{opts[ef_name]}"
    end
  end.join
end
enable_aria_label() click to toggle source
# File lib/capybara/selector/selector.rb, line 394
def enable_aria_label
  @config[:enable_aria_label]
end
find_by_attr(attribute, value) click to toggle source
# File lib/capybara/selector/selector.rb, line 429
def find_by_attr(attribute, value)
  finder_name = "find_by_#{attribute}_attr"
  if respond_to?(finder_name, true)
    send(finder_name, value)
  else
    value ? XPath.attr(attribute) == value : nil
  end
end
find_by_class_attr(classes) click to toggle source
# File lib/capybara/selector/selector.rb, line 438
def find_by_class_attr(classes)
  Array(classes).map { |klass| XPath.attr(:class).contains_word(klass) }.reduce(:&)
end
locate_field(xpath, locator, **_options) click to toggle source
# File lib/capybara/selector/selector.rb, line 402
def locate_field(xpath, locator, **_options)
  return xpath if locator.nil?
  locate_xpath = xpath # Need to save original xpath for the label wrap
  locator = locator.to_s
  attr_matchers = [XPath.attr(:id) == locator,
                   XPath.attr(:name) == locator,
                   XPath.attr(:placeholder) == locator,
                   XPath.attr(:id) == XPath.anywhere(:label)[XPath.string.n.is(locator)].attr(:for)].reduce(:|)
  attr_matchers |= XPath.attr(:'aria-label').is(locator) if enable_aria_label
  attr_matchers |= XPath.attr(test_id) == locator if test_id

  locate_xpath = locate_xpath[attr_matchers]
  locate_xpath + XPath.descendant(:label)[XPath.string.n.is(locator)].descendant(xpath)
end
test_id() click to toggle source
# File lib/capybara/selector/selector.rb, line 398
def test_id
  @config[:test_id]
end