Class: Capybara::Selector

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/capybara/selector/selector.rb,
lib/capybara/selector/css.rb,
lib/capybara/selector/filter_set.rb,
lib/capybara/selector/filters/base.rb,
lib/capybara/selector/filters/node_filter.rb,
lib/capybara/selector/regexp_disassembler.rb,
lib/capybara/selector/builders/css_builder.rb,
lib/capybara/selector/builders/xpath_builder.rb,
lib/capybara/selector/filters/locator_filter.rb,
lib/capybara/selector/filters/expression_filter.rb

Overview

## 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: (String, Regexp, XPath::Expression) 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, Regexp, XPath::Expression) — 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>, Regexp, XPath::Expression) — 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, Regexp, XPath::Expression) — Matches id attribute
    * :legend (String) — Matches contents of wrapped legend
    * :class (String, Array<String>, Regexp, XPath::Expression) — 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, Regexp, XPath::Expression) — Matches the id attribute
    * :title (String) — Matches the title attribute
    * :alt (String) — Matches the alt attribute of a contained img element
    * :class (String, Array<String>, Regexp, XPath::Expression) — 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, Regexp, XPath::Expression) — Matches the id attribute
    * :title (String) — Matches the title attribute
    * :class (String, Array<String>, Regexp, XPath::Expression) — 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, Regexp, XPath::Expression) — 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>, Regexp, XPath::Expression) — 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, Regexp, XPath::Expression) — Matches the id attribute
    * :name (String) — Matches the name attribute
    * :class (String, Array<String>, Regexp, XPath::Expression) — 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, Regexp, XPath::Expression) — Matches the id attribute
    * *:name (String) — Matches the name attribute
    * *:class (String, Array<String>, Regexp, XPath::Expression) — 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, Regexp, XPath::Expression) — Matches the id attribute
    * :name (String) — Matches the name attribute
    * :placeholder (String) — Matches the placeholder attribute
    * :class (String, Array<String>, Regexp, XPath::Expression) — 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, Regexp, XPath::Expression) — Matches the id attribute
    * :name (String) — Matches the name attribute
    * :class (String, Array<String>, Regexp, XPath::Expression) — 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, Regexp, XPath::Expression) — Match id attribute of table
    * :caption (String) — Match text of associated caption
    * :class ((String, Array<String>, Regexp, XPath::Expression) — Matches the class(es) provided

* **:frame** - Find frame/iframe elements
  * Locator: Match id or name
  * Filters:
    * :id (String, Regexp, XPath::Expression) — Match id attribute
    * :name (String) — Match name attribute
    * :class (String, Array<String>, Regexp, XPath::Expression) — Matches the class(es) provided

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

Defined Under Namespace

Modules: Filters Classes: CSS, CSSBuilder, FilterSet, RegexpDisassembler, XPathBuilder

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, &block) ⇒ Selector

Returns a new instance of Selector



193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/capybara/selector/selector.rb', line 193

def initialize(name, &block)
  @name = name
  @filter_set = FilterSet.add(name) {}
  @match = nil
  @label = nil
  @failure_message = nil
  @format = nil
  @expression = nil
  @expression_filters = {}
  @locator_filter = nil
  @default_visibility = nil
  @config = {
    enable_aria_label: false,
    test_id: nil
  }
  instance_eval(&block)
end

Instance Attribute Details

#formatObject (readonly)

Returns the value of attribute format



164
165
166
# File 'lib/capybara/selector/selector.rb', line 164

def format
  @format
end

#nameObject (readonly)

Returns the value of attribute name



164
165
166
# File 'lib/capybara/selector/selector.rb', line 164

def name
  @name
end

Class Method Details

.[](name) ⇒ Object



172
173
174
# File 'lib/capybara/selector/selector.rb', line 172

def [](name)
  all.fetch(name.to_sym) { |sel_type| raise ArgumentError, "Unknown selector type (:#{sel_type})" }
end

.add(name, &block) ⇒ Object



176
177
178
# File 'lib/capybara/selector/selector.rb', line 176

def add(name, &block)
  all[name.to_sym] = Capybara::Selector.new(name.to_sym, &block)
end

.allObject



168
169
170
# File 'lib/capybara/selector/selector.rb', line 168

def all
  @selectors ||= {} # rubocop:disable Naming/MemoizedInstanceVariableName
end

.for(locator) ⇒ Object



188
189
190
# File 'lib/capybara/selector/selector.rb', line 188

def for(locator)
  all.values.find { |sel| sel.match?(locator) }
end

.remove(name) ⇒ Object



184
185
186
# File 'lib/capybara/selector/selector.rb', line 184

def remove(name)
  all.delete(name.to_sym)
end

.update(name, &block) ⇒ Object



180
181
182
# File 'lib/capybara/selector/selector.rb', line 180

def update(name, &block)
  self[name].instance_eval(&block)
end

Instance Method Details

#add_error(error_msg) ⇒ Object



407
408
409
# File 'lib/capybara/selector/selector.rb', line 407

def add_error(error_msg)
  errors << error_msg
end

#builder(expr = nil) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



412
413
414
415
416
417
418
419
420
421
# File 'lib/capybara/selector/selector.rb', line 412

def builder(expr = nil)
  case format
  when :css
    Capybara::Selector::CSSBuilder
  when :xpath
    Capybara::Selector::XPathBuilder
  else
    raise NotImplementedError, "No builder exists for selector of type #{format}"
  end.new(expr)
end

#call(locator, selector_config: {}, **options) ⇒ Object



297
298
299
300
301
302
303
304
# File 'lib/capybara/selector/selector.rb', line 297

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(*expression_filters) {|locator, options| ... } ⇒ #call #css#call

Define a selector by a CSS selector

Overloads:

  • #css(*expression_filters) {|locator, options| ... } ⇒ #call

    Parameters:

    • expression_filters (Array<Symbol>)

      ([]) Names of filters that can be implemented via this CSS selector

    Yields:

    • (locator, options)

      The block to use to generate the CSS selector

    Yield Parameters:

    • locator (String)

      The locator string passed to the query

    • options (Hash)

      The options hash passed to the query

    Yield Returns:

    • (#to_s)

      An object that can produce a CSS selector

Returns:

  • (#call)

    The block that will be called to generate the CSS selector



256
257
258
# File 'lib/capybara/selector/selector.rb', line 256

def css(*allowed_filters, &block)
  expression(:css, allowed_filters, &block)
end

#custom_filtersObject



211
212
213
214
# File 'lib/capybara/selector/selector.rb', line 211

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, options = {}) ⇒ Object



398
399
400
401
402
403
404
405
# File 'lib/capybara/selector/selector.rb', line 398

def default_visibility(fallback = Capybara.ignore_hidden_elements, options = {})
  vis = if @default_visibility&.respond_to?(:call)
    @default_visibility.call(options)
  else
    @default_visibility
  end
  vis.nil? ? fallback : vis
end

#describe_expression_filters(&block) ⇒ Object



371
372
373
374
375
376
377
378
379
# File 'lib/capybara/selector/selector.rb', line 371

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) ⇒ Object



381
382
383
# File 'lib/capybara/selector/selector.rb', line 381

def describe_node_filters(&block)
  describe(:node_filters, &block)
end

#description(options) ⇒ String

Returns Description of the selector when used with the options passed

Parameters:

  • options (Hash)

    The options of the query used to generate the description

Returns:

  • (String)

    Description of the selector when used with the options passed



295
# File 'lib/capybara/selector/selector.rb', line 295

def_delegator :@filter_set, :description

#expression_filter(name, *types, matcher: nil, **options, &block) ⇒ Object

Parameters:

  • name (Symbol, Regexp)

    The filter name

  • matcher (Regexp)

    (nil) A Regexp used to check whether a specific option is handled by this filter

  • types (Array<Symbol>)

    The types of the filter - currently valid types are [:boolean]

  • options (Hash)

    ({}) Options of the filter

Options Hash (**options):

  • :valid_values (Array<>)

    Valid values for this filter

  • :default (Object)

    The default value of the filter (if any)

  • :skip_if (Object)

    Value of the filter that will cause it to be skipped

  • :matcher (Regexp) — default: nil

    A Regexp used to check whether a specific option is handled by this filter. If not provided the filter will be used for options matching the filter name.



357
# File 'lib/capybara/selector/selector.rb', line 357

def_delegators :@filter_set, :node_filter, :expression_filter, :filter

#expression_filtersObject



220
221
222
# File 'lib/capybara/selector/selector.rb', line 220

def expression_filters
  @filter_set.expression_filters
end

#filterObject



# File 'lib/capybara/selector/selector.rb', line 336

#filter_set(name, filters_to_use = nil) ⇒ Object



365
366
367
# File 'lib/capybara/selector/selector.rb', line 365

def filter_set(name, filters_to_use = nil)
  @filter_set.import(name, filters_to_use)
end

#label(label) ⇒ String #labelString

Set/get a descriptive label for the selector

Overloads:

  • #label(label) ⇒ String

    Parameters:

    • label (String)

      A descriptive label for this selector - used in error messages

Returns:

  • (String)

    The currently set label



283
284
285
286
# File 'lib/capybara/selector/selector.rb', line 283

def label(label = nil)
  @label = label if label
  @label
end

#locator_filter(*types, **options, &block) ⇒ Object



359
360
361
362
363
# File 'lib/capybara/selector/selector.rb', line 359

def locator_filter(*types, **options, &block)
  types.each { |type| options[type] = true }
  @locator_filter = Filters::LocatorFilter.new(block, options) if block
  @locator_filter
end

#match {|locator| ... } ⇒ #call

Automatic selector detection

Yields:

  • (locator)

    This block takes the passed in locator string and returns whether or not it matches the selector

Yield Parameters:

  • , (String)

    locator The locator string used to determin if it matches the selector

Yield Returns:

  • (Boolean)

    Whether this selector matches the locator string

Returns:

  • (#call)

    The block that will be used to detect selector match



269
270
271
272
# File 'lib/capybara/selector/selector.rb', line 269

def match(&block)
  @match = block if block
  @match
end

#match?(locator) ⇒ Boolean

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

Parameters:

  • locator (String)

    The locator passed to the query

Returns:

  • (Boolean)

    Whether or not to use this selector



315
316
317
# File 'lib/capybara/selector/selector.rb', line 315

def match?(locator)
  @match&.call(locator)
end

#node_filter(name, *types, options = {}, &block) ⇒ Object

Parameters:

  • name (Symbol, Regexp)

    The filter name

  • types (Array<Symbol>)

    The types of the filter - currently valid types are [:boolean]

  • options (Hash) (defaults to: {})

    ({}) Options of the filter

Options Hash (options):

  • :valid_values (Array<>)

    Valid values for this filter

  • :default (Object)

    The default value of the filter (if any)

  • :skip_if (Object)

    Value of the filter that will cause it to be skipped

  • :matcher (Regexp) — default: nil

    A Regexp used to check whether a specific option is handled by this filter. If not provided the filter will be used for options matching the filter name.



# File 'lib/capybara/selector/selector.rb', line 319

#node_filtersObject



216
217
218
# File 'lib/capybara/selector/selector.rb', line 216

def node_filters
  @filter_set.node_filters
end

#visible(default_visibility = nil, &block) ⇒ Object

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

Parameters:

  • default_visibility (Symbol) (defaults to: nil)

    Only find elements with the specified visibility:

    • :all - finds visible and invisible elements.

    • :hidden - only finds invisible elements.

    • :visible - only finds visible elements.



394
395
396
# File 'lib/capybara/selector/selector.rb', line 394

def visible(default_visibility = nil, &block)
  @default_visibility = block || default_visibility
end

#with_filter_errors(errors) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



424
425
426
427
428
429
# File 'lib/capybara/selector/selector.rb', line 424

def with_filter_errors(errors)
  Thread.current["capybara_#{object_id}_errors"] = errors
  yield
ensure
  Thread.current["capybara_#{object_id}_errors"] = nil
end

#xpath(*expression_filters) {|locator, options| ... } ⇒ #call #xpath#call

Define a selector by an xpath expression

Overloads:

  • #xpath(*expression_filters) {|locator, options| ... } ⇒ #call

    Parameters:

    • expression_filters (Array<Symbol>)

      ([]) Names of filters that are implemented via this expression, if not specified the names of any keyword parameters in the block will be used

    Yields:

    • (locator, options)

      The block to use to generate the XPath expression

    Yield Parameters:

    • locator (String)

      The locator string passed to the query

    • options (Hash)

      The options hash passed to the query

    Yield Returns:

    • (#to_xpath, #to_s)

      An object that can produce an xpath expression

Returns:

  • (#call)

    The block that will be called to generate the XPath expression



238
239
240
# File 'lib/capybara/selector/selector.rb', line 238

def xpath(*allowed_filters, &block)
  expression(:xpath, allowed_filters, &block)
end