Class: Capybara::Node::Element
Relationships & Source Files | |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
self,
Base
|
|
Instance Chain:
|
|
Inherits: |
Capybara::Node::Base
|
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)
= session.find('#bar') # from Capybara::Node::Finders
.select('Baz', from: 'Quox') # from Capybara::Node::Actions
Element
also has access to Capybara.HTML attributes and other properties of the element:
value
.text
[:title]
.
Constant Summary
-
STYLE_SCRIPT =
# File 'lib/capybara/node/element.rb', line 590<<~JS (function(){ var s = window.getComputedStyle(this); var result = {}; for (var i = arguments.length; i--; ) { var property_name = arguments[i]; result[property_name] = s.getPropertyValue(property_name); } return result; }).apply(this, arguments) JS
Actions
- Included
CAPTURE_FILE_ELEMENT_SCRIPT, DATALIST_OPTIONS_SCRIPT, RESET_STYLE_SCRIPT, UPDATE_STYLE_SCRIPT
Class Method Summary
Instance Attribute Summary
-
#checked? ⇒ Boolean
readonly
Whether or not the element is checked.
-
#disabled? ⇒ Boolean
readonly
Whether or not the element is disabled.
-
#multiple? ⇒ Boolean
readonly
Whether or not the element supports multiple results.
-
#obscured? ⇒ Boolean
readonly
Whether or not the element is currently in the viewport and it (or descendants) would be considered clickable at the elements center point.
-
#readonly? ⇒ Boolean
readonly
Whether or not the element is readonly.
-
#selected? ⇒ Boolean
readonly
Whether or not the element is selected.
-
#visible? ⇒ Boolean
readonly
Whether or not the element is visible.
Base
- Inherited
Instance Method Summary
-
#[](attribute) ⇒ String
Retrieve the given attribute.
- #allow_reload!(idx = nil)
-
#click(*modifier_keys, wait: nil, **offset) ⇒ Capybara::Node::Element
Click the
Element
. -
#double_click(*modifier_keys, wait: nil, **offset) ⇒ Capybara::Node::Element
Double Click the
Element
. -
#drag_to(node, **options) ⇒ Capybara::Node::Element
Drag the element to the given other element.
-
#drop(path, ...) ⇒ Capybara::Node::Element
Drop items on the current element.
-
#evaluate_async_script(script, *args) ⇒ Object
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.
-
#evaluate_script(script, *args) ⇒ Object
Evaluate the given JS in the context of the element and return the result.
-
#execute_script(script, *args)
Execute the given JS in the context of the element not returning a result.
-
#flash ⇒ Capybara::Node::Element
Toggle the elements background color between white and black for a period of time.
-
#hover ⇒ Capybara::Node::Element
Hover on the
Element
. -
#inspect ⇒ String
A human-readable representation of the element.
- #native ⇒ Object
-
#path ⇒ String
An XPath expression describing where on the page the element can be found.
- #rect
-
#right_click(*modifier_keys, wait: nil, **offset) ⇒ Capybara::Node::Element
Right Click the
Element
. -
#scroll_to(position, offset: [0,0]) ⇒ Capybara::Node::Element
Scroll the page or element.
-
#select_option(wait: nil) ⇒ Capybara::Node::Element
Select this node if it is an option element inside a select tag.
-
#send_keys(keys, ...) ⇒ Capybara::Node::Element
Send Keystrokes to the
Element
. -
#set(value, **options) ⇒ Capybara::Node::Element
Set the value of the form element to the given value.
-
#shadow_root ⇒ Capybara::Node::Element
Return the shadow_root for the current element.
-
#style(*styles) ⇒ Hash
Retrieve the given CSS styles.
- #tag_name ⇒ String
-
#text(type = nil, normalize_ws: false) ⇒ String
Retrieve the text of the element.
-
#trigger(event) ⇒ Capybara::Node::Element
Trigger any event on the current element, for example mouseover or focus events.
-
#unselect_option(wait: nil) ⇒ Capybara::Node::Element
Unselect this node if it is an option element inside a multiple select tag.
- #value ⇒ String
- #perform_click_action(keys, wait: nil, **options) private
- #initial_cache Internal use only Internal use only
- #reload Internal use only Internal use only
Base
- Inherited
#reload | overridden in subclasses, e.g. |
#synchronize | This method is Capybara’s primary defence against asynchronicity problems. |
#to_capybara_node, #find_css, #find_xpath, #session_options |
Minitest::Expectations
- Included
Matchers
- Included
#==, | |
#assert_all_of_selectors | Asserts that all of the provided selectors are present on the given page or descendants of the current node. |
#assert_ancestor | Asserts that a given selector matches an ancestor of the current node. |
#assert_any_of_selectors | Asserts that any of the provided selectors are present on the given page or descendants of the current node. |
#assert_matches_selector | Asserts that the current node matches a given selector. |
#assert_matches_style | Asserts that an element has the specified CSS styles. |
#assert_no_ancestor, | |
#assert_no_selector | Asserts that a given selector is not on the page or a descendant of the current node. |
#assert_no_sibling, | |
#assert_no_text | Asserts that the page or current node doesn’t have the given text content, ignoring any Capybara.HTML tags. |
#assert_none_of_selectors | Asserts that none of the provided selectors are present on the given page or descendants of the current node. |
#assert_not_matches_selector | Asserts that the current node does not match a given selector. |
#assert_selector | Asserts that a given selector is on the page or a descendant of the current node. |
#assert_sibling | Asserts that a given selector matches a sibling of the current node. |
#assert_style, | |
#assert_text | Asserts that the page or current node has the given text content, ignoring any Capybara.HTML tags. |
#has_ancestor? | Predicate version of |
#has_button? | Checks if the page or current node has a button with the given text, value or id. |
#has_checked_field? | Checks if the page or current node has a radio button or checkbox with the given label, value, id, or test_id attribute that is currently checked. |
#has_content? | Alias for Matchers#has_text?. |
#has_css? | Checks if a given CSS selector is on the page or a descendant of the current node. |
#has_element? | Checks if the page or current node has a element with the given local name. |
#has_field? | Checks if the page or current node has a form field with the given label, name or id. |
#has_link? | Checks if the page or current node has a link with the given text or id. |
#has_no_ancestor? | Predicate version of |
#has_no_button? | Checks if the page or current node has no button with the given text, value or id. |
#has_no_checked_field? | Checks if the page or current node has no radio button or checkbox with the given label, value or id, or test_id attribute that is currently checked. |
#has_no_content? | Alias for Matchers#has_no_text?. |
#has_no_css? | Checks if a given CSS selector is not on the page or a descendant of the current node. |
#has_no_element? | Checks if the page or current node has no element with the given local name. |
#has_no_field? | Checks if the page or current node has no form field with the given label, name or id. |
#has_no_link? | Checks if the page or current node has no link with the given text or id. |
#has_no_select? | Checks if the page or current node has no select field with the given label, name or id. |
#has_no_selector? | Checks if a given selector is not on the page or a descendant of the current node. |
#has_no_sibling? | Predicate version of |
#has_no_table? | Checks if the page or current node has no table with the given id or caption. |
#has_no_text? | Checks if the page or current node does not have the given text content, ignoring any Capybara.HTML tags and normalizing whitespace. |
#has_no_unchecked_field? | Checks if the page or current node has no radio button or checkbox with the given label, value or id, or test_id attribute that is currently unchecked. |
#has_no_xpath? | Checks if a given |
#has_select? | Checks if the page or current node has a select field with the given label, name or id. |
#has_selector? | Checks if a given selector is on the page or a descendant of the current node. |
#has_sibling? | Predicate version of |
#has_style?, | |
#has_table? | Checks if the page or current node has a table with the given id or caption: |
#has_text? | Checks if the page or current node has the given text content, ignoring any Capybara.HTML tags. |
#has_unchecked_field? | Checks if the page or current node has a radio button or checkbox with the given label, value or id, or test_id attribute that is currently unchecked. |
#has_xpath? | Checks if a given |
#matches_css? | Checks if the current node matches given CSS selector. |
#matches_selector? | Checks if the current node matches given selector. |
#matches_style? | Checks if a an element has the specified CSS styles. |
#matches_xpath? | Checks if the current node matches given |
#not_matches_css? | Checks if the current node does not match given CSS selector. |
#not_matches_selector? | Checks if the current node does not match given selector. |
#not_matches_xpath? | Checks if the current node does not match given |
#_set_query_session_options, #_verify_match_result, #_verify_multiple, #_verify_selector_result, #_verify_text, #extract_selector, #make_predicate |
Actions
- Included
#attach_file | Find a descendant file field on the page and attach a file given its path. |
#check | Find a descendant check box and mark it as checked. |
#choose | Find a descendant radio button and mark it as checked. |
#click_button | Finds a button on the page and clicks it. |
#click_link | Finds a link by id, test_id attribute, text or title and clicks it. |
#click_link_or_button | Finds a button or link and clicks it. |
#click_on | Alias for Actions#click_link_or_button. |
#fill_in | Locate a text field or text area and fill it in with the given text. |
#select | If |
#uncheck | Find a descendant check box and uncheck it. |
#unselect | Find a select box on the page and unselect a particular option from it. |
#_check_with_label, #_reset_style, #_update_style, #find_select_or_datalist_input, #select_datalist_option, #while_visible |
Finders
- Included
#all | Find all elements on the page matching the given selector and options. |
#ancestor | Find an |
#find | Find an |
#find_all | Alias for Finders#all. |
#find_button | Find a button on the page. |
#find_by_id | Find a element on the page, given its id. |
#find_field | Find a form field on the page. |
#find_link | Find a link on the page. |
#first | Find the first element on the page matching the given selector and options. |
#sibling | Find an |
#ambiguous?, #options_include_minimum?, #parent, #prefer_exact?, #synced_resolve |
Constructor Details
.new(session, base, query_scope, query) ⇒ Element
# 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 @query_idx = nil end
Instance Attribute Details
#checked? ⇒ Boolean
(readonly)
Whether or not the element is checked.
# File 'lib/capybara/node/element.rb', line 326
def checked? synchronize { base.checked? } end
#disabled? ⇒ Boolean
(readonly)
Whether or not the element is disabled.
# File 'lib/capybara/node/element.rb', line 346
def disabled? synchronize { base.disabled? } end
#multiple? ⇒ Boolean
(readonly)
Whether or not the element supports multiple results.
# File 'lib/capybara/node/element.rb', line 366
def multiple? synchronize { base.multiple? } end
#obscured? ⇒ Boolean
(readonly)
Whether or not the element is currently in the viewport and it (or descendants) would be considered clickable at the elements center point.
# File 'lib/capybara/node/element.rb', line 316
def obscured? synchronize { base.obscured? } end
#readonly? ⇒ Boolean
(readonly)
Whether or not the element is readonly.
# File 'lib/capybara/node/element.rb', line 356
def readonly? synchronize { base.readonly? } end
#selected? ⇒ Boolean
(readonly)
Whether or not the element is selected.
# File 'lib/capybara/node/element.rb', line 336
def selected? synchronize { base.selected? } end
#visible? ⇒ Boolean
(readonly)
Whether or not the element is visible. Not all drivers support CSS, so the result may be inaccurate.
# File 'lib/capybara/node/element.rb', line 305
def visible? synchronize { base.visible? } end
Instance Method Details
#[](attribute) ⇒ String
Retrieve the given attribute.
element[:title] # => HTML title attribute
# File 'lib/capybara/node/element.rb', line 73
def [](attribute) synchronize { base[attribute] } end
#allow_reload!(idx = nil)
[ GitHub ]# File 'lib/capybara/node/element.rb', line 33
def allow_reload!(idx = nil) @query_idx = idx @allow_reload = true end
#click(*modifier_keys, wait: nil, **offset) ⇒ Element
Click the Element
.
If the driver dynamic pages (JS) and the element is currently non-interactable, this method will continuously retry the action until either the element becomes interactable or the maximum wait time expires.
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.
# File 'lib/capybara/node/element.rb', line 170
def click(*keys, ** ) perform_click_action(keys, ** ) do |k, opts| base.click(k, **opts) end end
#double_click(*modifier_keys, wait: nil, **offset) ⇒ Element
Double Click the Element
.
If the driver dynamic pages (JS) and the element is currently non-interactable, this method will continuously retry the action until either the element becomes interactable or the maximum wait time expires.
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.
# File 'lib/capybara/node/element.rb', line 197
def double_click(*keys, ** ) perform_click_action(keys, ** ) do |k, opts| base.double_click(k, **opts) end end
#drag_to(node, **options) ⇒ Element
Drag the element to the given other element.
source = page.find('#foo')
target = page.find('#bar')
source.drag_to(target)
# File 'lib/capybara/node/element.rb', line 418
def drag_to(node, ** ) synchronize { base.drag_to(node.base, ** ) } self end
#drop(path, ...) ⇒ Element
#drop(strings, ...) ⇒ Element
Element
#drop(strings, ...) ⇒ Element
Drop items on the current element.
target = page.find('#foo')
target.drop('/some/path/file.csv')
# File 'lib/capybara/node/element.rb', line 437
def drop(*args) = args.map { |arg| arg.respond_to?(:to_path) ? arg.to_path : arg } synchronize { base.drop(* ) } self end
#evaluate_async_script(script, *args) ⇒ Object
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.
# File 'lib/capybara/node/element.rb', line 529
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_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.
# File 'lib/capybara/node/element.rb', line 512
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_script(script, *args)
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 a result is not expected or needed. this
in the script will refer to the element this is called on.
# File 'lib/capybara/node/element.rb', line 495
def execute_script(script, *args) session.execute_script(<<~JS, self, *args) (function (){ #{script} }).apply(arguments[0], Array.prototype.slice.call(arguments,1)); JS end
#flash ⇒ Element
Toggle the elements background color between white and black for a period of time.
# File 'lib/capybara/node/element.rb', line 542
def flash execute_script(<<~JS, 100) async function flash(el, delay){ var old_bg = el.style.backgroundColor; var colors = ["black", "white"]; for(var i=0; i<20; i++){ el.style.backgroundColor = colors[i % colors.length]; await new Promise(resolve => setTimeout(resolve, delay)); } el.style.backgroundColor = old_bg; } flash(this, arguments[0]); JS self end
#hover ⇒ Element
Hover on the Element
.
# File 'lib/capybara/node/element.rb', line 284
def hover synchronize { base.hover } self end
#initial_cache
# File 'lib/capybara/node/element.rb', line 586
def initial_cache base.respond_to?(:initial_cache) ? base.initial_cache : {} end
#inspect ⇒ String
A human-readable representation of the element.
# File 'lib/capybara/node/element.rb', line 577
def inspect %(#<Capybara::Node::Element tag="#{base.tag_name}" path="#{base.path}">) rescue NotSupportedByDriverError %(#<Capybara::Node::Element tag="#{base.tag_name}">) rescue *session.driver.invalid_element_errors %(Obsolete #<Capybara::Node::Element>) end
#native ⇒ Object
# File 'lib/capybara/node/element.rb', line 42
def native synchronize { base.native } end
#path ⇒ String
An XPath expression describing where on the page the element can be found.
# File 'lib/capybara/node/element.rb', line 376
def path synchronize { base.path } end
#perform_click_action(keys, wait: nil, **options) (private)
# File 'lib/capybara/node/element.rb', line 604
def perform_click_action(keys, wait: nil, ** ) raise ArgumentError, 'You must specify both x: and y: for a click offset' if nil ^ [:x] ^ [:y] [:offset] ||= :center if .w3c_click_offset synchronize(wait) { yield keys, } self end
#rect
[ GitHub ]# File 'lib/capybara/node/element.rb', line 380
def rect synchronize { base.rect } end
#reload
# File 'lib/capybara/node/element.rb', line 560
def reload return self unless @allow_reload begin reloaded = @query.resolve_for(query_scope ? query_scope.reload : session)[@query_idx.to_i] @base = reloaded.base if reloaded rescue StandardError => e raise e unless catch_error?(e) end self end
#right_click(*modifier_keys, wait: nil, **offset) ⇒ Element
Right Click the Element
.
If the driver dynamic pages (JS) and the element is currently non-interactable, this method will continuously retry the action until either the element becomes interactable or the maximum wait time expires.
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.
# File 'lib/capybara/node/element.rb', line 184
def right_click(*keys, ** ) perform_click_action(keys, ** ) do |k, opts| base.right_click(k, **opts) end end
#scroll_to(position, offset: [0,0]) ⇒ Element
#scroll_to(element, align: :top) ⇒ Element
#scroll_to(x, y) ⇒ Element
Element
#scroll_to(element, align: :top) ⇒ Element
#scroll_to(x, y) ⇒ Element
Scroll the page or element.
# File 'lib/capybara/node/element.rb', line 462
def scroll_to(pos_or_el_or_x, y = nil, align: :top, offset: nil) case pos_or_el_or_x when Symbol synchronize { base.scroll_to(nil, pos_or_el_or_x) } unless pos_or_el_or_x == :current when Capybara::Node::Element synchronize { base.scroll_to(pos_or_el_or_x.base, align) } else synchronize { base.scroll_to(nil, nil, [pos_or_el_or_x, y]) } end synchronize { base.scroll_by(*offset) } unless offset.nil? self end
#select_option(wait: nil) ⇒ Element
Select this node if it is an option element inside a select tag.
If the driver dynamic pages (JS) and the element is currently non-interactable, this method will continuously retry the action until either the element becomes interactable or the maximum wait time expires.
# File 'lib/capybara/node/element.rb', line 139
def select_option(wait: nil) synchronize(wait) { base.select_option } self end
#send_keys(keys, ...) ⇒ 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
# File 'lib/capybara/node/element.rb', line 274
def send_keys(*args) synchronize { base.send_keys(*args) } self end
#set(value, **options) ⇒ Element
Set the value of the form element to the given value.
#shadow_root ⇒ Element
Return the shadow_root for the current element
#style(*styles) ⇒ Hash
Retrieve the given CSS styles.
element.style('color', 'font-size') # => Computed values of CSS 'color' and 'font-size' styles
# File 'lib/capybara/node/element.rb', line 86
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 => e begin evaluate_script(STYLE_SCRIPT, *styles) rescue Capybara::NotSupportedByDriverError raise e end end end
#tag_name ⇒ String
# File 'lib/capybara/node/element.rb', line 293
def tag_name # Element type is immutable so cache it @tag_name ||= initial_cache[:tag_name] || synchronize { base.tag_name } end
#text(type = nil, normalize_ws: false) ⇒ String
Retrieve the text of the element. If 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.
# File 'lib/capybara/node/element.rb', line 58
def text(type = nil, normalize_ws: false) type ||= :all unless .ignore_hidden_elements || .visible_text_only txt = synchronize { type == :all ? base.all_text : base.visible_text } normalize_ws ? txt.gsub(/[[:space:]]+/, ' ').strip : txt end
#trigger(event) ⇒ Element
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.
# File 'lib/capybara/node/element.rb', line 394
def trigger(event) synchronize { base.trigger(event) } self end
#unselect_option(wait: nil) ⇒ Element
Unselect this node if it is an option element inside a multiple select tag.
If the driver dynamic pages (JS) and the element is currently non-interactable, this method will continuously retry the action until either the element becomes interactable or the maximum wait time expires.
# File 'lib/capybara/node/element.rb', line 150
def unselect_option(wait: nil) synchronize(wait) { base.unselect_option } self end
#value ⇒ String
# File 'lib/capybara/node/element.rb', line 105
def value synchronize { base.value } end