watir 1.9.2 → 2.0.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/CHANGES +27 -0
  2. data/VERSION +1 -1
  3. data/lib/watir/collections.rb +29 -387
  4. data/lib/watir/container.rb +14 -784
  5. data/lib/watir/dialogs/javascript.rb +7 -0
  6. data/lib/watir/element.rb +24 -4
  7. data/lib/watir/element_collections.rb +35 -57
  8. data/lib/watir/form.rb +13 -33
  9. data/lib/watir/frame.rb +14 -27
  10. data/lib/watir/html_element.rb +11 -3
  11. data/lib/watir/ie-class.rb +10 -1
  12. data/lib/watir/image.rb +3 -11
  13. data/lib/watir/input_elements.rb +11 -11
  14. data/lib/watir/link.rb +8 -15
  15. data/lib/watir/locator.rb +98 -73
  16. data/lib/watir/modal_dialog.rb +7 -1
  17. data/lib/watir/non_control_elements.rb +5 -89
  18. data/lib/watir/table.rb +46 -49
  19. data/unittests/checkbox_test.rb +39 -44
  20. data/unittests/checkbox_xpath_test.rb +2 -2
  21. data/unittests/css_test.rb +1 -1
  22. data/unittests/div_test.rb +43 -43
  23. data/unittests/div_xpath_test.rb +12 -12
  24. data/unittests/element_collections_test.rb +85 -0
  25. data/unittests/element_test.rb +4 -4
  26. data/unittests/form_test.rb +16 -19
  27. data/unittests/form_xpath_test.rb +6 -6
  28. data/unittests/frame_test.rb +114 -120
  29. data/unittests/html/multiple_specifiers.html +64 -0
  30. data/unittests/ie_test.rb +5 -5
  31. data/unittests/images_test.rb +12 -12
  32. data/unittests/index_specifier_test.rb +32 -0
  33. data/unittests/js_events_test.rb +3 -3
  34. data/unittests/links_multi_test.rb +4 -4
  35. data/unittests/links_test.rb +20 -20
  36. data/unittests/lists_test.rb +1 -1
  37. data/unittests/map_test.rb +1 -1
  38. data/unittests/multiple_specifiers_test.rb +29 -0
  39. data/unittests/no_wait_test.rb +2 -2
  40. data/unittests/pagecontainstext_test.rb +2 -2
  41. data/unittests/parent_child_test.rb +2 -2
  42. data/unittests/pre_test.rb +5 -5
  43. data/unittests/radios_test.rb +41 -60
  44. data/unittests/selectbox_test.rb +15 -15
  45. data/unittests/speed_settings_test.rb +2 -2
  46. data/unittests/table_and_tablerow_to_a_test.rb +7 -7
  47. data/unittests/table_test.rb +81 -94
  48. data/unittests/textfields_test.rb +26 -27
  49. data/unittests/windows/attach_to_new_window_test.rb +1 -1
  50. data/watir-rdoc.rb +1 -1
  51. data/watir.gemspec +1 -2
  52. metadata +34 -40
@@ -27,6 +27,13 @@ module Watir
27
27
  @window ||= ::RAutomation::Window.new(:title => @opts[:title] || /^(#{WINDOW_TITLES.join('|')})$/)
28
28
  end
29
29
 
30
+ Watir::Container.module_eval do
31
+ def javascript_dialog(opts={})
32
+ JavascriptDialog.new(opts)
33
+ end
34
+
35
+ alias_method :dialog, :javascript_dialog
36
+ end
30
37
  end
31
38
  end
32
39
 
@@ -10,15 +10,35 @@ module Watir
10
10
  # number of spaces that separate the property from the value in the to_s method
11
11
  TO_S_SIZE = 14
12
12
 
13
+ def self.inherited subclass
14
+ class_name = Watir::Util.demodulize(subclass.to_s)
15
+ method_name = Watir::Util.underscore(class_name)
16
+ Watir::Container.module_eval <<-RUBY
17
+ def #{method_name}(how={}, what=nil)
18
+ #{class_name}.new(self, how, what)
19
+ end
20
+
21
+ def #{method_name}s(how={}, what=nil)
22
+ #{class_name}s.new(self, how, what)
23
+ end
24
+ RUBY
25
+ end
26
+
13
27
  # ole_object - the ole object for the element being wrapped
14
28
  def initialize(ole_object)
15
29
  @o = ole_object
16
30
  @original_color = nil
17
31
  end
18
32
 
33
+ def locate
34
+ return if [Element, TableBodies].include? self.class
35
+ tag = self.class.constants.include?("TAG") ? self.class::TAG : self.class.name.split("::").last
36
+ @o = @container.tagged_element_locator(tag, @how, @what).locate
37
+ end
38
+
19
39
  # Return the ole object, allowing any methods of the DOM that Watir doesn't support to be used.
20
- def ole_object # BUG: should use an attribute reader and rename the instance variable
21
- return @o
40
+ def ole_object
41
+ @o
22
42
  end
23
43
 
24
44
  def ole_object=(o)
@@ -52,7 +72,7 @@ module Watir
52
72
 
53
73
  public
54
74
  def assert_exists
55
- locate if respond_to?(:locate)
75
+ locate
56
76
  unless ole_object
57
77
  raise UnknownObjectException.new(
58
78
  Watir::Exception.message_for_unable_to_locate(@how, @what))
@@ -371,7 +391,7 @@ module Watir
371
391
  # Returns whether this element actually exists.
372
392
  def exists?
373
393
  begin
374
- locate if defined?(locate)
394
+ locate
375
395
  rescue WIN32OLERuntimeError, UnknownObjectException
376
396
  @o = nil
377
397
  end
@@ -6,48 +6,40 @@ module Watir
6
6
 
7
7
  # Super class for all the iteractor classes
8
8
  # * container - an instance of an IE object
9
- def initialize(container)
9
+ def initialize(container, how, what)
10
+ if how == :index || (how.is_a?(Hash) && how[:index])
11
+ _how = what ? "#{how.inspect}, #{what.inspect}" : "#{how.inspect}"
12
+ raise Exception::MissingWayOfFindingObjectException,
13
+ "#{self.class} does not support attribute :index in #{_how}"
14
+ end
15
+
10
16
  @container = container
17
+ @how = how
18
+ @what = what
19
+ @length = length
11
20
  @page_container = container.page_container
12
- @length = length # defined by subclasses
13
-
14
- # set up the items we want to display when the show method is used
15
- set_show_items
16
- end
17
-
18
- private
19
- def set_show_items
20
- @show_attributes = AttributeLengthPairs.new("id", 20)
21
- @show_attributes.add("name", 20)
22
21
  end
23
22
 
24
- public
25
- def get_length_of_input_objects(object_type)
26
- object_types =
27
- if object_type.kind_of? Array
28
- object_type
29
- else
30
- [object_type]
31
- end
32
-
33
- length = 0
34
- objects = @container.document.getElementsByTagName("INPUT")
35
- if objects.length > 0
36
- objects.each do |o|
37
- length += 1 if object_types.include?(o.invoke("type").downcase)
38
- end
39
- end
40
- return length
23
+ def length
24
+ count = 0
25
+ each {|element| count += 1 }
26
+ count
41
27
  end
42
-
28
+
29
+ alias_method :size, :length
30
+
43
31
  # iterate through each of the elements in the collection in turn
44
32
  def each
45
- 0.upto(@length-1) { |i| yield iterator_object(i) }
33
+ @container.tagged_element_locator(element_tag, @how, @what, element_class).each {|element| yield element}
46
34
  end
47
35
 
48
36
  # allows access to a specific item in the collection
49
37
  def [](n)
50
- return iterator_object(n-1)
38
+ unless n.between?(0, length - 1)
39
+ raise Exception::MissingWayOfFindingObjectException,
40
+ "Can't find #{element_tag.downcase} with :index #{n} from #{self.class} with size of #{length}"
41
+ end
42
+ return iterator_object(n)
51
43
  end
52
44
 
53
45
  def first
@@ -58,29 +50,6 @@ module Watir
58
50
  iterator_object(length - 1)
59
51
  end
60
52
 
61
- # this method is the way to show the objects, normally used from irb
62
- def show
63
- s = "index".ljust(6)
64
- @show_attributes.each do |attribute_length_pair|
65
- s += attribute_length_pair.attribute.ljust(attribute_length_pair.length)
66
- end
67
-
68
- index = 1
69
- self.each do |o|
70
- s += "\n"
71
- s += index.to_s.ljust(6)
72
- @show_attributes.each do |attribute_length_pair|
73
- begin
74
- s += eval('o.ole_object.invoke("#{attribute_length_pair.attribute}")').to_s.ljust(attribute_length_pair.length)
75
- rescue => e
76
- s += " ".ljust(attribute_length_pair.length)
77
- end
78
- end
79
- index += 1
80
- end
81
- puts s
82
- end
83
-
84
53
  def to_s
85
54
  map { |e| e.to_s }.join("\n")
86
55
  end
@@ -89,10 +58,19 @@ module Watir
89
58
  '#<%s:0x%x length=%s container=%s>' % [self.class, hash*2, @length.inspect, @container.inspect]
90
59
  end
91
60
 
92
- # this method creates an object of the correct type that the iterators use
93
61
  private
62
+
94
63
  def iterator_object(i)
95
- element_class.new(@container, :index, i + 1)
64
+ count = 0
65
+ each {|e| return e if count == i; count += 1}
66
+ end
67
+
68
+ def element_class
69
+ Watir.const_get self.class.name.split("::").last.chop
70
+ end
71
+
72
+ def element_tag
73
+ element_class.constants.include?("TAG") ? element_class::TAG : element_class.name.split("::").last
96
74
  end
97
75
  end
98
- end
76
+ end
@@ -1,8 +1,16 @@
1
1
  module Watir
2
2
 
3
- # Forms
3
+ class Form < Element
4
+ # * container - the containing object, normally an instance of IE
5
+ # * how - symbol - how we access the form (:name, :id, :index, :action, :method)
6
+ # * what - what we use to access the form
7
+ def initialize(container, how, what)
8
+ set_container container
9
+ @how = how
10
+ @what = what
11
+ copy_test_config container
12
+ end
4
13
 
5
- class FormElement < Element
6
14
  def_wrap_guard :action
7
15
 
8
16
  def name
@@ -22,38 +30,10 @@ module Watir
22
30
  else
23
31
  super(arg)
24
32
  end
25
- end
26
- end
27
-
28
- # Form Factory object
29
- class Form < FormElement
30
- include Container
31
-
32
- attr_accessor :form
33
-
34
- # * container - the containing object, normally an instance of IE
35
- # * how - symbol - how we access the form (:name, :id, :index, :action, :method)
36
- # * what - what we use to access the form
37
- def initialize(container, how, what)
38
- set_container container
39
- @how = how
40
- @what = what
41
- copy_test_config container
42
- end
33
+ end
43
34
 
44
35
  def locate
45
- log "Get form how is #{@how} what is #{@what} "
46
-
47
- # Get form using xpath.
48
- if @how == :xpath
49
- @o = @container.element_by_xpath(@what)
50
- elsif @how == :css
51
- @o = @container.element_by_css(@what)
52
- else
53
- locator = FormLocator.new(@container, 'FORM')
54
- locator.set_specifier(@how, @what)
55
- @o = locator.locate
56
- end
36
+ @o = @container.locator_for(FormLocator, @how, @what).locate
57
37
  end
58
38
 
59
39
  # Submit the data -- equivalent to pressing Enter or Return to submit a form.
@@ -119,4 +99,4 @@ module Watir
119
99
 
120
100
  end # class Form
121
101
 
122
- end
102
+ end
@@ -1,35 +1,22 @@
1
1
  module Watir
2
2
  class Frame < Element
3
3
  include PageContainer
4
+ TAG = ['FRAME', 'IFRAME']
5
+
6
+ attr_accessor :document
4
7
 
5
8
  # Find the frame denoted by how and what in the container and return its ole_object
6
9
  def locate
7
- @o = nil
8
- if @how == :xpath
9
- @o = @container.element_by_xpath(@what)
10
- elsif @how == :css
11
- @o = @container.element_by_css(@what)
12
- else
13
- locator = FrameLocator.new(@container)
14
- locator.set_specifier(@how, @what)
15
- ['FRAME', 'IFRAME'].each do |frame_tag|
16
- locator.tag = frame_tag
17
- located_frame, document = locator.locate
18
- unless (located_frame.nil? && document.nil?)
19
- @o = located_frame
20
- begin
21
- @document = document.document
22
- rescue WIN32OLERuntimeError => e
23
- if e.message =~ /Access is denied/
24
- # This frame's content is not directly accessible but let the
25
- # user continue so they can access the frame properties
26
- else
27
- raise e
28
- end
29
- end
30
- break
31
- end
32
- end
10
+ frame, document = @container.locator_for(FrameLocator, @how, @what).locate
11
+ if frame && document
12
+ @o = frame
13
+ begin
14
+ @document = document.document
15
+ rescue WIN32OLERuntimeError => e
16
+ # This frame's content is not directly accessible but let the
17
+ # user continue so they can access the frame properties
18
+ raise e unless e.message =~ /Access is denied/
19
+ end
33
20
  end
34
21
  end
35
22
 
@@ -59,4 +46,4 @@ module Watir
59
46
  end
60
47
 
61
48
  end
62
- end
49
+ end
@@ -4,6 +4,8 @@
4
4
  # all share the same class.
5
5
  module Watir
6
6
  class HTMLElement < Element
7
+ TAG = "*"
8
+
7
9
  def initialize(container, how, what)
8
10
  set_container container
9
11
  @how = how
@@ -15,8 +17,14 @@ module Watir
15
17
  super nil
16
18
  end
17
19
 
18
- def locate
19
- @o = @container.locate_tagged_element('*', @how, @what)
20
+ Watir::Container.module_eval do
21
+ def element(how={}, what=nil)
22
+ HTMLElement.new(self, how, what)
23
+ end
24
+
25
+ def elements(how={}, what=nil)
26
+ HTMLElements.new(self, how, what)
27
+ end
20
28
  end
21
29
  end
22
- end
30
+ end
@@ -17,7 +17,7 @@ module Watir
17
17
  # Return the options used when creating new instances of IE.
18
18
  # BUG: this interface invites misunderstanding/misuse such as IE.options[:speed] = :zippy]
19
19
  def self.options
20
- {:speed => self.speed, :visible => self.visible, :attach_timeout => self.attach_timeout}
20
+ {:speed => self.speed, :visible => self.visible, :attach_timeout => self.attach_timeout, :zero_based_indexing => self.zero_based_indexing}
21
21
  end
22
22
  # set values for options used when creating new instances of IE.
23
23
  def self.set_options options
@@ -49,6 +49,15 @@ module Watir
49
49
  @@visible = x
50
50
  end
51
51
 
52
+ @@zero_based_indexing = true
53
+ def self.zero_based_indexing= enabled
54
+ @@zero_based_indexing = enabled
55
+ end
56
+
57
+ def self.zero_based_indexing
58
+ @@zero_based_indexing
59
+ end
60
+
52
61
  # Used internally to determine when IE has finished loading a page
53
62
  READYSTATES = {:complete => 4}
54
63
 
@@ -6,6 +6,8 @@ module Watir
6
6
  # many of the methods available to this object are inherited from the Element class
7
7
  #
8
8
  class Image < Element
9
+ TAG = "IMG"
10
+
9
11
  def initialize(container, how, what)
10
12
  set_container container
11
13
  @how = how
@@ -13,16 +15,6 @@ module Watir
13
15
  super nil
14
16
  end
15
17
 
16
- def locate
17
- if @how == :xpath
18
- @o = @container.element_by_xpath(@what)
19
- elsif @how == :css
20
- @o = @container.element_by_css(@what)
21
- else
22
- @o = @container.locate_tagged_element('IMG', @how, @what)
23
- end
24
- end
25
-
26
18
  # this method produces the properties for an image as an array
27
19
  def image_string_creator
28
20
  n = []
@@ -131,4 +123,4 @@ module Watir
131
123
  private :fill_save_image_dialog
132
124
  end
133
125
 
134
- end
126
+ end
@@ -2,7 +2,8 @@ module Watir
2
2
 
3
3
  class InputElement < Element #:nodoc:all
4
4
  def locate
5
- @o = @container.locate_input_element(@how, @what, self.class::INPUT_TYPES)
5
+ locator_or_element = @container.input_element_locator(@how, @what, self.class::INPUT_TYPES, self.class)
6
+ @o = locator_or_element.is_a?(WIN32OLE) ? locator_or_element : locator_or_element.locate
6
7
  end
7
8
  def initialize(container, how, what)
8
9
  set_container container
@@ -482,14 +483,6 @@ module Watir
482
483
  #--
483
484
  # most of the methods available to this element are inherited from the Element class
484
485
  class RadioCheckCommon < InputElement
485
- def locate #:nodoc:
486
- @o = @container.locate_input_element(@how, @what, self.class::INPUT_TYPES, @value, self.class)
487
- end
488
- def initialize(container, how, what, value=nil)
489
- super container, how, what
490
- @value = value
491
- end
492
-
493
486
  def inspect
494
487
  '#<%s:0x%x located=%s how=%s what=%s value=%s>' % [self.class, hash*2, !!ole_object, @how.inspect, @what.inspect, @value.inspect]
495
488
  end
@@ -542,7 +535,7 @@ module Watir
542
535
 
543
536
  # This class is the watir representation of a check box.
544
537
  # Normally a user would not need to create this object as it is returned by the Watir::Container#checkbox method
545
- class CheckBox < RadioCheckCommon
538
+ class Checkbox < RadioCheckCommon
546
539
  INPUT_TYPES = ["checkbox"]
547
540
  # This method checks or unchecks the checkbox.
548
541
  # With no arguments supplied it sets the checkbox.
@@ -567,6 +560,13 @@ module Watir
567
560
  set false
568
561
  end
569
562
 
563
+ Watir::Container.module_eval do
564
+ remove_method :checkboxs
565
+
566
+ def checkboxes(how={}, what=nil)
567
+ Checkboxes.new(self, how, what)
568
+ end
569
+ end
570
570
  end
571
571
 
572
- end
572
+ end
@@ -5,6 +5,8 @@ module Watir
5
5
  # many of the methods available to this object are inherited from the Element class
6
6
  #
7
7
  class Link < Element
8
+ TAG = "A"
9
+
8
10
  # Returns an initialized instance of a link object
9
11
  # * container - an instance of a container
10
12
  # * how - symbol - how we access the link
@@ -16,20 +18,6 @@ module Watir
16
18
  super(nil)
17
19
  end
18
20
 
19
- def locate
20
- if @how == :xpath
21
- @o = @container.element_by_xpath(@what)
22
- elsif @how == :css
23
- @o = @container.element_by_css(@what)
24
- else
25
- begin
26
- @o = @container.locate_tagged_element('A', @how, @what)
27
- rescue UnknownObjectException
28
- @o = nil
29
- end
30
- end
31
- end
32
-
33
21
  # if an image is used as part of the link, this will return true
34
22
  def link_has_image
35
23
  assert_exists
@@ -62,6 +50,11 @@ module Watir
62
50
  r = r + link_string_creator
63
51
  return r.join("\n")
64
52
  end
53
+
54
+ Watir::Container.module_eval do
55
+ alias_method :a, :link
56
+ alias_method :as, :links
57
+ end
65
58
  end
66
59
 
67
- end
60
+ end