class Capybara::Node::Element
A {Capybara::Node::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
{Capybara::Node::Element} also has access to HTML attributes and other properties of the element:
bar.value bar.text bar[:title]
@see Capybara::Node
Constants
- STYLE_SCRIPT
Public Class Methods
# File lib/capybara/node/element.rb, line 24 def initialize(session, base, query_scope, query) super(session, base) @query_scope = query_scope @query = query @allow_reload = false end
Public Instance Methods
Retrieve the given attribute
element[:title] # => HTML title attribute
@param [Symbol] attribute The attribute to retrieve @return [String] The value of the attribute
# File lib/capybara/node/element.rb, line 70 def [](attribute) synchronize { base[attribute] } end
# File lib/capybara/node/element.rb, line 31 def allow_reload! @allow_reload = true end
Whether or not the element is checked.
@return [Boolean] Whether the element is checked
# File lib/capybara/node/element.rb, line 290 def checked? synchronize { base.checked? } end
Click the Element
@!macro click_modifiers
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 @overload $0(*modifier_keys, **offset) @param *modifier_keys [:alt, :control, :meta, :shift] ([]) Keys to be held down when clicking @option offset [Integer] x X coordinate to offset the click location from the top left corner of the element @option offset [Integer] y Y coordinate to offset the click location from the top left corner of the element
@return [Capybara::Node::Element] The element
# File lib/capybara/node/element.rb, line 152 def click(*keys, **offset) synchronize { base.click(keys, offset) } self end
Whether or not the element is disabled.
@return [Boolean] Whether the element is disabled
# File lib/capybara/node/element.rb, line 310 def disabled? synchronize { base.disabled? } end
Double Click the Element
@macro click_modifiers @return [Capybara::Node::Element] The element
# File lib/capybara/node/element.rb, line 174 def double_click(*keys, **offset) synchronize { base.double_click(keys, offset) } self end
Drag the element to the given other element.
source = page.find('#foo') target = page.find('#bar') source.drag_to(target)
@param [Capybara::Node::Element] node The element to drag to
@return [Capybara::Node::Element] The element
# File lib/capybara/node/element.rb, line 370 def drag_to(node) synchronize { base.drag_to(node.base) } self end
Evaluate the given JavaScript in the context of the element and obtain the result from a callback function which will be passed as the last argument to the script. `this` in the script will refer to the element this is called on
@param [String] script A string of JavaScript to evaluate @return [Object] The result of the evaluated JavaScript (may be driver specific)
# File lib/capybara/node/element.rb, line 418 def evaluate_async_script(script, *args) session.evaluate_async_script(<<~JS, self, *args) (function (){ #{script} }).apply(arguments[0], Array.prototype.slice.call(arguments,1)); JS end
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.
@param [String] script A string of JavaScript to evaluate @return [Object] The result of the evaluated JavaScript (may be driver specific)
# File lib/capybara/node/element.rb, line 401 def evaluate_script(script, *args) session.evaluate_script(<<~JS, self, *args) (function(){ return #{script.strip} }).apply(arguments[0], Array.prototype.slice.call(arguments,1)); JS end
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.
@param [String] script A string of JavaScript to execute @param 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
# File lib/capybara/node/element.rb, line 384 def execute_script(script, *args) session.execute_script(<<~JS, self, *args) (function (){ #{script} }).apply(arguments[0], Array.prototype.slice.call(arguments,1)); JS end
Hover on the Element
@return [Capybara::Node::Element] The element
# File lib/capybara/node/element.rb, line 260 def hover synchronize { base.hover } self end
# File lib/capybara/node/element.rb, line 438 def inspect %(#<Capybara::Node::Element tag="#{base.tag_name}" path="#{base.path}">) rescue NotSupportedByDriverError %(#<Capybara::Node::Element tag="#{base.tag_name}">) rescue StandardError => err raise unless session.driver.invalid_element_errors.any? { |et| err.is_a?(et) } %(Obsolete #<Capybara::Node::Element>) end
Whether or not the element supports multiple results.
@return [Boolean] Whether the element supports multiple results.
# File lib/capybara/node/element.rb, line 330 def multiple? synchronize { base.multiple? } end
@return [Object] The native element from the driver, this allows access to driver specific methods
# File lib/capybara/node/element.rb, line 39 def native synchronize { base.native } end
Whether or not the element is readonly.
@return [Boolean] Whether the element is readonly
# File lib/capybara/node/element.rb, line 320 def readonly? synchronize { base.readonly? } end
# File lib/capybara/node/element.rb, line 426 def reload if @allow_reload begin reloaded = query_scope.reload.first(@query.name, @query.locator, @query.options) @base = reloaded.base if reloaded rescue StandardError => err raise err unless catch_error?(err) end end self end
Right Click the Element
@macro click_modifiers @return [Capybara::Node::Element] The element
# File lib/capybara/node/element.rb, line 163 def right_click(*keys, **offset) synchronize { base.right_click(keys, offset) } self end
Select this node if is an option element inside a select tag
@return [Capybara::Node::Element] The element
# File lib/capybara/node/element.rb, line 125 def select_option warn "Attempt to select disabled option: #{value || text}" if disabled? synchronize { base.select_option } self end
Whether or not the element is selected.
@return [Boolean] Whether the element is selected
# File lib/capybara/node/element.rb, line 300 def selected? synchronize { base.selected? } end
Send Keystrokes to the Element
@overload #send_keys(keys, …)
@param keys [String, Symbol, Array<String,Symbol>]
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
@return [Capybara::Node::Element] The element
# File lib/capybara/node/element.rb, line 250 def send_keys(*args) synchronize { base.send_keys(*args) } self end
Set the value of the form element to the given value.
@param [String] value The new value @param [Hash{}] options Driver specific options for how to set the value. Take default values from `Capybara#default_set_options` - See {Capybara::configure}
@return [Capybara::Node::Element] The element
# File lib/capybara/node/element.rb, line 113 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
Retrieve the given CSS styles
element.style('color', 'font-size') # => Computed values of CSS 'color' and 'font-size' styles
@param [Array<String>] styles Names of the desired CSS properties @return [Hash] Hash of the CSS property names to computed values
# File lib/capybara/node/element.rb, line 83 def style(*styles) styles = styles.flatten.map(&:to_s) raise ArgumentError, 'You must specify at least one CSS style' if styles.empty? begin synchronize { base.style(styles) } rescue NotImplementedError => err begin evaluate_script(STYLE_SCRIPT, *styles) rescue Capybara::NotSupportedByDriverError raise err end end end
@return [String] The tag name of the element
# File lib/capybara/node/element.rb, line 269 def tag_name synchronize { base.tag_name } end
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.
@param type [:all, :visible] Whether to return only visible or all text @return [String] The text of the element
# File lib/capybara/node/element.rb, line 55 def text(type = nil, normalize_ws: false) type ||= :all unless session_options.ignore_hidden_elements || session_options.visible_text_only txt = synchronize { type == :all ? base.all_text : base.visible_text } normalize_ws ? txt.gsub(/[[:space:]]+/, ' ').strip : txt end
Trigger any event on the current element, for example mouseover or focus events. Not supported with the Selenium driver, and SHOULDN'T BE USED IN TESTING unless you fully understand why you're using it, that it can allow actions a user could never perform, and that it may completely invalidate your test.
@param [String] event The name of the event to trigger
@return [Capybara::Node::Element] The element
# File lib/capybara/node/element.rb, line 354 def trigger(event) synchronize { base.trigger(event) } self end
Unselect this node if is an option element inside a multiple select tag
@return [Capybara::Node::Element] The element
# File lib/capybara/node/element.rb, line 136 def unselect_option synchronize { base.unselect_option } self end
@return [String] The value of the form element
# File lib/capybara/node/element.rb, line 101 def value synchronize { base.value } end
Whether or not the element is visible. Not all drivers support CSS, so the result may be inaccurate.
@return [Boolean] Whether the element is visible
# File lib/capybara/node/element.rb, line 280 def visible? synchronize { base.visible? } end