Class: Capybara::Node::Element

Inherits:
Base
  • Object
show all
Defined in:
lib/capybara/node/element.rb

Overview

A Element represents a single element on the page. It is possible to interact with the contents of this element the same as with a document:

session = Capybara::Session.new(:rack_test, my_app)

bar = session.find('#bar')              # from Capybara::Node::Finders
bar.select('Baz', from: 'Quox')      # from Capybara::Node::Actions

Element also has access to HTML attributes and other properties of the element:

bar.value
bar.text
bar[:title]

See Also:

Instance Attribute Summary

Attributes inherited from Base

#base, #query_scope, #session

Instance Method Summary collapse

Methods inherited from Base

#find_css, #find_xpath, #session_options, #synchronize, #to_capybara_node

Methods included from Matchers

#==, #assert_all_of_selectors, #assert_matches_selector, #assert_no_selector, #assert_no_text, #assert_none_of_selectors, #assert_not_matches_selector, #assert_selector, #assert_text, #has_button?, #has_checked_field?, #has_css?, #has_field?, #has_link?, #has_no_button?, #has_no_checked_field?, #has_no_css?, #has_no_field?, #has_no_link?, #has_no_select?, #has_no_selector?, #has_no_table?, #has_no_text?, #has_no_unchecked_field?, #has_no_xpath?, #has_select?, #has_selector?, #has_table?, #has_text?, #has_unchecked_field?, #has_xpath?, #matches_css?, #matches_selector?, #matches_xpath?, #not_matches_css?, #not_matches_selector?, #not_matches_xpath?

Methods included from Actions

#attach_file, #check, #choose, #click_button, #click_link, #click_link_or_button, #fill_in, #select, #uncheck, #unselect

Methods included from Finders

#all, #ancestor, #find, #find_button, #find_by_id, #find_field, #find_link, #first, #sibling

Constructor Details

#initialize(session, base, query_scope, query) ⇒ Element

Returns a new instance of Element.



25
26
27
28
29
30
# File 'lib/capybara/node/element.rb', line 25

def initialize(session, base, query_scope, query)
  super(session, base)
  @query_scope = query_scope
  @query = query
  @allow_reload = false
end

Instance Method Details

#[](attribute) ⇒ String

Retrieve the given attribute

element[:title] # => HTML title attribute

Parameters:

  • attribute (Symbol)

    The attribute to retrieve

Returns:

  • (String)

    The value of the attribute



70
71
72
# File 'lib/capybara/node/element.rb', line 70

def [](attribute)
  synchronize { base[attribute] }
end

#allow_reload!Object



32
33
34
# File 'lib/capybara/node/element.rb', line 32

def allow_reload!
  @allow_reload = true
end

#checked?Boolean

Whether or not the element is checked.

Returns:

  • (Boolean)

    Whether the element is checked



267
268
269
# File 'lib/capybara/node/element.rb', line 267

def checked?
  synchronize { base.checked? }
end

#click(*modifier_keys, **offset) ⇒ Capybara::Node::Element

Click the Element

Both x: and y: must be specified if an offset is wanted, if not specified the click will occur at the middle of the element

Parameters:

  • *modifier_keys (:alt, :control, :meta, :shift)

    ([]) Keys to be held down when clicking

Options Hash (**offset):

  • x (Integer)

    X coordinate to offset the click location from the top left corner of the element

  • y (Integer)

    Y coordinate to offset the click location from the top left corner of the element

Returns:



129
130
131
132
# File 'lib/capybara/node/element.rb', line 129

def click(*keys, **offset)
  synchronize { base.click(keys, offset) }
  self
end

#disabled?Boolean

Whether or not the element is disabled.

Returns:

  • (Boolean)

    Whether the element is disabled



287
288
289
# File 'lib/capybara/node/element.rb', line 287

def disabled?
  synchronize { base.disabled? }
end

#double_click(*modifier_keys, **offset) ⇒ Capybara::Node::Element

Double Click the Element

Both x: and y: must be specified if an offset is wanted, if not specified the click will occur at the middle of the element

Parameters:

  • *modifier_keys (:alt, :control, :meta, :shift)

    ([]) Keys to be held down when clicking

Options Hash (**offset):

  • x (Integer)

    X coordinate to offset the click location from the top left corner of the element

  • y (Integer)

    Y coordinate to offset the click location from the top left corner of the element

Returns:



151
152
153
154
# File 'lib/capybara/node/element.rb', line 151

def double_click(*keys, **offset)
  synchronize { base.double_click(keys, offset) }
  self
end

#drag_to(node) ⇒ Capybara::Node::Element

Drag the element to the given other element.

source = page.find('#foo')
target = page.find('#bar')
source.drag_to(target)

Parameters:

Returns:



345
346
347
348
# File 'lib/capybara/node/element.rb', line 345

def drag_to(node)
  synchronize { base.drag_to(node.base) }
  self
end

#evaluate_script(script, *args) ⇒ Object

Evaluate the given JS in the context of the element and return the result. Be careful when using this with scripts that return complex objects, such as jQuery statements. execute_script might be a better alternative. ‘this` in the script will refer to the element this is called on.

Parameters:

  • script (String)

    A string of JavaScript to evaluate

Returns:

  • (Object)

    The result of the evaluated JavaScript (may be driver specific)



376
377
378
379
380
381
382
# File 'lib/capybara/node/element.rb', line 376

def evaluate_script(script, *args)
  session.evaluate_script(<<~JS, self, *args)
    (function(){
      return #{script}
    }).apply(arguments[0], Array.prototype.slice.call(arguments,1));
  JS
end

#execute_script(script, *args) ⇒ Object

Execute the given JS in the context of the element not returning a result. This is useful for scripts that return complex objects, such as jQuery statements. execute_script should be used over evaluate_script whenever possible. ‘this` in the script will refer to the element this is called on.

Parameters:

  • script (String)

    A string of JavaScript to execute

  • args

    Optional arguments that will be passed to the script. Driver support for this is optional and types of objects supported may differ between drivers



359
360
361
362
363
364
365
# File 'lib/capybara/node/element.rb', line 359

def execute_script(script, *args)
  session.execute_script(<<~JS, self, *args)
    (function (){
      #{script}
    }).apply(arguments[0], Array.prototype.slice.call(arguments,1));
  JS
end

#hoverCapybara::Node::Element

Hover on the Element

Returns:



237
238
239
240
# File 'lib/capybara/node/element.rb', line 237

def hover
  synchronize { base.hover }
  self
end

#inspectObject



396
397
398
399
400
401
402
403
404
# File 'lib/capybara/node/element.rb', line 396

def inspect
  %(#<Capybara::Node::Element tag="#{base.tag_name}" path="#{base.path}">)
rescue NotSupportedByDriverError
  %(#<Capybara::Node::Element tag="#{base.tag_name}">)
rescue StandardError => e
  raise unless session.driver.invalid_element_errors.any? { |et| e.is_a?(et) }

  %(Obsolete #<Capybara::Node::Element>)
end

#multiple?Boolean

Whether or not the element supports multiple results.

Returns:

  • (Boolean)

    Whether the element supports multiple results.



307
308
309
# File 'lib/capybara/node/element.rb', line 307

def multiple?
  synchronize { base.multiple? }
end

#nativeObject

Returns The native element from the driver, this allows access to driver specific methods.

Returns:

  • (Object)

    The native element from the driver, this allows access to driver specific methods



40
41
42
# File 'lib/capybara/node/element.rb', line 40

def native
  synchronize { base.native }
end

#pathString

An XPath expression describing where on the page the element can be found

Returns:

  • (String)

    An XPath expression



317
318
319
# File 'lib/capybara/node/element.rb', line 317

def path
  synchronize { base.path }
end

#readonly?Boolean

Whether or not the element is readonly.

Returns:

  • (Boolean)

    Whether the element is readonly



297
298
299
# File 'lib/capybara/node/element.rb', line 297

def readonly?
  synchronize { base.readonly? }
end

#reloadObject



384
385
386
387
388
389
390
391
392
393
394
# File 'lib/capybara/node/element.rb', line 384

def reload
  if @allow_reload
    begin
      reloaded = query_scope.reload.first(@query.name, @query.locator, @query.options)
      @base = reloaded.base if reloaded
    rescue StandardError => e
      raise e unless catch_error?(e)
    end
  end
  self
end

#right_click(*modifier_keys, **offset) ⇒ Capybara::Node::Element

Right Click the Element

Both x: and y: must be specified if an offset is wanted, if not specified the click will occur at the middle of the element

Parameters:

  • *modifier_keys (:alt, :control, :meta, :shift)

    ([]) Keys to be held down when clicking

Options Hash (**offset):

  • x (Integer)

    X coordinate to offset the click location from the top left corner of the element

  • y (Integer)

    Y coordinate to offset the click location from the top left corner of the element

Returns:



140
141
142
143
# File 'lib/capybara/node/element.rb', line 140

def right_click(*keys, **offset)
  synchronize { base.right_click(keys, offset) }
  self
end

#select_optionCapybara::Node::Element

Select this node if is an option element inside a select tag

Returns:



102
103
104
105
106
# File 'lib/capybara/node/element.rb', line 102

def select_option
  warn "Attempt to select disabled option: #{value || text}" if disabled?
  synchronize { base.select_option }
  self
end

#selected?Boolean

Whether or not the element is selected.

Returns:

  • (Boolean)

    Whether the element is selected



277
278
279
# File 'lib/capybara/node/element.rb', line 277

def selected?
  synchronize { base.selected? }
end

#send_keys(keys, ...) ⇒ Capybara::Node::Element

Send Keystrokes to the Element

Examples:

element.send_keys "foo"                     #=> value: 'foo'
element.send_keys "tet", :left, "s"   #=> value: 'test'
element.send_keys [:control, 'a'], :space   #=> value: ' ' - assuming ctrl-a selects all contents

Symbols supported for keys :cancel :help :backspace :tab :clear :return :enter :shift :control :alt :pause :escape :space :page_up :page_down :end :home :left :up :right :down :insert :delete :semicolon :equals :numpad0 :numpad1 :numpad2 :numpad3 :numpad4 :numpad5 :numpad6 :numpad7 :numpad8 :numpad9 :multiply - numeric keypad * :add - numeric keypad + :separator - numeric keypad ‘separator’ key ?? :subtract - numeric keypad - :decimal - numeric keypad . :divide - numeric keypad / :f1 :f2 :f3 :f4 :f5 :f6 :f7 :f8 :f9 :f10 :f11 :f12 :meta :command - alias of :meta

Parameters:

  • keys (String, Symbol, Array<String,Symbol>)

Returns:



227
228
229
230
# File 'lib/capybara/node/element.rb', line 227

def send_keys(*args)
  synchronize { base.send_keys(*args) }
  self
end

#set(value, **options) ⇒ Capybara::Node::Element

Set the value of the form element to the given value.

Parameters:

  • value (String)

    The new value

  • options (Hash{})

    Driver specific options for how to set the value. Take default values from Capybara#default_set_options

Returns:

Raises:



90
91
92
93
94
95
# File 'lib/capybara/node/element.rb', line 90

def set(value, **options)
  raise Capybara::ReadOnlyElementError, "Attempt to set readonly element with value: #{value}" if readonly?
  options = session_options.default_set_options.to_h.merge(options)
  synchronize { base.set(value, options) }
  self
end

#tag_nameString

Returns The tag name of the element.

Returns:

  • (String)

    The tag name of the element



246
247
248
# File 'lib/capybara/node/element.rb', line 246

def tag_name
  synchronize { base.tag_name }
end

#text(type = nil) ⇒ String

Retrieve the text of the element. If ‘Capybara.ignore_hidden_elements` is `true`, which it is by default, then this will return only text which is visible. The exact semantics of this may differ between drivers, but generally any text within elements with `display:none` is ignored. This behaviour can be overridden by passing `:all` to this method.

Parameters:

  • type (:all, :visible) (defaults to: nil)

    Whether to return only visible or all text

Returns:

  • (String)

    The text of the element



56
57
58
59
# File 'lib/capybara/node/element.rb', line 56

def text(type = nil)
  type ||= :all unless session_options.ignore_hidden_elements || session_options.visible_text_only
  synchronize { type == :all ? base.all_text : base.visible_text }
end

#trigger(event) ⇒ Capybara::Node::Element

Trigger any event on the current element, for example mouseover or focus events. Does not work in Selenium.

Parameters:

  • event (String)

    The name of the event to trigger

Returns:



329
330
331
332
# File 'lib/capybara/node/element.rb', line 329

def trigger(event)
  synchronize { base.trigger(event) }
  self
end

#unselect_optionCapybara::Node::Element

Unselect this node if is an option element inside a multiple select tag

Returns:



113
114
115
116
# File 'lib/capybara/node/element.rb', line 113

def unselect_option
  synchronize { base.unselect_option }
  self
end

#valueString

Returns The value of the form element.

Returns:

  • (String)

    The value of the form element



78
79
80
# File 'lib/capybara/node/element.rb', line 78

def value
  synchronize { base.value }
end

#visible?Boolean

Whether or not the element is visible. Not all drivers support CSS, so the result may be inaccurate.

Returns:

  • (Boolean)

    Whether the element is visible



257
258
259
# File 'lib/capybara/node/element.rb', line 257

def visible?
  synchronize { base.visible? }
end