Class: Capybara::Selenium::Node

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

Direct Known Subclasses

ChromeNode, MarionetteNode

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



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

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

#all_textObject



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

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



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

def click(keys = [], **options)
  if keys.empty? && !coords?(options)
    native.click
  else
    scroll_if_needed do
      action_with_modifiers(keys, options) do |a|
        coords?(options) ? a.click : a.click(native)
      end
    end
  end
rescue StandardError => e
  if e.is_a?(::Selenium::WebDriver::Error::ElementClickInterceptedError) ||
     e.message =~ /Other element would receive the click/
    scroll_to_center
  end

  raise e
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)


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

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



111
112
113
114
115
116
117
# File 'lib/capybara/selenium/node.rb', line 111

def double_click(keys = [], **options)
  scroll_if_needed do
    action_with_modifiers(keys, options) do |a|
      coords?(options) ? a.double_click : a.double_click(native)
    end
  end
end

#drag_to(element) ⇒ Object



127
128
129
# File 'lib/capybara/selenium/node.rb', line 127

def drag_to(element)
  scroll_if_needed { driver.browser.action.drag_and_drop(native, element.native).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 { |n| self.class.new(driver, n) }
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 { |n| self.class.new(driver, n) }
end

#hoverObject



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

def hover
  scroll_if_needed { driver.browser.action.move_to(native).perform }
end

#multiple?Boolean

Returns:

  • (Boolean)


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

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
# 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
        "[#{siblings.index(node) + 1}]"
      end
    end
    result.push selector
  end

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

#readonly?Boolean

Returns:

  • (Boolean)


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

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

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



103
104
105
106
107
108
109
# File 'lib/capybara/selenium/node.rb', line 103

def right_click(keys = [], **options)
  scroll_if_needed do
    action_with_modifiers(keys, options) do |a|
      coords?(options) ? a.context_click : a.context_click(native)
    end
  end
end

#select_optionObject



75
76
77
# File 'lib/capybara/selenium/node.rb', line 75

def select_option
  native.click unless selected? || disabled?
end

#selected?Boolean Also known as: checked?

Returns:

  • (Boolean)


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

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

#send_keys(*args) ⇒ Object



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

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)


48
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
# File 'lib/capybara/selenium/node.rb', line 48

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



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

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

#tag_nameObject



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

def tag_name
  native.tag_name.downcase
end

#unselect_optionObject



79
80
81
82
# File 'lib/capybara/selenium/node.rb', line 79

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

#valueObject



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

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

#visible?Boolean

Returns:

  • (Boolean)


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

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

#visible_textObject



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

def visible_text
  native.text
end