Class: Capybara::Selenium::Node

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

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



187
188
189
# File 'lib/capybara/selenium/node.rb', line 187

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

#[](name) ⇒ Object



14
15
16
17
18
# File 'lib/capybara/selenium/node.rb', line 14

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

#all_textObject



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

def all_text
  text = driver.execute_script("return arguments[0].textContent", self)
  Capybara::Helpers.normalize_whitespace(text)
end

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



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/capybara/selenium/node.rb', line 72

def click(keys = [], options = {})
  if keys.empty? && !(options[:x] && options[:y])
    native.click
  else
    scroll_if_needed do
      action_with_modifiers(keys, options) do |a|
        if options[:x] && options[:y]
          a.click
        else
          a.click(native)
        end
      end
    end
  end
rescue => e
  if e.is_a?(::Selenium::WebDriver::Error::ElementClickInterceptedError) ||
     e.message =~ /Other element would receive the click/
    begin
      driver.execute_script("arguments[0].scrollIntoView({behavior: 'instant', block: 'center', inline: 'center'})", self)
    rescue # Swallow error if scrollIntoView with options isn't supported
    end
  end
  raise e
end

#content_editable?Boolean

Returns:

  • (Boolean)


175
176
177
# File 'lib/capybara/selenium/node.rb', line 175

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

#disabled?Boolean

Returns:

  • (Boolean)


152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/capybara/selenium/node.rb', line 152

def disabled?
  # workaround for selenium-webdriver/geckodriver reporting elements as enabled when they are nested in disabling elements
  if driver.marionette?
    if %w[option optgroup].include? tag_name
      !native.enabled? || find_xpath("parent::*[self::optgroup or self::select]")[0].disabled?
    else
      !native.enabled? || !find_xpath("parent::fieldset[@disabled] | ancestor::*[not(self::legend) or preceding-sibling::legend][parent::fieldset[@disabled]]").empty?
    end
  else
    !native.enabled?
  end
end

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



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

def double_click(keys = [], options = {})
  scroll_if_needed do
    action_with_modifiers(keys, options) do |a|
      if options[:x] && options[:y]
        a.double_click
      else
        a.double_click(native)
      end
    end
  end
end

#drag_to(element) ⇒ Object



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

def drag_to(element)
  scroll_if_needed do
    driver.browser.action.drag_and_drop(native, element.native).perform
  end
end

#find_css(locator) ⇒ Object



183
184
185
# File 'lib/capybara/selenium/node.rb', line 183

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

#find_xpath(locator) ⇒ Object



179
180
181
# File 'lib/capybara/selenium/node.rb', line 179

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

#hoverObject



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

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

#multiple?Boolean

Returns:

  • (Boolean)


170
171
172
173
# File 'lib/capybara/selenium/node.rb', line 170

def multiple?
  multiple = self[:multiple]
  multiple and multiple != "false"
end

#pathObject



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/capybara/selenium/node.rb', line 191

def path
  path = find_xpath('ancestor::*').reverse
  path.unshift self

  result = []
  while (node = path.shift)
    parent = path.first

    if parent
      siblings = parent.find_xpath(node.tag_name)
      if siblings.size == 1
        result.unshift node.tag_name
      else
        index = siblings.index(node)
        result.unshift "#{node.tag_name}[#{index + 1}]"
      end
    else
      result.unshift node.tag_name
    end
  end

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

#readonly?Boolean

Returns:

  • (Boolean)


165
166
167
168
# File 'lib/capybara/selenium/node.rb', line 165

def readonly?
  readonly = self[:readonly]
  readonly and readonly != "false"
end

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



97
98
99
100
101
102
103
104
105
106
107
# File 'lib/capybara/selenium/node.rb', line 97

def right_click(keys = [], options = {})
  scroll_if_needed do
    action_with_modifiers(keys, options) do |a|
      if options[:x] && options[:y]
        a.context_click
      else
        a.context_click(native)
      end
    end
  end
end

#select_optionObject



63
64
65
# File 'lib/capybara/selenium/node.rb', line 63

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

#selected?Boolean Also known as: checked?

Returns:

  • (Boolean)


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

def selected?
  selected = native.selected?
  selected and selected != "false"
end

#send_keys(*args) ⇒ Object



121
122
123
# File 'lib/capybara/selenium/node.rb', line 121

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)


39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/capybara/selenium/node.rb', line 39

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?
  tag_name = self.tag_name
  type = self[:type]

  case tag_name
  when 'input'
    case type
    when 'radio'
      click
    when 'checkbox'
      click if value ^ checked?
    when 'file'
      set_file(value)
    else
      set_text(value, options)
    end
  when 'textarea'
    set_text(value, options)
  else
    set_content_editable(value) if content_editable?
  end
end

#tag_nameObject



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

def tag_name
  native.tag_name.downcase
end

#unselect_optionObject



67
68
69
70
# File 'lib/capybara/selenium/node.rb', line 67

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

#valueObject



20
21
22
23
24
25
26
# File 'lib/capybara/selenium/node.rb', line 20

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

#visible?Boolean

Returns:

  • (Boolean)


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

def visible?
  displayed = native.displayed?
  displayed and displayed != "false"
end

#visible_textObject



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

def visible_text
  # Selenium doesn't normalize Unicode whitespace.
  Capybara::Helpers.normalize_whitespace(native.text)
end