Class: Watir::Element

Inherits:
Object show all
Includes:
Comparable, Container, DragAndDropHelper, ElementExtensions, Exception
Defined in:
lib/watir-classic/element.rb

Overview

Base class for html elements. This is not a class that users would normally access.

Constant Summary collapse

TO_S_SIZE =

number of spaces that separate the property from the value in the to_s method

14

Instance Attribute Summary collapse

Attributes included from Container

#page_container

Instance Method Summary collapse

Methods included from DragAndDropHelper

#drag_and_drop_by, #drag_and_drop_on

Methods included from Container

#alert, #locator_for, #modal_dialog, #set_container, support_element, #wait

Methods included from Exception

message_for_unable_to_locate

Methods included from ElementExtensions

#present?, #wait_until_present, #wait_while_present, #when_present

Constructor Details

#initialize(container, specifiers) ⇒ Element

Returns a new instance of Element.

Raises:

  • (ArgumentError)


16
17
18
19
20
21
22
# File 'lib/watir-classic/element.rb', line 16

def initialize(container, specifiers)
  set_container container
  raise ArgumentError, "#{specifiers.inspect} has to be Hash" unless specifiers.is_a?(Hash)

  @o = specifiers[:ole_object]
  @specifiers = specifiers
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args, &block) ⇒ Object



421
422
423
424
425
426
427
428
429
430
431
432
433
# File 'lib/watir-classic/element.rb', line 421

def method_missing(method_name, *args, &block)
  meth = method_name.to_s
  if meth =~ /(.*)_no_wait/ && self.respond_to?($1)
    perform_action do
      ruby_code = generate_ruby_code(self, $1, *args)
      system(spawned_no_wait_command(ruby_code))
    end
  elsif meth =~ /^data_(.*)/
    self.send(:attribute_value, meth.gsub("_", "-")) || ''
  else
    super
  end
end

Instance Attribute Details

#containerObject

Returns the value of attribute container.



11
12
13
# File 'lib/watir-classic/element.rb', line 11

def container
  @container
end

Instance Method Details

#<=>(other) ⇒ Object



24
25
26
27
28
# File 'lib/watir-classic/element.rb', line 24

def <=> other
  assert_exists
  other.assert_exists
  ole_object.sourceindex <=> other.ole_object.sourceindex
end

#__ole_inner_elementsObject



129
130
131
132
# File 'lib/watir-classic/element.rb', line 129

def __ole_inner_elements
  assert_exists
  ole_object.all
end

#activeObjectHighLightColorObject



155
156
157
# File 'lib/watir-classic/element.rb', line 155

def activeObjectHighLightColor
  @container.activeObjectHighLightColor
end

#assert_enabledObject



70
71
72
# File 'lib/watir-classic/element.rb', line 70

def assert_enabled
  raise ObjectDisabledException, "object #{@specifiers.inspect} is disabled" unless enabled?
end

#assert_existsObject



62
63
64
65
66
67
68
# File 'lib/watir-classic/element.rb', line 62

def assert_exists
  locate
  unless ole_object
    exception_class = self.is_a?(Frame) ? UnknownFrameException : UnknownObjectException
    raise exception_class.new(Watir::Exception.message_for_unable_to_locate(@specifiers))
  end
end

#attribute_value(attribute_name) ⇒ Object

Get attribute value for any attribute of the element. Returns null if attribute doesn’t exist.



406
407
408
409
# File 'lib/watir-classic/element.rb', line 406

def attribute_value(attribute_name)
  assert_exists
  ole_object.getAttribute(attribute_name)
end

#clickObject

This method clicks the active element.

raises: UnknownObjectException  if the object is not found
ObjectDisabledException if the object is currently disabled


210
211
212
213
# File 'lib/watir-classic/element.rb', line 210

def click
  click!
  @container.wait
end

#click!Object



268
269
270
271
272
273
274
275
# File 'lib/watir-classic/element.rb', line 268

def click!
  perform_action do
    # Not sure why but in IE9 Document mode, passing a parameter
    # to click seems to work. Firing the onClick event breaks other tests
    # so this seems to be the safest change and also works fine in IE8
    ole_object.click(0)
  end
end

#create_event(event) ⇒ Object



306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
# File 'lib/watir-classic/element.rb', line 306

def create_event(event)
  event =~ /on(.*)/i
  event = $1 if $1
  event.downcase!
  # See http://www.howtocreate.co.uk/tutorials/javascript/domevents
  case event
    when 'abort', 'blur', 'change', 'error', 'focus', 'load',
         'reset', 'resize', 'scroll', 'select', 'submit', 'unload'
      event_name = :initEvent
      event_type = 'HTMLEvents'
      event_args = [event, true, true]
    when 'select'
      event_name = :initUIEvent
      event_type = 'UIEvent'
      event_args = [event, true, true, @container.page_container.document.parentWindow.window,0]
    when 'keydown', 'keypress', 'keyup'
      event_name = :initKeyboardEvent
      event_type = 'KeyboardEvent'
      # 'type', bubbles, cancelable, windowObject, ctrlKey, altKey, shiftKey, metaKey, keyCode, charCode
      event_args = [event, true, true, @container.page_container.document.parentWindow.window, false, false, false, false, 0, 0]
    when 'click', 'dblclick', 'mousedown', 'mousemove', 'mouseout', 'mouseover', 'mouseup',
         'contextmenu', 'drag', 'dragstart', 'dragenter', 'dragover', 'dragleave', 'dragend', 'drop', 'selectstart'
      event_name = :initMouseEvent
      event_type = 'MouseEvents'
      # 'type', bubbles, cancelable, windowObject, detail, screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget
      event_args = [event, true, true, @container.page_container.document.parentWindow.window, 1, 0, 0, 0, 0, false, false, false, false, 0, @container.page_container.document]
    else
      raise UnhandledEventException, "Don't know how to trigger event '#{event}'"
  end
  event = @container.page_container.document.createEvent(event_type)
  event.send event_name, *event_args
  event
end

#disabled?Boolean

Returns:

  • (Boolean)


375
376
377
378
# File 'lib/watir-classic/element.rb', line 375

def disabled?
  assert_exists
  false
end

#dispatch_event(event) ⇒ Object



298
299
300
301
302
303
304
# File 'lib/watir-classic/element.rb', line 298

def dispatch_event(event)
  if IE.version_parts.first.to_i >= 9 && container.page_container.document.documentMode.to_i >= 9
    ole_object.dispatchEvent(create_event(event))
  else
    ole_object.fireEvent(event)
  end
end

#documentObject



134
135
136
137
# File 'lib/watir-classic/element.rb', line 134

def document
  assert_exists
  ole_object
end

#double_clickObject



219
220
221
# File 'lib/watir-classic/element.rb', line 219

def double_click
  perform_action {fire_event("ondblclick"); @container.wait}
end

#enabled?Boolean

Returns true if the element is enabled, false if it isn’t.

raises: UnknownObjectException  if the object is not found

Returns:

  • (Boolean)


370
371
372
373
# File 'lib/watir-classic/element.rb', line 370

def enabled?
  assert_exists
  !disabled?
end

#exists?Boolean Also known as: exist?

Returns whether this element actually exists.

Returns:

  • (Boolean)


357
358
359
360
361
362
363
364
# File 'lib/watir-classic/element.rb', line 357

def exists?
  begin
    locate
  rescue WIN32OLERuntimeError, UnknownObjectException
    @o = nil
  end
  !!@o
end

#fire_event(event) ⇒ Object

Executes a user defined “fireEvent” for objects with JavaScript events tied to them such as DHTML menus.

usage: allows a generic way to fire javascript events on page objects such as "onMouseOver", "onClick", etc.
raises: UnknownObjectException  if the object is not found
        ObjectDisabledException if the object is currently disabled


294
295
296
# File 'lib/watir-classic/element.rb', line 294

def fire_event(event)
  perform_action {dispatch_event(event); @container.wait}
end

#flash(number = 10) ⇒ Object

Flash the element the specified number of times. Defaults to 10 flashes.



279
280
281
282
283
284
285
286
287
288
# File 'lib/watir-classic/element.rb', line 279

def flash number=10
  assert_exists
  number.times do
    highlight(:set)
    sleep 0.05
    highlight(:clear)
    sleep 0.05
  end
  nil
end

#focusObject

This method sets focus on the active element.

raises: UnknownObjectException  if the object is not found
        ObjectDisabledException if the object is currently disabled


343
344
345
346
347
348
# File 'lib/watir-classic/element.rb', line 343

def focus
  assert_exists
  assert_enabled
  @page_container.focus
  ole_object.focus(0)
end

#focused?Boolean

Returns:

  • (Boolean)


350
351
352
353
354
# File 'lib/watir-classic/element.rb', line 350

def focused?
  assert_exists
  assert_enabled
  @page_container.document.activeElement.uniqueNumber == unique_number
end

#inspectObject



45
46
47
# File 'lib/watir-classic/element.rb', line 45

def inspect
  '#<%s:0x%x located=%s specifiers=%s>' % [self.class, hash*2, !!ole_object, @specifiers.inspect]
end

#locateObject



32
33
34
# File 'lib/watir-classic/element.rb', line 32

def locate
  @o = @container.locator_for(TaggedElementLocator, @specifiers, self.class).locate
end

#ole_objectObject

Return the ole object, allowing any methods of the DOM that Watir doesn’t support to be used.



37
38
39
# File 'lib/watir-classic/element.rb', line 37

def ole_object
  @o
end

#ole_object=(o) ⇒ Object



41
42
43
# File 'lib/watir-classic/element.rb', line 41

def ole_object=(o)
  @o = o
end

#parentObject

Return the element immediately containing self.



140
141
142
143
144
145
# File 'lib/watir-classic/element.rb', line 140

def parent
  assert_exists
  parent_element = ole_object.parentelement
  return unless parent_element
  Element.new(self, :ole_object => parent_element).to_subtype
end

#right_clickObject



215
216
217
# File 'lib/watir-classic/element.rb', line 215

def right_click
  perform_action {fire_event("oncontextmenu"); @container.wait}
end

#send_keys(*keys) ⇒ Object

send keys to element



110
111
112
113
# File 'lib/watir-classic/element.rb', line 110

def send_keys(*keys)
  focus
  page_container.send_keys *keys
end

#styleObject

return the css style as a string



116
117
118
119
# File 'lib/watir-classic/element.rb', line 116

def style
  assert_exists
  ole_object.style.cssText
end

#tag_nameObject



86
87
88
89
# File 'lib/watir-classic/element.rb', line 86

def tag_name
  assert_exists
  @o.tagName.downcase
end

#textObject

Return the innerText of the object or an empty string if the object is not visible Raise an ObjectNotFound exception if the object cannot be found



124
125
126
127
# File 'lib/watir-classic/element.rb', line 124

def text
  assert_exists
  visible? ? ole_object.innerText.strip : ""
end

#to_sObject

Display basic details about the object. Sample output for a button is shown. Raises UnknownObjectException if the object is not found.

name      b4
type      button
id         b5
value      Disabled Button
disabled   true


175
176
177
178
# File 'lib/watir-classic/element.rb', line 175

def to_s
  assert_exists
  return string_creator.join("\n")
end

#to_subtypeObject

returns specific Element subclass for current Element



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/watir-classic/element.rb', line 92

def to_subtype
  assert_exists

  tag = tag_name
  if tag == "html"
    element(:ole_object => ole_object)
  elsif tag == "input"
    send(ole_object.invoke('type'), :ole_object => ole_object)
  elsif tag == "select"
    select_list(:ole_object => ole_object)
  elsif respond_to?(tag.downcase)
    send(tag.downcase, :ole_object => ole_object)
  else
    self
  end
end

#type_keysObject



151
152
153
# File 'lib/watir-classic/element.rb', line 151

def type_keys
  @type_keys || @container.type_keys
end

#typingspeedObject



147
148
149
# File 'lib/watir-classic/element.rb', line 147

def typingspeed
  @container.typingspeed
end

#visible?Boolean

If any parent element isn’t visible then we cannot write to the element. The only realiable way to determine this is to iterate up the DOM element tree checking every element to make sure it’s visible.

Returns:

  • (Boolean)


384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
# File 'lib/watir-classic/element.rb', line 384

def visible?
  # Now iterate up the DOM element tree and return false if any
  # parent element isn't visible 
  assert_exists
  object = @o
  while object
    begin
      if object.currentstyle.invoke('visibility') =~ /^hidden$/i
        return false
      end
      if object.currentstyle.invoke('display') =~ /^none$/i
        return false
      end
    rescue WIN32OLERuntimeError
    end
    object = object.parentElement
  end
  true
end