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) 

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, locator_type: nil, raw_locator: false, &block) ⇒ Selector

Returns a new instance of Selector.



204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/capybara/selector/selector.rb', line 204

def initialize(name, locator_type: nil, raw_locator: false, &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
  @locator_type = locator_type
  @raw_locator = raw_locator
  @config = {
    enable_aria_label: false,
    test_id: nil
  }
  instance_eval(&block)
end

Instance Attribute Details

#formatObject (readonly)

Returns the value of attribute format.



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

def format
  @format
end

#nameObject (readonly)

Returns the value of attribute name.



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

def name
  @name
end

Class Method Details

.[](name) ⇒ Object



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

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

.add(name, **options, &block) ⇒ Object



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

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

.allObject



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

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

.for(locator) ⇒ Object



199
200
201
# File 'lib/capybara/selector/selector.rb', line 199

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

.remove(name) ⇒ Object



195
196
197
# File 'lib/capybara/selector/selector.rb', line 195

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

.update(name, &block) ⇒ Object



191
192
193
# File 'lib/capybara/selector/selector.rb', line 191

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

Instance Method Details

#add_error(error_msg) ⇒ Object



422
423
424
# File 'lib/capybara/selector/selector.rb', line 422

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.



427
428
429
430
431
432
433
434
435
436
# File 'lib/capybara/selector/selector.rb', line 427

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



310
311
312
313
314
315
316
317
318
319
# File 'lib/capybara/selector/selector.rb', line 310

def call(locator, selector_config: {}, **options)
  @config.merge! selector_config
  if format
    @expression.call(locator, options)
  else
    warn 'Selector has no format'
  end
ensure
  warn "Locator #{locator.inspect} must #{locator_description}. This will raise an error in a future version of Capybara." unless locator_valid?(locator)
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



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

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

#custom_filtersObject



224
225
226
227
# File 'lib/capybara/selector/selector.rb', line 224

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



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

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



386
387
388
389
390
391
392
393
394
# File 'lib/capybara/selector/selector.rb', line 386

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



396
397
398
# File 'lib/capybara/selector/selector.rb', line 396

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



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

def_delegator :@filter_set, :description

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

Parameters:

  • name (Symbol, Regexp)

    The filter name

  • matcher (Regexp) (defaults to: nil)

    (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.



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

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

#expression_filtersObject



233
234
235
# File 'lib/capybara/selector/selector.rb', line 233

def expression_filters
  @filter_set.expression_filters
end

#filterObject



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


#filter_set(name, filters_to_use = nil) ⇒ Object



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

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



296
297
298
299
# File 'lib/capybara/selector/selector.rb', line 296

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

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



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

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



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

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



330
331
332
# File 'lib/capybara/selector/selector.rb', line 330

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 334


#node_filtersObject



229
230
231
# File 'lib/capybara/selector/selector.rb', line 229

def node_filters
  @filter_set.node_filters
end

#raw_locator?Boolean

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.

Returns:

  • (Boolean)


447
448
449
# File 'lib/capybara/selector/selector.rb', line 447

def raw_locator?
  !!@raw_locator
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.



409
410
411
# File 'lib/capybara/selector/selector.rb', line 409

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.



439
440
441
442
443
444
# File 'lib/capybara/selector/selector.rb', line 439

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



251
252
253
# File 'lib/capybara/selector/selector.rb', line 251

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