Class: Capybara::Selenium::Node

Inherits:
Driver::Node show all
Defined in:
lib/capybara/selenium/node.rb,
lib/capybara/selenium/extensions/html5_drag.rb

Overview

Selenium specific implementation of the Capybara::Driver::Node API

Direct Known Subclasses

ChromeNode, MarionetteNode

Defined Under Namespace

Modules: Html5Drag

Instance Attribute Summary

Attributes inherited from Driver::Node

#driver, #native

Instance Method Summary collapse

Methods inherited from Driver::Node

#initialize, #inspect, #trigger

Constructor Details

This class inherits a constructor from Capybara::Driver::Node

Instance Method Details

#==(other) ⇒ Object



159
160
161
# File 'lib/capybara/selenium/node.rb', line 159

def ==(other)
  native == other.native
end

#[](name) ⇒ Object



18
19
20
21
22
# File 'lib/capybara/selenium/node.rb', line 18

def [](name)
  native.attribute(name.to_s)
rescue Selenium::WebDriver::Error::WebDriverError
  nil
end

#all_textObject



9
10
11
12
13
14
15
16
# File 'lib/capybara/selenium/node.rb', line 9

def all_text
  text = driver.execute_script('return arguments[0].textContent', self)
  text.gsub(/[\u200b\u200e\u200f]/, '')
      .gsub(/[\ \n\f\t\v\u2028\u2029]+/, ' ')
      .gsub(/\A[[:space:]&&[^\u00a0]]+/, '')
      .gsub(/[[:space:]&&[^\u00a0]]+\z/, '')
      .tr("\u00a0", ' ')
end

#click(keys = [], **options) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/capybara/selenium/node.rb', line 87

def click(keys = [], **options)
  click_options = ClickOptions.new(keys, options)
  return native.click if click_options.empty?

  click_with_options(click_options)
rescue StandardError => err
  if err.is_a?(::Selenium::WebDriver::Error::ElementClickInterceptedError) ||
     err.message =~ /Other element would receive the click/
    scroll_to_center
  end

  raise err
end

#content_editable?Boolean

Returns:

  • (Boolean)


147
148
149
# File 'lib/capybara/selenium/node.rb', line 147

def content_editable?
  native.attribute('isContentEditable')
end

#disabled?Boolean

Returns:

  • (Boolean)


140
141
142
143
144
145
# File 'lib/capybara/selenium/node.rb', line 140

def disabled?
  return true unless native.enabled?

  # WebDriver only defines `disabled?` for form controls but fieldset makes sense too
  tag_name == 'fieldset' && find_xpath('ancestor-or-self::fieldset[@disabled]').any?
end

#double_click(keys = [], **options) ⇒ Object



108
109
110
111
112
113
# File 'lib/capybara/selenium/node.rb', line 108

def double_click(keys = [], **options)
  click_options = ClickOptions.new(keys, options)
  click_with_options(click_options) do |action|
    click_options.coords? ? action.double_click : action.double_click(native)
  end
end

#drag_to(element) ⇒ Object



123
124
125
126
127
128
# File 'lib/capybara/selenium/node.rb', line 123

def drag_to(element)
  # Due to W3C spec compliance - The Actions API no longer scrolls to elements when necessary
  # which means Seleniums `drag_and_drop` is now broken - do it manually
  scroll_if_needed { browser_action.click_and_hold(native).perform }
  element.scroll_if_needed { browser_action.move_to(element.native).release.perform }
end

#find_css(locator) ⇒ Object



155
156
157
# File 'lib/capybara/selenium/node.rb', line 155

def find_css(locator)
  native.find_elements(:css, locator).map { |el| self.class.new(driver, el) }
end

#find_xpath(locator) ⇒ Object



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

def find_xpath(locator)
  native.find_elements(:xpath, locator).map { |el| self.class.new(driver, el) }
end

#hoverObject



119
120
121
# File 'lib/capybara/selenium/node.rb', line 119

def hover
  scroll_if_needed { browser_action.move_to(native).perform }
end

#multiple?Boolean

Returns:

  • (Boolean)


136
# File 'lib/capybara/selenium/node.rb', line 136

def multiple?; boolean_attr(self[:multiple]); end

#pathObject



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/capybara/selenium/node.rb', line 163

def path
  path = find_xpath(XPath.ancestor_or_self).reverse

  result = []
  default_ns = path.last[:namespaceURI]
  while (node = path.shift)
    parent = path.first
    selector = node[:tagName]
    if node[:namespaceURI] != default_ns
      selector = XPath.child.where((XPath.local_name == selector) & (XPath.namespace_uri == node[:namespaceURI])).to_s
      selector
    end

    if parent
      siblings = parent.find_xpath(selector)
      selector += case siblings.size
      when 0
        '[ERROR]' # IE doesn't support full XPath (namespace-uri, etc)
      when 1
        '' # index not necessary when only one matching element
      else
        idx = siblings.index(node)
        # Element may not be found in the siblings if it has gone away
        idx.nil? ? '[ERROR]' : "[#{idx + 1}]"
      end
    end
    result.push selector
  end

  '/' + result.reverse.join('/')
end

#readonly?Boolean

Returns:

  • (Boolean)


135
# File 'lib/capybara/selenium/node.rb', line 135

def readonly?; boolean_attr(self[:readonly]); end

#right_click(keys = [], **options) ⇒ Object



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

def right_click(keys = [], **options)
  click_options = ClickOptions.new(keys, options)
  click_with_options(click_options) do |action|
    click_options.coords? ? action.context_click : action.context_click(native)
  end
end

#select_optionObject



77
78
79
# File 'lib/capybara/selenium/node.rb', line 77

def select_option
  click unless selected? || disabled?
end

#selected?Boolean Also known as: checked?

Returns:

  • (Boolean)


137
# File 'lib/capybara/selenium/node.rb', line 137

def selected?; boolean_attr(native.selected?); end

#send_keys(*args) ⇒ Object



115
116
117
# File 'lib/capybara/selenium/node.rb', line 115

def send_keys(*args)
  native.send_keys(*args)
end

#set(value, **options) ⇒ Object

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

Options Hash (**options):

  • :clear (Symbol, Array) — default: nil

    The method used to clear the previous value <br/> nil => clear via javascript <br/> :none => append the new value to the existing value <br/> :backspace => send backspace keystrokes to clear the field <br/> Array => an array of keys to send before the value being set, e.g. [[:command, ‘a’], :backspace]

Raises:

  • (ArgumentError)


49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/capybara/selenium/node.rb', line 49

def set(value, **options)
  raise ArgumentError, "Value cannot be an Array when 'multiple' attribute is not present. Not a #{value.class}" if value.is_a?(Array) && !multiple?

  case tag_name
  when 'input'
    case self[:type]
    when 'radio'
      click
    when 'checkbox'
      click if value ^ checked?
    when 'file'
      set_file(value)
    when 'date'
      set_date(value)
    when 'time'
      set_time(value)
    when 'datetime-local'
      set_datetime_local(value)
    else
      set_text(value, options)
    end
  when 'textarea'
    set_text(value, options)
  else
    set_content_editable(value) if content_editable?
  end
end

#style(styles) ⇒ Object



32
33
34
35
36
# File 'lib/capybara/selenium/node.rb', line 32

def style(styles)
  styles.each_with_object({}) do |style, result|
    result[style] = native.css_value(style)
  end
end

#tag_nameObject



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

def tag_name
  native.tag_name.downcase
end

#unselect_optionObject



81
82
83
84
85
# File 'lib/capybara/selenium/node.rb', line 81

def unselect_option
  raise Capybara::UnselectNotAllowed, 'Cannot unselect option from single select box.' unless select_node.multiple?

  click if selected?
end

#valueObject



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

def value
  if tag_name == 'select' && multiple?
    native.find_elements(:css, 'option:checked').map { |el| el[:value] || el.text }
  else
    native[:value]
  end
end

#visible?Boolean

Returns:

  • (Boolean)


134
# File 'lib/capybara/selenium/node.rb', line 134

def visible?; boolean_attr(native.displayed?); end

#visible_textObject



5
6
7
# File 'lib/capybara/selenium/node.rb', line 5

def visible_text
  native.text
end