watir 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. data/readme.rb +211 -0
  2. data/unittests/WindowLogonExample.rb +30 -0
  3. data/unittests/WindowLogonExtra.rb +7 -0
  4. data/unittests/all_tests.rb +10 -0
  5. data/unittests/all_tests_concurrent.rb +57 -0
  6. data/unittests/attachToExistingWindow_test.rb +40 -0
  7. data/unittests/buttons_test.rb +131 -0
  8. data/unittests/checkbox_test.rb +149 -0
  9. data/unittests/core_tests.rb +9 -0
  10. data/unittests/css_test.rb +60 -0
  11. data/unittests/div_test.rb +179 -0
  12. data/unittests/errorchecker_test.rb +29 -0
  13. data/unittests/filefield_test.rb +35 -0
  14. data/unittests/form_test.rb +279 -0
  15. data/unittests/frame_test.rb +141 -0
  16. data/unittests/html/blankpage.html +12 -0
  17. data/unittests/html/buttons1.html +40 -0
  18. data/unittests/html/checkboxes1.html +69 -0
  19. data/unittests/html/complex_table.html +36 -0
  20. data/unittests/html/cssTest.html +42 -0
  21. data/unittests/html/div.html +105 -0
  22. data/unittests/html/fileupload.html +45 -0
  23. data/unittests/html/formTest1.html +39 -0
  24. data/unittests/html/forms2.html +45 -0
  25. data/unittests/html/forms3.html +132 -0
  26. data/unittests/html/forms4.html +27 -0
  27. data/unittests/html/frame_buttons.html +4 -0
  28. data/unittests/html/frame_links.html +4 -0
  29. data/unittests/html/frame_multi.html +5 -0
  30. data/unittests/html/iframeTest.html +13 -0
  31. data/unittests/html/iframeTest1.html +7 -0
  32. data/unittests/html/iframeTest2.html +6 -0
  33. data/unittests/html/images/1.gif +0 -0
  34. data/unittests/html/images/2.GIF +0 -0
  35. data/unittests/html/images/3.GIF +0 -0
  36. data/unittests/html/images/button.jpg +0 -0
  37. data/unittests/html/images/circle.jpg +0 -0
  38. data/unittests/html/images/minus.GIF +0 -0
  39. data/unittests/html/images/originaltriangle.jpg +0 -0
  40. data/unittests/html/images/plus.gif +0 -0
  41. data/unittests/html/images/square.jpg +0 -0
  42. data/unittests/html/images/triangle.jpg +0 -0
  43. data/unittests/html/images1.html +52 -0
  44. data/unittests/html/javascriptevents.html +39 -0
  45. data/unittests/html/link_pass.html +11 -0
  46. data/unittests/html/links1.html +37 -0
  47. data/unittests/html/links2.html +11 -0
  48. data/unittests/html/nestedFrames.html +6 -0
  49. data/unittests/html/pass.html +10 -0
  50. data/unittests/html/popups1.html +60 -0
  51. data/unittests/html/radioButtons1.html +71 -0
  52. data/unittests/html/select_tealeaf.html +54 -0
  53. data/unittests/html/selectboxes1.html +55 -0
  54. data/unittests/html/simple_table.html +26 -0
  55. data/unittests/html/simple_table_buttons.html +104 -0
  56. data/unittests/html/simple_table_columns.html +76 -0
  57. data/unittests/html/table1.html +142 -0
  58. data/unittests/html/textarea.html +30 -0
  59. data/unittests/html/textfields1.html +87 -0
  60. data/unittests/html/textsearch.html +44 -0
  61. data/unittests/ie_mock.rb +93 -0
  62. data/unittests/ie_test.rb +50 -0
  63. data/unittests/images_test.rb +179 -0
  64. data/unittests/iostring.rb +30 -0
  65. data/unittests/iostring_test.rb +48 -0
  66. data/unittests/js_events_test.rb +77 -0
  67. data/unittests/jscriptExtraAlert.rb +6 -0
  68. data/unittests/jscriptExtraConfirmCancel.rb +7 -0
  69. data/unittests/jscriptExtraConfirmOk.rb +7 -0
  70. data/unittests/jscriptPushButton.rb +5 -0
  71. data/unittests/jscript_test.rb +57 -0
  72. data/unittests/links_test.rb +169 -0
  73. data/unittests/minmax_test.rb +31 -0
  74. data/unittests/navigate_test.rb +56 -0
  75. data/unittests/non_core_tests.rb +9 -0
  76. data/unittests/pagecontainstext_test.rb +49 -0
  77. data/unittests/popups_test.rb +44 -0
  78. data/unittests/radios_test.rb +164 -0
  79. data/unittests/screen_capture_test.rb +53 -0
  80. data/unittests/selectbox_test.rb +197 -0
  81. data/unittests/send_keys_test.rb +29 -0
  82. data/unittests/setup.rb +47 -0
  83. data/unittests/table_test.rb +306 -0
  84. data/unittests/textAreafields_test.rb +81 -0
  85. data/unittests/textfields_test.rb +239 -0
  86. data/watir.rb +3744 -0
  87. data/watir/AutoItX3.dll +0 -0
  88. data/watir/WindowHelper.rb +47 -0
  89. data/watir/camel_case.rb +37 -0
  90. data/watir/clickJSDialog.rb +19 -0
  91. data/watir/cookiemanager.rb +53 -0
  92. data/watir/exceptions.rb +60 -0
  93. data/watir/screen_capture.rb +115 -0
  94. data/watir/setFileDialog.rb +16 -0
  95. data/watir/testUnitAddons.rb +47 -0
  96. data/watir/watir_simple.rb +475 -0
  97. data/watir/winClicker.rb +505 -0
  98. metadata +152 -0
@@ -0,0 +1,239 @@
1
+ # feature tests for Text Fields
2
+ # revision: $Revision: 1.31 $
3
+
4
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..') if $0 == __FILE__
5
+ require 'unittests/setup'
6
+
7
+ class TC_Fields < Test::Unit::TestCase
8
+ include Watir
9
+
10
+ def setup()
11
+ $ie.goto($htmlRoot + "textfields1.html")
12
+ end
13
+
14
+ def test_text_field_exists
15
+ assert($ie.text_field(:name, "text1").exists?)
16
+ assert_false($ie.text_field(:name, "missing").exists?)
17
+
18
+ assert($ie.text_field(:id, "text2").exists?)
19
+ assert_false($ie.text_field(:id, "alsomissing").exists?)
20
+
21
+ assert($ie.text_field(:beforeText , "This Text After").exists? )
22
+ assert($ie.text_field(:afterText , "This Text Before").exists? )
23
+
24
+ assert($ie.text_field(:beforeText , /after/i).exists? )
25
+ assert($ie.text_field(:afterText , /before/i).exists? )
26
+ end
27
+
28
+ def test_text_field_dragContentsTo
29
+ $ie.text_field(:name, "text1").dragContentsTo(:id, "text2")
30
+ assert_equal($ie.text_field(:name, "text1").getContents, "" )
31
+ assert_equal($ie.text_field(:id, "text2").getContents, "goodbye allHello World" )
32
+ end
33
+
34
+ def test_text_field_VerifyContents
35
+ assert($ie.text_field(:name, "text1").verify_contains("Hello World") )
36
+ assert($ie.text_field(:name, "text1").verify_contains(/Hello\sW/ ) )
37
+ assert_false($ie.text_field(:name, "text1").verify_contains("Ruby") )
38
+ assert_false($ie.text_field(:name, "text1").verify_contains(/R/) )
39
+ assert_raises(UnknownObjectException , "UnknownObjectException was supposed to be thrown" ) { $ie.text_field(:name, "NoName").verify_contains("No field to get a value of") }
40
+
41
+ assert($ie.text_field(:id, "text2").verify_contains("goodbye all") )
42
+ assert_raises(UnknownObjectException , "UnknownObjectException was supposed to be thrown" ) { $ie.text_field(:id, "noID").verify_contains("No field to get a value of") }
43
+
44
+ end
45
+
46
+ def test_text_field_enabled
47
+ assert_false($ie.text_field(:name, "disabled").enabled? )
48
+ assert($ie.text_field(:name, "text1").enabled? )
49
+ assert($ie.text_field(:id, "text2").enabled? )
50
+ end
51
+
52
+ def test_text_field_readOnly
53
+ assert_false($ie.text_field(:name, "disabled").readonly? )
54
+ assert($ie.text_field(:name, "readOnly").readonly? )
55
+ assert($ie.text_field(:id, "readOnly2").readonly? )
56
+ end
57
+
58
+ def test_text_field_getContents()
59
+ assert_raises(UnknownObjectException , "ObjectReadOnlyException was supposed to be thrown" ) { $ie.text_field(:name, "missing_field").append("Some Text") }
60
+ assert_equal( "Hello World" , $ie.text_field(:name, "text1").getContents )
61
+ end
62
+
63
+ def test_TextField_to_s
64
+ expected = [build_to_s_regex("type", "text"),
65
+ build_to_s_regex("id", ""),
66
+ build_to_s_regex("name", "text1"),
67
+ build_to_s_regex("value", "Hello World"),
68
+ build_to_s_regex("disabled", "false"),
69
+ build_to_s_regex("length", "20"),
70
+ build_to_s_regex("max length", "2147483647"),
71
+ build_to_s_regex("read only", "false")]
72
+ items = $ie.text_field(:index, 1).to_s.split(/\n/)
73
+ expected.each_with_index{|regex, x| assert(regex =~ items[x]) }
74
+ expected[1] = build_to_s_regex("id", "text2")
75
+ expected[2] = build_to_s_regex("name", "")
76
+ expected[3] = build_to_s_regex("value", "goodbye all")
77
+ items = $ie.text_field(:index, 2).to_s.split(/\n/)
78
+ expected.each_with_index{|regex, x| assert(regex =~ items[x]) }
79
+ assert_raises(UnknownObjectException , "UnknownObjectException was supposed to be thrown" ) { $ie.text_field(:index, 999 ).to_s}
80
+ end
81
+
82
+ def build_to_s_regex(lhs, rhs)
83
+ Regexp.new("^#{lhs}: +#{rhs}$")
84
+ end
85
+
86
+ def test_text_field_Append
87
+ assert_raises(ObjectReadOnlyException , "ObjectReadOnlyException was supposed to be thrown" ) { $ie.text_field(:id, "readOnly2").append("Some Text") }
88
+ assert_raises(ObjectDisabledException , "ObjectDisabledException was supposed to be thrown" ) { $ie.text_field(:name, "disabled").append("Some Text") }
89
+ assert_raises(UnknownObjectException , "UnknownObjectException was supposed to be thrown" ) { $ie.text_field(:name, "missing_field").append("Some Text") }
90
+
91
+ $ie.text_field(:name, "text1").append(" Some Text")
92
+ assert_equal( "Hello World Some Text" , $ie.text_field(:name, "text1").getContents )
93
+
94
+ # may need this to see that it really happened
95
+ #puts "press return to continue"
96
+ #gets
97
+
98
+ end
99
+
100
+
101
+ def test_text_field_Clear
102
+ assert_raises(ObjectReadOnlyException , "ObjectReadOnlyException was supposed to be thrown" ) { $ie.text_field(:id, "readOnly2").append("Some Text") }
103
+ assert_raises(ObjectDisabledException , "ObjectReadOnlyException was supposed to be thrown" ) { $ie.text_field(:name, "disabled").append("Some Text") }
104
+ assert_raises(UnknownObjectException , "ObjectReadOnlyException was supposed to be thrown" ) { $ie.text_field(:name, "missing_field").append("Some Text") }
105
+
106
+ $ie.text_field(:name, "text1").clear()
107
+ assert_equal( "" , $ie.text_field(:name, "text1").getContents )
108
+
109
+ # may need this to see that it really happened
110
+ #puts "press return to continue"
111
+ #gets
112
+
113
+ end
114
+
115
+ def test_text_field_Set
116
+ assert_raises(ObjectReadOnlyException , "ObjectReadOnlyException was supposed to be thrown" ) { $ie.text_field(:id, "readOnly2").append("Some Text") }
117
+ assert_raises(ObjectDisabledException , "ObjectReadOnlyException was supposed to be thrown" ) { $ie.text_field(:name, "disabled").append("Some Text") }
118
+ assert_raises(UnknownObjectException , "ObjectReadOnlyException was supposed to be thrown" ) { $ie.text_field(:name, "missing_field").append("Some Text") }
119
+
120
+ $ie.text_field(:name, "text1").set("watir IE Controller")
121
+ assert_equal( "watir IE Controller" , $ie.text_field(:name, "text1").getContents )
122
+
123
+ # may need this to see that it really happened
124
+ #puts "press return to continue"
125
+ #gets
126
+ end
127
+
128
+ def test_text_field_properties
129
+
130
+ assert_raises(UnknownObjectException , "UnknownObjectException was supposed to be thrown" ) { $ie.text_field(:index, 199).value}
131
+ assert_raises(UnknownObjectException , "UnknownObjectException was supposed to be thrown" ) { $ie.text_field(:index, 199).name }
132
+ assert_raises(UnknownObjectException , "UnknownObjectException was supposed to be thrown" ) { $ie.text_field(:index, 199).id }
133
+ assert_raises(UnknownObjectException , "UnknownObjectException was supposed to be thrown" ) { $ie.text_field(:index, 199).disabled }
134
+ assert_raises(UnknownObjectException , "UnknownObjectException was supposed to be thrown" ) { $ie.text_field(:index, 199).type }
135
+
136
+ assert_equal( "Hello World" , $ie.text_field(:index, 1).value )
137
+ assert_equal( "text" , $ie.text_field(:index, 1).type)
138
+ assert_equal( "text1" , $ie.text_field(:index, 1).name )
139
+ assert_equal( "" , $ie.text_field(:index, 1).id )
140
+ assert_equal( false , $ie.text_field(:index, 1).disabled )
141
+
142
+ assert_equal( "" , $ie.text_field(:index, 2).name )
143
+ assert_equal( "text2" , $ie.text_field(:index, 2).id )
144
+
145
+ assert( $ie.text_field(:index, 3).disabled )
146
+
147
+ assert_equal( "This used to test :afterText" , $ie.text_field(:name, "aftertest" ).title )
148
+ assert_equal( "" , $ie.text_field(:index, 1 ).title )
149
+
150
+
151
+ end
152
+
153
+ def test_text_field_iterators
154
+
155
+ assert_equal( 12 , $ie.text_fields.length )
156
+
157
+ # watir is 1 based, so this is the first text field
158
+ assert_equal( "Hello World" , $ie.text_fields[1].value )
159
+ assert_equal( "text1" , $ie.text_fields[1].name )
160
+
161
+ assert_equal( "password" , $ie.text_fields[ $ie.text_fields.length ].type)
162
+
163
+
164
+ index = 1
165
+ $ie.text_fields.each do |t|
166
+ assert_equal( $ie.text_field(:index, index).value, t.value )
167
+ assert_equal( $ie.text_field(:index, index).id, t.id )
168
+ assert_equal( $ie.text_field(:index, index).name, t.name )
169
+ index +=1
170
+ end
171
+ assert_equal( index-1, $ie.text_fields.length)
172
+
173
+ end
174
+
175
+ def test_JS_Events
176
+ $ie.text_field(:name , 'events_tester').set('p')
177
+
178
+ # the following line has an extra keypress at the begining, as we mimic the delete key being pressed
179
+ assert_equal( "keypresskeydownkeypresskeyup" , $ie.text_field(:name , 'events_text').value.gsub("\r\n" , "") )
180
+ $ie.button(:value , "Clear Events Box").click
181
+ $ie.text_field(:name , 'events_tester').set('ab')
182
+
183
+ # the following line has an extra keypress at the begining, as we mimic the delete key being pressed
184
+ assert_equal( "keypresskeydownkeypresskeyupkeydownkeypresskeyup" , $ie.text_field(:name , 'events_text').value.gsub("\r\n" , "") )
185
+
186
+ end
187
+
188
+ def test_password
189
+
190
+ $ie.text_field(:name , "password1").set("secret")
191
+ assert( 'secret' , $ie.text_field(:name , "password1").value )
192
+
193
+ $ie.text_field(:id , "password1").set("top_secret")
194
+ assert( 'top_secret' , $ie.text_field(:id, "password1").value )
195
+ end
196
+
197
+ def test_labels_iterator
198
+
199
+ assert_equal(3, $ie.labels.length)
200
+ assert_equal('Label For this Field' , $ie.labels[1].innerText.strip )
201
+ assert_equal('Password With ID ( the text here is a label for it )' , $ie.labels[3].innerText )
202
+
203
+ count=0
204
+ $ie.labels.each do |l|
205
+ count +=1
206
+ end
207
+ assert_equal(count, $ie.labels.length)
208
+
209
+
210
+ end
211
+
212
+ def test_label_properties
213
+ assert_raises(UnknownObjectException ) { $ie.label(:index,20).innerText }
214
+ assert_raises(UnknownObjectException ) { $ie.label(:index,20).for }
215
+ assert_raises(UnknownObjectException ) { $ie.label(:index,20).name }
216
+ assert_raises(UnknownObjectException ) { $ie.label(:index,20).type }
217
+ assert_raises(UnknownObjectException ) { $ie.label(:index,20).id }
218
+
219
+ assert_false( $ie.label(:index,10).exists? )
220
+ assert_false( $ie.label(:id,'missing').exists? )
221
+ assert( $ie.label(:index,1).exists? )
222
+
223
+
224
+ assert_equal( "" , $ie.label(:index,1).id )
225
+ assert_false( $ie.label(:index,1).disabled )
226
+ assert( $ie.label(:index,1).enabled?)
227
+
228
+
229
+ assert_equal( "label2" , $ie.label(:index,2).id )
230
+ assert_equal( "Label" , $ie.label(:index,2).type )
231
+
232
+ assert_equal( "Password With ID ( the text here is a label for it )" , $ie.label(:index,3).innerText)
233
+ assert_equal( "password1" , $ie.label(:index,3).for)
234
+ end
235
+
236
+
237
+
238
+
239
+ end
@@ -0,0 +1,3744 @@
1
+ =begin
2
+ license
3
+ ---------------------------------------------------------------------------
4
+ Copyright (c) 2004-2005, Paul Rogers and Bret Pettichord
5
+ All rights reserved.
6
+
7
+ Redistribution and use in source and binary forms, with or without
8
+ modification, are permitted provided that the following conditions are met:
9
+
10
+ 1. Redistributions of source code must retain the above copyright notice,
11
+ this list of conditions and the following disclaimer.
12
+
13
+ 2. Redistributions in binary form must reproduce the above copyright
14
+ notice, this list of conditions and the following disclaimer in the
15
+ documentation and/or other materials provided with the distribution.
16
+
17
+ 3. Neither the names Paul Rogers, Bret Pettichord nor the names of contributors to
18
+ this software may be used to endorse or promote products derived from this
19
+ software without specific prior written permission.
20
+
21
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
22
+ IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
23
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
25
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28
+ OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
+ --------------------------------------------------------------------------
33
+ (based on BSD Open Source License)
34
+ =end
35
+
36
+ # This is Watir, Web Application Testing In Ruby
37
+ # Home page is http://wtr.rubyforge.org
38
+ #
39
+ # Version "$Revision: 1.211.2.2 $"
40
+ #
41
+ # Typical usage:
42
+ # # include the controller
43
+ # require "watir"
44
+ # # go to the page you want to test
45
+ # ie = Watir::IE.start("http://myserver/mypage")
46
+ # # enter "Paul" into an input field named "username"
47
+ # ie.text_field(:name, "username").set("Paul")
48
+ # # enter "Ruby Co" into input field with id "company_ID"
49
+ # ie.text_field(:id ,"company_ID").set("Ruby Co")
50
+ # # click button that has a caption of "Cancel"
51
+ # ie.button(:value, "Cancel").click
52
+ #
53
+ # The ways that are available to identify an html object depend upon the object type, but include
54
+ # :id used for an object that has an ID attribute -- this is the best way!
55
+ # :name used for an object that has a name attribute.
56
+ # :value value of text fields, captions of buttons
57
+ # :index finds the nth object of the specified type - eg button(:index , 2) finds the second button. This is 1 based. <br>
58
+ # :beforeText finds the object immeditaley before the specified text. Doesnt work if the text is in a table cell
59
+ # :afterText finds the object immeditaley after the specified text. Doesnt work if the text is in a table cell
60
+ #
61
+
62
+
63
+ # These 2 web sites provide info on Internet Explorer and on the DOM as implemented by Internet Explorer
64
+ # http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/webbrowser/webbrowser.asp
65
+ # http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/overview/overview.asp
66
+
67
+ # command line options:
68
+ #
69
+ # -b (background) Run Internet Explorer invisible
70
+ # -f (fast) Run tests fast
71
+ # -x (spinner) Add a spinner that displays when pages are waiting to be loaded.
72
+
73
+ require 'win32ole'
74
+ require 'logger'
75
+ require 'watir/winClicker'
76
+ require 'watir/exceptions'
77
+
78
+ class String
79
+ def matches (x)
80
+ return self == x
81
+ end
82
+ end
83
+
84
+ class Regexp
85
+ def matches (x)
86
+ return self.match(x)
87
+ end
88
+ end
89
+
90
+ # ARGV needs to be deleted to enable the Test::Unit functionality that grabs
91
+ # the remaining ARGV as a filter on what tests to run.
92
+ # Note: this means that watir must be require'd BEFORE test/unit.
93
+ def command_line_flag(switch)
94
+ setting = ARGV.include?(switch)
95
+ ARGV.delete(switch)
96
+ return setting
97
+ end
98
+
99
+ # Constant to make Internet explorer minimisez. -b stands for background
100
+ $HIDE_IE = command_line_flag('-b')
101
+
102
+ # Constant to enable/disable the spinner
103
+ $ENABLE_SPINNER = command_line_flag('-x')
104
+
105
+ # Constant to set fast speed
106
+ $FAST_SPEED = command_line_flag('-f')
107
+
108
+ # Eat the -s command line switch (deprecated)
109
+ command_line_flag('-s')
110
+
111
+ module Watir
112
+ include Watir::Exception
113
+
114
+ # BUG: this won't work right until the null objects are pulled out
115
+ def exists?
116
+ begin
117
+ yield
118
+ true
119
+ rescue
120
+ false
121
+ end
122
+ end
123
+
124
+ class WatirLogger < Logger
125
+ def initialize( filName , logsToKeep, maxLogSize )
126
+ super( filName , logsToKeep, maxLogSize )
127
+ self.level = Logger::DEBUG
128
+ self.datetime_format = "%d-%b-%Y %H:%M:%S"
129
+ self.debug("Watir starting")
130
+ end
131
+ end
132
+
133
+ class DefaultLogger < Logger
134
+ def initialize()
135
+ super(STDERR)
136
+ self.level = Logger::WARN
137
+ self.datetime_format = "%d-%b-%Y %H:%M:%S"
138
+ self.info "Log started"
139
+ end
140
+ end
141
+
142
+ # This class displays the spinner object that appears in the console when a page is being loaded
143
+ class Spinner
144
+
145
+ def initialize(enabled = true)
146
+ @s = [ "\b/" , "\b|" , "\b\\" , "\b-"]
147
+ @i=0
148
+ @enabled = enabled
149
+ end
150
+
151
+ # reverse the direction of spinning
152
+ def reverse
153
+ @s.reverse!
154
+ end
155
+
156
+ def spin
157
+ print self.next if @enabled
158
+ end
159
+
160
+ # get the next character to display
161
+ def next
162
+ @i=@i+1
163
+ @i=0 if @i>@s.length-1
164
+ return @s[@i]
165
+ end
166
+ end
167
+
168
+ # This module contains the factory methods that are used to access most html objects
169
+ #
170
+ # For example, to access a button on a web page that has the following html
171
+ # <input type = button name= 'b1' value='Click Me' onClick='javascript:doSomething()'>
172
+ #
173
+ # the following watir code could be used
174
+ #
175
+ # ie.button(:name, 'b1').click
176
+ #
177
+ # or
178
+ #
179
+ # ie.button(:value, 'Click Me').to_s
180
+ #
181
+ # there are many methods available to the Button object
182
+ #
183
+ # Is includable for classes that have @ieController, document and document.body
184
+ module SupportsSubElements
185
+ include Watir::Exception
186
+
187
+ # this method returns the real Internet Explorer object, allowing access to objects, properties and methods that Watir doesnot support
188
+ def ie
189
+ return @ieController
190
+ end
191
+
192
+ # write the specified string to the log, assuming a logger has been setup using IE#set_logger
193
+ def log ( what )
194
+ @ieController.logger.debug( what ) if @logger
195
+ end
196
+
197
+ # this method causes Watir to wait until Internet Explorer has finished the action
198
+ def wait( noSleep = false )
199
+ @ieController.wait( noSleep )
200
+ end
201
+
202
+ def process_default(default_attribute, how, what)
203
+ if what == nil
204
+ what = how
205
+ how = default_attribute
206
+ end
207
+ return how, what
208
+ end
209
+ private :process_default
210
+
211
+ # this method is the main way of accessing a frame
212
+ # * how - how the frame is accessed. This can also just be the name of the frame
213
+ # * what - what we want to access.
214
+ #
215
+ # Typical usage:
216
+ #
217
+ # ie.frame(:index, 1)
218
+ # ie.frame(:name , 'main_frame')
219
+ # ie.frame('main_frame') # in this case, just a name is supplied
220
+ def frame(how, what=nil)
221
+ how, what = process_default :name, how, what
222
+ return Frame.new(self, how, what)
223
+ end
224
+
225
+ # this method is used to access a form.
226
+ # available ways of accessing it are, :index , :name, :id, :method, :action
227
+ # * how - symbol - WHat mecahnism we use to find the form, one of the above. NOTE if what is not supplied this parameter is the NAME of the form
228
+ # * what - String - the text associated with the symbol
229
+ def form(how, what=nil)
230
+ how, what = process_default :name, how, what
231
+ return Form.new(self, how, what)
232
+ end
233
+
234
+ # This method is used to get a table from the page.
235
+ # :index (1 based counting)and :id are supported.
236
+ # NOTE :name is not supported, as the table tag does not have a name attribute. It is not part of the DOM.
237
+ # :index can be used when there are multiple tables on a page.
238
+ # The first form can be accessed with :index 1, the second :index 2, etc.
239
+ # * how - symbol - the way we look for the table. Supported values are
240
+ # - :id
241
+ # - :index
242
+ # * what - string the thing we are looking for, ex. id or index of the object we are looking for
243
+ def table( how, what )
244
+ return Table.new( self , how, what)
245
+ end
246
+
247
+ # this is the main method for accessing the tables iterator. It returns a Tables object
248
+ #
249
+ # Typical usage:
250
+ #
251
+ # ie.tables.each { |t| puts t.to_s } # iterate through all the tables on the page
252
+ # ie.tables[1].to_s # goto the first table on the page
253
+ # ie.tables.length # show how many tables are on the page. Tables that are nested will be included in this
254
+ def tables()
255
+ return Tables.new(self)
256
+ end
257
+
258
+ # this method accesses a table cell.
259
+ # how - symbol - how we access the cell, :id is supported
260
+ #
261
+ # returns a TableCell Object
262
+ def cell( how, what )
263
+ return TableCell.new( self, how, what)
264
+ end
265
+
266
+ # this method accesses a table row.
267
+ # how - symbol - how we access the row, :id is supported
268
+ #
269
+ # returns a TableRow object
270
+ def row( how, what )
271
+ return TableRow.new( self, how, what)
272
+ end
273
+
274
+ # This is the main method for accessing a button. Often declared as an <input type = submit> tag.
275
+ # * how - symbol - how we access the button
276
+ # * what - string, int or re , what we are looking for,
277
+ # Returns a Button object.
278
+ #
279
+ # Valid values for 'how' are
280
+ #
281
+ # :index - find the item using the index in the container ( a container can be a document, a TableCell, a Span, a Div or a P
282
+ # index is 1 based
283
+ # :name - find the item using the name attribute
284
+ # :id - find the item using the id attribute
285
+ # :value - find the item using the value attribute ( in this case the button caption)
286
+ # :caption - same as value
287
+ # :beforeText - finds the item immediately before the specified text
288
+ # :afterText - finds the item immediately after the specified text
289
+ #
290
+ # Typical Usage
291
+ #
292
+ # ie.button(:id, 'b_1') # access the button with an ID of b_1
293
+ # ie.button(:name, 'verify_data') # access the button with a name of verify_data
294
+ # ie.button(:value, 'Login') # access the button with a value (the text displayed on the button) of Login
295
+ # ie.button(:caption, 'Login') # same as above
296
+ # ie.button(:value, /Log/) # access the button that has text matching /Log/
297
+ # ie.button(:index, 2) # access the second button on the page ( 1 based, so the first button is accessed with :index,1)
298
+ #
299
+ # if only a single parameter is supplied, then :value is used
300
+ #
301
+ # ie.button('Click Me') # access the button with a value of Click Me
302
+ def button(how, what=nil)
303
+ how, what = process_default :value, how, what
304
+ return Button.new(self, how, what)
305
+ end
306
+
307
+ # this is the main method for accessing the buttons iterator. It returns a Buttons object
308
+ #
309
+ # Typical usage:
310
+ #
311
+ # ie.buttons.each { |b| puts b.to_s } # iterate through all the buttons on the page
312
+ # ie.buttons[1].to_s # goto the first button on the page
313
+ # ie.buttons.length # show how many buttons are on the page.
314
+ def buttons()
315
+ return Buttons.new(self)
316
+ end
317
+
318
+
319
+ # This is the main method for accessing a file field. Usually an <input type = file> HTML tag.
320
+ # * how - symbol - how we access the field , :index, :id, :name etc
321
+ # * what - string, int or re , what we are looking for,
322
+ #
323
+ # returns a FileField object
324
+ #
325
+ # Typical Usage
326
+ #
327
+ # ie.file_field(:id, 'up_1') # access the file upload field with an ID of up_1
328
+ # ie.file_field(:name, 'upload') # access the file upload field with a name of upload
329
+ # ie.file_field(:index, 2) # access the second file upload on the page ( 1 based, so the first field is accessed with :index,1)
330
+ #
331
+ def file_field(how , what)
332
+ return FileField.new(self , how, what)
333
+ end
334
+
335
+ # this is the main method for accessing the file_fields iterator. It returns a FileFields object
336
+ #
337
+ # Typical usage:
338
+ #
339
+ # ie.file_fields.each { |f| puts f.to_s } # iterate through all the file fields on the page
340
+ # ie.file_fields[1].to_s # goto the first file field on the page
341
+ # ie.file_fields.length # show how many file fields are on the page.
342
+ def file_fields()
343
+ return FileFields.new(self)
344
+ end
345
+
346
+ # This is the main method for accessing a text field. Usually an <input type = text> HTML tag. or a text area - a <textarea> tag
347
+ # * how - symbol - how we access the field , :index, :id, :name etc
348
+ # * what - string, int or re , what we are looking for,
349
+ #
350
+ # returns a TextField object
351
+ #
352
+ # Valid values for 'how' are
353
+ #
354
+ # :index - find the item using the index in the container ( a container can be a document, a TableCell, a Span, a Div or a P
355
+ # index is 1 based
356
+ # :name - find the item using the name attribute
357
+ # :id - find the item using the id attribute
358
+ # :beforeText - finds the item immediately before the specified text
359
+ # :afterText - finds the item immediately after the specified text
360
+ #
361
+ # Typical Usage
362
+ #
363
+ # ie.text_field(:id, 'user_name') # access the text field with an ID of user_name
364
+ # ie.text_field(:name, 'address') # access the text field with a name of address
365
+ # ie.text_field(:index, 2) # access the second text field on the page ( 1 based, so the first field is accessed with :index,1)
366
+ def text_field(how , what=nil)
367
+ return TextField.new(self, how, what)
368
+ end
369
+
370
+ # this is the method for accessing the text_fields iterator. It returns a Text_Fields object
371
+ #
372
+ # Typical usage:
373
+ #
374
+ # ie.text_fields.each { |t| puts t.to_s } # iterate through all the text fields on the page
375
+ # ie.text_fields[1].to_s # goto the first text field on the page
376
+ # ie.text_fields.length # show how many text field are on the page.
377
+ def text_fields
378
+ return TextFields.new(self)
379
+ end
380
+
381
+ # This is the main method for accessing a hidden field. Usually an <input type = hidden> HTML tag
382
+ # * how - symbol - how we access the field , :index, :id, :name etc
383
+ # * what - string, int or re , what we are looking for,
384
+ #
385
+ # returns a Hidden object
386
+ #
387
+ # Typical usage
388
+ #
389
+ # ie.hidden(:id, 'session_id') # access the hidden field with an ID of session_id
390
+ # ie.hidden(:name, 'temp_value') # access the hidden field with a name of temp_value
391
+ # ie.hidden(:index, 2) # access the second hidden field on the page ( 1 based, so the first field is accessed with :index,1)
392
+ def hidden( how, what )
393
+ return Hidden.new(self, how, what)
394
+ end
395
+
396
+ # this is the method for accessing the hiddens iterator. It returns a Hiddens object
397
+ #
398
+ # Typical usage:
399
+ #
400
+ # ie.hiddens.each { |t| puts t.to_s } # iterate through all the hidden fields on the page
401
+ # ie.hiddens[1].to_s # goto the first hidden field on the page
402
+ # ie.hiddens.length # show how many hidden fields are on the page.
403
+ def hiddens
404
+ return Hiddens.new(self)
405
+ end
406
+
407
+ # This is the main method for accessing a selection list. Usually a <select> HTML tag.
408
+ # * how - symbol - how we access the selection list , :index, :id, :name etc
409
+ # * what - string, int or re , what we are looking for,
410
+ #
411
+ # returns a SelectList object
412
+ #
413
+ # Valid values for 'how' are
414
+ #
415
+ # :index - find the item using the index in the container ( a container can be a document, a TableCell, a Span, a Div or a P
416
+ # index is 1 based
417
+ # :name - find the item using the name attribute
418
+ # :id - find the item using the id attribute
419
+ # :beforeText - finds the item immediately before the specified text
420
+ # :afterText - finds the item immediately after the specified text
421
+ #
422
+ # Typical usage
423
+ #
424
+ # ie.select_list(:id, 'currency') # access the select box with an id of currency
425
+ # ie.select_list(:name, 'country') # access the select box with a name of country
426
+ # ie.select_list(:name, /n_/ ) # access the first select box whose name matches n_
427
+ # ie.select_list(:index, 2) # access the second select box on the page ( 1 based, so the first field is accessed with :index,1)
428
+ def select_list(how , what=nil)
429
+ return SelectList.new(self, how, what)
430
+ end
431
+
432
+ # this is the method for accessing the select lists iterator. Returns a SelectLists object
433
+ #
434
+ # Typical usage:
435
+ #
436
+ # ie.select_lists.each { |s| puts s.to_s } # iterate through all the select boxes on the page
437
+ # ie.select_lists[1].to_s # goto the first select boxes on the page
438
+ # ie.select_lists.length # show how many select boxes are on the page.
439
+ def select_lists()
440
+ return SelectLists.new(self)
441
+ end
442
+
443
+ # This is the main method for accessing a check box. Usually an <input type = checkbox> HTML tag.
444
+ #
445
+ # * how - symbol - how we access the check box , :index, :id, :name etc
446
+ # * what - string, int or re , what we are looking for,
447
+ # * value - string - when there are multiple objects with different value attributes, this can be used to find the correct object
448
+ #
449
+ # returns a CheckBox object
450
+ #
451
+ # Valid values for 'how' are
452
+ #
453
+ # :index - find the item using the index in the container ( a container can be a document, a TableCell, a Span, a Div or a P
454
+ # index is 1 based
455
+ # :name - find the item using the name attribute
456
+ # :id - find the item using the id attribute
457
+ # :beforeText - finds the item immediately before the specified text
458
+ # :afterText - finds the item immediately after the specified text
459
+ #
460
+ # Typical usage
461
+ #
462
+ # ie.checkbox(:id, 'send_email') # access the check box with an id of send_mail
463
+ # ie.checkbox(:name, 'send_copy') # access the check box with a name of send_copy
464
+ # ie.checkbox(:name, /n_/ ) # access the first check box whose name matches n_
465
+ # ie.checkbox(:index, 2) # access the second check box on the page ( 1 based, so the first field is accessed with :index,1)
466
+ #
467
+ # In many instances, checkboxes on an html page have the same name, but are identified by different values. An example is shown next.
468
+ #
469
+ # <input type = checkbox name = email_frequency value = 'daily' > Daily Email
470
+ # <input type = checkbox name = email_frequency value = 'Weekly'> Weekly Email
471
+ # <input type = checkbox name = email_frequency value = 'monthly'>Monthly Email
472
+ #
473
+ # Watir can access these using the following:
474
+ #
475
+ # ie.checkbox(:id, 'day_to_send' , 'monday' ) # access the check box with an id of day_to_send and a value of monday
476
+ # ie.checkbox(:name ,'email_frequency', 'weekly') # access the check box with a name of email_frequency and a value of 'weekly'
477
+ def checkbox(how, what=nil ,value=nil)
478
+ return CheckBox.new(self, how, what, ["checkbox"], value)
479
+ end
480
+
481
+ # this is the method for accessing the check boxes iterator. Returns a CheckBoxes object
482
+ #
483
+ # Typical usage:
484
+ #
485
+ # ie.checkboxes.each { |c| puts c.to_s } # iterate through all the check boxes on the page
486
+ # ie.checkboxes[1].to_s # goto the first check box on the page
487
+ # ie.checkboxes.length # show how many check boxes are on the page.
488
+ def checkboxes
489
+ return CheckBoxes.new(self)
490
+ end
491
+
492
+ # This is the main method for accessing a radio button. Usually an <input type = radio> HTML tag.
493
+ # * how - symbol - how we access the radio button, :index, :id, :name etc
494
+ # * what - string, int or regexp , what we are looking for,
495
+ # * value - string - when there are multiple objects with different value attributes, this can be used to find the correct object
496
+ #
497
+ # returns a Radio object
498
+ #
499
+ # Valid values for 'how' are
500
+ #
501
+ # :index - find the item using the index in the container ( a container can be a document, a TableCell, a Span, a Div or a P
502
+ # index is 1 based
503
+ # :name - find the item using the name attribute
504
+ # :id - find the item using the id attribute
505
+ # :beforeText - finds the item immediately before the specified text
506
+ # :afterText - finds the item immediately after the specified text
507
+ #
508
+ # Typical usage
509
+ #
510
+ # ie.radio(:id, 'send_email') # access the radio button with an id of currency
511
+ # ie.radio(:name, 'send_copy') # access the radio button with a name of country
512
+ # ie.radio(:name, /n_/ ) # access the first radio button whose name matches n_
513
+ # ie.radio(:index, 2) # access the second radio button on the page ( 1 based, so the first field is accessed with :index,1)
514
+ #
515
+ # In many instances, radio buttons on an html page have the same name, but are identified by different values. An example is shown next.
516
+ #
517
+ # <input type = radio name = email_frequency value = 'daily' > Daily Email
518
+ # <input type = radio name = email_frequency value = 'Weekly'> Weekly Email
519
+ # <input type = radio name = email_frequency value = 'monthly'>Monthly Email
520
+ #
521
+ # Watir can access these using the following:
522
+ #
523
+ # ie.radio(:id, 'day_to_send' , 'monday' ) # access the radio button with an id of day_to_send and a value of monday
524
+ # ie.radio(:name ,'email_frequency', 'weekly') # access the radio button with a name of email_frequency and a value of 'weekly'
525
+ #
526
+ def radio(how, what=nil, value=nil)
527
+ return Radio.new(self, how, what, ["radio"], value)
528
+ end
529
+
530
+ # This is the method for accessing the radio buttons iterator. Returns a Radios object
531
+ #
532
+ # Typical usage:
533
+ #
534
+ # ie.radios.each { |r| puts r.to_s } # iterate through all the radio buttons on the page
535
+ # ie.radios[1].to_s # goto the first radio button on the page
536
+ # ie.radios.length # show how many radio buttons are on the page.
537
+ #
538
+ def radios
539
+ return Radios.new(self)
540
+ end
541
+
542
+ # This is the main method for accessing a link.
543
+ # * how - symbol - how we access the link, :index, :id, :name , :beforetext, :afterText, :title , :text , :url
544
+ # * what - string, int or re , what we are looking for
545
+ #
546
+ # returns a Link object
547
+ #
548
+ # Valid values for 'how' are
549
+ #
550
+ # :index - find the item using the index in the container ( a container can be a document, a TableCell, a Span, a Div or a P
551
+ # index is 1 based
552
+ # :name - find the item using the name attribute
553
+ # :id - find the item using the id attribute
554
+ # :beforeText - finds the item immediately before the specified text
555
+ # :afterText - finds the item immediately after the specified text
556
+ # :url - finds the link based on the url. This must be the full path to the link, so is best used with a regular expression
557
+ # :text - finds a link using the innerText of the link, ie the Text that is displayed to the user
558
+ # :title - finds the item using the tool tip text
559
+ #
560
+ # Typical Usage
561
+ #
562
+ # ie.link(:url, /login/) # access the first link whose url matches login. We can use a string in place of the regular expression
563
+ # # but the complete path must be used, ie.link(:url, 'http://myserver.com/my_path/login.asp')
564
+ # ie.link(:index,2) # access the second link on the page
565
+ # ie.link(:title , "Picture") # access a link using the tool tip
566
+ # ie.link(:text, 'Click Me') # access the link that has Click Me as its text
567
+ # ie.link(:afterText, 'Click->') # access the link that immediately follows the text Click->
568
+ #
569
+ def link(how, what=nil)
570
+ return Link.new(self, how, what)
571
+ end
572
+
573
+ # This is the main method for accessing the links collection. Returns a Links object
574
+ #
575
+ # Typical usage:
576
+ #
577
+ # ie.links.each { |l| puts l.to_s } # iterate through all the links on the page
578
+ # ie.links[1].to_s # goto the first link on the page
579
+ # ie.links.length # show how many links are on the page.
580
+ #
581
+ def links
582
+ return Links.new(self)
583
+ end
584
+
585
+ # This is the main method for accessing images - normally an <img src="image.gif"> HTML tag.
586
+ # * how - symbol - how we access the image, :index, :id, :name , :src or :alt are supported
587
+ # * what - string, int or re , what we are looking for,
588
+ #
589
+ # returns an Image object
590
+ #
591
+ # Valid values for 'how' are
592
+ #
593
+ # :index - find the item using the index in the container ( a container can be a document, a TableCell, a Span, a Div or a P
594
+ # index is 1 based
595
+ # :name - find the item using the name attribute
596
+ # :id - find the item using the id attribute
597
+ # :alt - finds the item using the tool tip text
598
+ # :src - finds the item using the src tag. This must be the fully qualified name, so is best used with a regular expression
599
+ #
600
+ # Typical Usage
601
+ #
602
+ # ie.image(:src, /myPic/) # access the first image that matches myPic. We can use a string in place of the regular expression
603
+ # # but the complete path must be used, ie.image(:src, 'http://myserver.com/my_path/my_image.jpg')
604
+ # ie.image(:index,2) # access the second image on the page
605
+ # ie.image(:alt , "A Picture") # access an image using the alt text
606
+ #
607
+ def image( how , what=nil)
608
+ return Image.new(self, how, what)
609
+ end
610
+
611
+ # This is the main method for accessing the images collection. Returns an Images object
612
+ #
613
+ # Typical usage:
614
+ #
615
+ # ie.images.each { |i| puts i.to_s } # iterate through all the images on the page
616
+ # ie.images[1].to_s # goto the first image on the page
617
+ # ie.images.length # show how many images are on the page.
618
+ #
619
+ def images
620
+ return Images.new(self)
621
+ end
622
+
623
+ # This is the main method for accessing JavaScript popups.
624
+ # returns a PopUp object
625
+ def popup
626
+ return PopUp.new(self )
627
+ end
628
+
629
+ # This is the main method for accessing divs. http://msdn.microsoft.com/workshop/author/dhtml/reference/objects/div.asp?frame=true
630
+ # * how - symbol - how we access the div, :index, :id, :title
631
+ # * what - string, integer or re , what we are looking for,
632
+ #
633
+ # returns an Div object
634
+ #
635
+ # Typical Usage
636
+ #
637
+ # ie.div(:id, /list/) # access the first div that matches list.
638
+ # ie.div(:index,2) # access the second div on the page
639
+ # ie.div(:title , "A Picture") # access a div using the tooltip text. See http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/title_1.asp?frame=true
640
+ #
641
+ def div(how, what)
642
+ return Div.new(self, how, what)
643
+ end
644
+
645
+ # this is the main method for accessing the divs iterator. Returns a Divs object
646
+ #
647
+ # Typical usage:
648
+ #
649
+ # ie.divs.each { |d| puts d.to_s } # iterate through all the divs on the page
650
+ # ie.divs[1].to_s # goto the first div on the page
651
+ # ie.divs.length # show how many divs are on the page.
652
+ #
653
+ def divs
654
+ return Divs.new(self)
655
+ end
656
+
657
+ # This is the main method for accessing span tags - http://msdn.microsoft.com/workshop/author/dhtml/reference/objects/span.asp?frame=true
658
+ # * how - symbol - how we access the span, :index, :id, :name
659
+ # * what - string, integer or re , what we are looking for,
660
+ #
661
+ # returns a Span object
662
+ #
663
+ # Typical Usage
664
+ #
665
+ # ie.span(:id, /list/) # access the first span that matches list.
666
+ # ie.span(:index,2) # access the second span on the page
667
+ # ie.span(:title , "A Picture") # access a span using the tooltip text. See http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/title_1.asp?frame=true
668
+ #
669
+ def span(how , what)
670
+ return Span.new(self, how, what)
671
+ end
672
+
673
+ # this is the main method for accessing the spans iterator.
674
+ #
675
+ # Returns a Spans object
676
+ #
677
+ # Typical usage:
678
+ #
679
+ # ie.spans.each { |s| puts s.to_s } # iterate through all the spans on the page
680
+ # ie.spans[1].to_s # goto the first span on the page
681
+ # ie.spans.length # show how many spans are on the page.
682
+ #
683
+ def spans
684
+ return Spans.new(self)
685
+ end
686
+
687
+ # This is the main method for accessing p tags - http://msdn.microsoft.com/workshop/author/dhtml/reference/objects/p.asp?frame=true
688
+ # * how - symbol - how we access the p, :index, :id, :name
689
+ # * what - string, integer or re , what we are looking for,
690
+ #
691
+ # returns a P object
692
+ #
693
+ # Typical Usage
694
+ #
695
+ # ie.p(:id, /list/) # access the first p tag that matches list.
696
+ # ie.p(:index,2) # access the second p tag on the page
697
+ # ie.p(:title , "A Picture") # access a p tag using the tooltip text. See http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/title_1.asp?frame=true
698
+ #
699
+ def p(how, what)
700
+ return P.new(self , how , what)
701
+ end
702
+
703
+ # this is the main method for accessing the ps iterator.
704
+ #
705
+ # Returns a Ps object
706
+ #
707
+ # Typical usage:
708
+ #
709
+ # ie.ps.each { |p| puts p.to_s } # iterate through all the p tags on the page
710
+ # ie.ps[1].to_s # goto the first p tag on the page
711
+ # ie.ps.length # show how many p tags are on the page.
712
+ #
713
+ def ps
714
+ return Ps.new(self)
715
+ end
716
+
717
+ # This is the main method for accessing labels. http://msdn.microsoft.com/workshop/author/dhtml/reference/objects/label.asp?frame=true
718
+ # * how - symbol - how we access the label, :index, :id, :for
719
+ # * what - string, integer or re , what we are looking for,
720
+ #
721
+ # returns a Label object
722
+ #
723
+ # Typical Usage
724
+ #
725
+ # ie.label(:id, /list/) # access the first span that matches list.
726
+ # ie.label(:index,2) # access the second label on the page
727
+ # ie.label(:for, "text_1") # access a the label that is associated with the object that has an id of text_1
728
+ #
729
+ def label(how, what)
730
+ return Label.new(self, how, what)
731
+ end
732
+
733
+ # this is the main method for accessing the labels iterator. It returns a Labels object
734
+ #
735
+ # Returns a Labels object
736
+ #
737
+ # Typical usage:
738
+ #
739
+ # ie.labels.each { |l| puts l.to_s } # iterate through all the labels on the page
740
+ # ie.labels[1].to_s # goto the first label on the page
741
+ # ie.labels.length # show how many labels are on the page.
742
+ #
743
+ def labels()
744
+ return Labels.new(self)
745
+ end
746
+
747
+ #--
748
+ #
749
+ # Searching for Page Elements
750
+ # Not for external consumption
751
+ #
752
+ #++
753
+ def getContainerContents()
754
+ return document.body.all
755
+ end
756
+ private :getContainerContents
757
+
758
+ # this method is used internally by Watir and should not be used externally.
759
+ # It cannot be marked as private because of the way mixins and inheritance work in watir.
760
+ # BUG: This looks wrong: Not everything that includes SupportsSubElements has a document.body!
761
+ def getContainer()
762
+ return document.body
763
+ end
764
+
765
+ # This is the main method for finding objects on a web page.
766
+ #
767
+ # This method is used internally by Watir and should not be used externally. It cannot be marked as private because of the way mixins and inheritance work in watir
768
+ #
769
+ # * how - symbol - the way we look for the object. Supported values are
770
+ # - :name
771
+ # - :id
772
+ # - :index
773
+ # - :value etc
774
+ # * what - string that we are looking for, ex. the name, or id tag attribute or index of the object we are looking for.
775
+ # * types - what object types we will look at. Only used when index is specified as the how.
776
+ # * value - used for objects that have one name, but many values. ex. radio lists and checkboxes
777
+ def getObject(how, what, types, value=nil)
778
+ container = getContainerContents # XXX actually this returns a collection object (not a container)
779
+ how = :value if how == :caption
780
+ log "getting object - how is #{how} what is #{what} types = #{types} value = #{value}"
781
+
782
+ o = nil
783
+ if how == :index
784
+ index = what.to_i
785
+ log" getting object #{types.to_s} at index( #{index}"
786
+
787
+ objectIndex = 1
788
+ container.each do | thisObject |
789
+ begin
790
+ this_type = thisObject.invoke("type")
791
+ rescue
792
+ this_type = nil
793
+ end
794
+ if types.include?(this_type)
795
+ if objectIndex == index
796
+ o = thisObject
797
+ break
798
+ end
799
+ objectIndex += 1
800
+ end
801
+ end
802
+ return o
803
+
804
+ else
805
+ container.each do |object|
806
+ next unless o == nil
807
+
808
+ begin
809
+ case how
810
+ when :id
811
+ attribute = object.invoke("id")
812
+ when :name
813
+ attribute = object.invoke("name")
814
+ when :value
815
+ attribute = object.value
816
+ when :alt
817
+ attribute = object.alt
818
+ when :src
819
+ attribute = object.src
820
+ when :beforeText
821
+ attribute = object.getAdjacentText("afterEnd").strip
822
+ when :afterText
823
+ attribute = object.getAdjacentText("beforeBegin").strip
824
+ else
825
+ next
826
+ end
827
+
828
+ if what.matches(attribute) && types.include?(object.invoke("type"))
829
+ if value
830
+ log "checking value supplied #{value} ( #{value.class}) actual #{object.value} ( #{object.value.class})"
831
+ if object.value.to_s == value.to_s
832
+ o = object
833
+ end
834
+ else # no value
835
+ o = object
836
+ end
837
+ end
838
+
839
+ rescue => e
840
+ log 'IE#getObject error ' + e.to_s
841
+ end
842
+
843
+ end
844
+ end
845
+
846
+ return o
847
+ end
848
+
849
+ # This method is used iternally by Watir and should not be used externally. It cannot be marked as private because of the way mixins and inheritance work in watir
850
+ #
851
+ # this method finds the specified image
852
+ # * how - symbol - how to look
853
+ # * what - string or regexp - what to look ofr
854
+ def getImage( how, what )
855
+
856
+ doc = document
857
+ count = 1
858
+ images = doc.all.tags("IMG")
859
+ o=nil
860
+ images.each do |img|
861
+
862
+ #puts "Image on page: src = #{img.src}"
863
+
864
+ next unless o == nil
865
+ if how == :index
866
+ o = img if count == what.to_i
867
+ else
868
+ case how
869
+
870
+ when :src
871
+ attribute = img.src
872
+ when :name
873
+ attribute = img.name
874
+ when :id
875
+ attribute = img.invoke("id")
876
+ when :alt
877
+ attribute = img.invoke("alt")
878
+ else
879
+ next
880
+ end
881
+
882
+ o = img if what.matches(attribute)
883
+ end
884
+ count +=1
885
+ end # do
886
+ return o
887
+
888
+ end
889
+
890
+ # This method is used iternally by Watir and should not be used externally. It cannot be marked as private because of the way mixins and inheritance work in watir
891
+ #
892
+ # This method gets a link from the document. This is a hyperlink, generally declared in the <a href="http://testsite">test site</a> HTML tag.
893
+ # * how - symbol - how we get the link Supported types are:
894
+ # :index - the link at position x , 1 based
895
+ # :url - get the link that has a url that matches. A regular expression match is performed
896
+ # :text - get link based on the supplied text. uses either a string or regular expression match
897
+ # * what - depends on how - an integer for index, a string or regexp for url and text
898
+ def getLink( how, what )
899
+ links = document.all.tags("A")
900
+
901
+ # Guard ensures watir won't crash if somehow the list of links is nil
902
+ if (links == nil)
903
+ raise UnknownObjectException, "Unknown Object in getLink: attempted to click a link when no links present"
904
+ end
905
+
906
+ link = nil
907
+ case how
908
+ when :index
909
+ begin
910
+ link = links[ (what-1).to_s ]
911
+ rescue
912
+ link=nil
913
+ end
914
+
915
+ when :url
916
+ links.each do |thisLink|
917
+ if what.matches(thisLink.href)
918
+ link = thisLink if link == nil
919
+ end
920
+ end
921
+
922
+ when :text
923
+ links.each do |thisLink|
924
+ if what.matches(thisLink.innerText.strip)
925
+ link = thisLink if link == nil
926
+ end
927
+ end
928
+
929
+ when :id
930
+ links.each do |thisLink|
931
+ if what.matches(thisLink.invoke("id"))
932
+ link = thisLink if link == nil
933
+ end
934
+ end
935
+ when :name
936
+ links.each do |thisLink|
937
+ if what.matches(thisLink.invoke("name"))
938
+ link = thisLink if link == nil
939
+ end
940
+ end
941
+
942
+ when :title
943
+ links.each do |thisLink|
944
+ if what.matches(thisLink.invoke("title"))
945
+ link = thisLink if link == nil
946
+ end
947
+ end
948
+
949
+ when :beforeText
950
+ links.each do |thisLink|
951
+ if what.matches(thisLink.getAdjacentText("afterEnd").strip)
952
+ link = thisLink if link == nil
953
+ end
954
+ end
955
+
956
+ when :afterText
957
+ links.each do |thisLink|
958
+ if what.matches(thisLink.getAdjacentText("beforeBegin").strip)
959
+ link = thisLink if link == nil
960
+ end
961
+ end
962
+ else
963
+ raise MissingWayOfFindingObjectException, "#{how.inspect} is an unknown way of finding a link ( #{what} )"
964
+ end
965
+
966
+ # if no link found, link will be a nil. This is OK. Actions taken on links (e.g. "click") should rescue
967
+ # the nil-related exceptions and provide useful information to the user.
968
+ return link
969
+
970
+ end
971
+
972
+ # This method is used iternally by Watir and should not be used externally. It cannot be marked as private because of the way mixins and inheritance work in watir
973
+ #
974
+ # This method gets a table row or cell
975
+ # * how - symbol - how we get the link row or cell types are:
976
+ # id
977
+ # * what - a string or regexp
978
+ def getTablePart( part , how , what )
979
+ doc = document
980
+ parts = doc.all.tags( part )
981
+ n = nil
982
+ parts.each do | p |
983
+ next unless n==nil
984
+ if what.matches( p.invoke("id") )
985
+ n = p
986
+ end
987
+ end
988
+ return n
989
+ end
990
+
991
+ # This method is used iternally by Watir and should not be used externally. It cannot be marked as private because of the way mixins and inheritance work in watir
992
+ #
993
+ # this method is used to get elements like SPAN or DIV
994
+ def getNonControlObject(part , how, what )
995
+
996
+ doc = document
997
+ parts = doc.all.tags( part )
998
+ n = nil
999
+ case how
1000
+ when :id
1001
+ attribute = "id"
1002
+ when :name
1003
+ attribute = "name"
1004
+ when :title
1005
+ attribute = "title"
1006
+ when :for # only applies to labels
1007
+ attribute = "htmlFor"
1008
+ end
1009
+
1010
+ if attribute
1011
+ parts.each do | p |
1012
+ next unless n==nil
1013
+ n = p if what.matches( p.invoke(attribute) )
1014
+ end
1015
+ elsif how == :index
1016
+ count = 1
1017
+ parts.each do | p |
1018
+ next unless n==nil
1019
+ n = p if what == count
1020
+ count +=1
1021
+ end
1022
+ else
1023
+ raise MissingWayOfFindingObjectException, "unknown way of finding a #{ part} ( {what} )"
1024
+ end
1025
+ return n
1026
+
1027
+ end
1028
+
1029
+ end
1030
+
1031
+
1032
+ # This class is the main Internet Explorer Controller
1033
+ # An instance of this must be created to access Internet Explorer.
1034
+ class IE
1035
+ include Watir::Exception
1036
+ include SupportsSubElements
1037
+
1038
+ # The revision number ( according to CVS )
1039
+ REVISION = "$Revision: 1.211.2.2 $"
1040
+
1041
+ # the Release number
1042
+ VERSION = "1.4.1"
1043
+
1044
+ # Used internally to determine when IE has finished loading a page
1045
+ READYSTATE_COMPLETE = 4
1046
+
1047
+ # The default delay when entering text on a web page.
1048
+ DEFAULT_TYPING_SPEED = 0.08
1049
+
1050
+ # The default time we wait after a page has loaded.
1051
+ DEFAULT_SLEEP_TIME = 0.1
1052
+
1053
+ # The default color for highlighting objects as they are accessed.
1054
+ DEFAULT_HIGHLIGHT_COLOR = "yellow"
1055
+
1056
+ # This is used to change the typing speed when entering text on a page.
1057
+ attr_accessor :typingspeed
1058
+
1059
+ # This is used to change how long after a page has finished loading that we wait for.
1060
+ attr_accessor :defaultSleepTime
1061
+
1062
+ # The color we want to use for the active object. This can be any valid web-friendly color.
1063
+ attr_accessor :activeObjectHighLightColor
1064
+
1065
+ # use this to switch the spinner on and off
1066
+ attr_accessor :enable_spinner
1067
+
1068
+ # use this to get the time for the last page download
1069
+ attr_reader :down_load_time
1070
+
1071
+ # When a new window is created it is stored in newWindow
1072
+ attr_accessor :newWindow
1073
+
1074
+ # Use this to gain access to the 'raw' internet explorer object.
1075
+ attr_reader :ie
1076
+
1077
+ # access to the logger object
1078
+ attr_accessor :logger
1079
+
1080
+
1081
+ # this contains the list of unique urls that have been visited
1082
+ attr_reader :url_list
1083
+
1084
+ def initialize(suppress_new_window=nil)
1085
+ unless suppress_new_window
1086
+ create_browser_window
1087
+ set_defaults
1088
+ end
1089
+ end
1090
+
1091
+ # Create a new IE Window, starting at the specified url.
1092
+ # If no url is given, start empty.
1093
+ def IE.start( url = nil )
1094
+ ie = new
1095
+ ie.goto(url) if url
1096
+ return ie
1097
+ end
1098
+
1099
+ # Attach to an existing IE window, either by url or title.
1100
+ # IE.attach(:url, 'http://www.google.com')
1101
+ # IE.attach(:title, 'Google')
1102
+ def IE.attach(how, what)
1103
+ ie = new(true) # don't create window
1104
+ ie.attach_init(how, what)
1105
+ return ie
1106
+ end
1107
+
1108
+ # this method is used internally to attach to an existing window
1109
+ # dont make private
1110
+ def attach_init( how, what )
1111
+ attach_browser_window(how, what)
1112
+ set_defaults
1113
+ wait
1114
+ end
1115
+
1116
+ def set_defaults
1117
+ @form = nil
1118
+
1119
+ @enable_spinner = $ENABLE_SPINNER
1120
+ @error_checkers= []
1121
+
1122
+ @ie.visible = ! $HIDE_IE
1123
+ @activeObjectHighLightColor = DEFAULT_HIGHLIGHT_COLOR
1124
+ if $FAST_SPEED
1125
+ set_fast_speed
1126
+ else
1127
+ set_slow_speed
1128
+ end
1129
+
1130
+ @logger = DefaultLogger.new()
1131
+
1132
+ @url_list = []
1133
+
1134
+ # add an error checker for http navigation errors, such as 404, 500 etc
1135
+ navigation_checker=Proc.new{ |ie|
1136
+ if ie.document.frames.length > 1
1137
+ 1.upto ie.document.frames.length do |i|
1138
+ check_for_http_error(ie.frame(:index, i) )
1139
+ end
1140
+ else
1141
+ check_for_http_error(ie)
1142
+ end
1143
+ }
1144
+
1145
+ add_checker( navigation_checker )
1146
+
1147
+ end
1148
+ private :set_defaults
1149
+
1150
+ # This method checks the currently displayed page for http errors, 404, 500 etc
1151
+ # It gets called internally by the wait method, so a user does not need to call it explicitly
1152
+ def check_for_http_error(ie)
1153
+ url=ie.document.url
1154
+ #puts "url is " + url
1155
+ if /shdoclc.dll/.match(url)
1156
+ #puts "Match on shdoclc.dll"
1157
+ m = /id=IEText.*?>(.*?)</i.match(ie.html)
1158
+ if m
1159
+ #puts "Error is #{m[1]}"
1160
+ raise NavigationException , m[1]
1161
+ end
1162
+ end
1163
+ end
1164
+
1165
+ def set_fast_speed
1166
+ @typingspeed = 0
1167
+ @defaultSleepTime = 0.01
1168
+ end
1169
+
1170
+ def set_slow_speed
1171
+ @typingspeed = DEFAULT_TYPING_SPEED
1172
+ @defaultSleepTime = DEFAULT_SLEEP_TIME
1173
+ end
1174
+
1175
+ def create_browser_window
1176
+ @ie = WIN32OLE.new('InternetExplorer.Application')
1177
+ end
1178
+ private :create_browser_window
1179
+
1180
+ def attach_browser_window( how, what )
1181
+ log "Seeking Window with #{how}: #{ what }"
1182
+ shell = WIN32OLE.new("Shell.Application")
1183
+ appWindows = shell.Windows()
1184
+
1185
+ ieTemp = nil
1186
+ appWindows.each do |aWin|
1187
+ log "Found a window: #{aWin}. "
1188
+
1189
+ case how
1190
+ when :url
1191
+ log " url is: #{aWin.locationURL}\n"
1192
+ ieTemp = aWin if (what.matches(aWin.locationURL) )
1193
+ when :title
1194
+ # normal windows explorer shells do not have document
1195
+ title = nil
1196
+ begin
1197
+ title = aWin.document.title
1198
+ rescue WIN32OLERuntimeError
1199
+ end
1200
+ ieTemp = aWin if (what.matches( title ) )
1201
+ else
1202
+ raise ArgumentError
1203
+ end
1204
+ end
1205
+
1206
+ #if it can not find window
1207
+ if ieTemp == nil
1208
+ raise NoMatchingWindowFoundException,
1209
+ "Unable to locate a window with #{ how} of #{what}"
1210
+ end
1211
+ @ie = ieTemp
1212
+ end
1213
+ private :attach_browser_window
1214
+
1215
+ # deprecated: use logger= instead
1216
+ def set_logger( logger )
1217
+ @logger = logger
1218
+ end
1219
+
1220
+ def log ( what )
1221
+ @logger.debug( what ) if @logger
1222
+ end
1223
+
1224
+ # Deprecated: Use IE#ie instead
1225
+ # This method returns the Internet Explorer object.
1226
+ # Methods, properties, etc. that the IE object does not support can be accessed.
1227
+ def getIE()
1228
+ return @ie
1229
+ end
1230
+
1231
+ #
1232
+ # Accessing data outside the document
1233
+ #
1234
+
1235
+ # Return the title of the window
1236
+ def title
1237
+ @ie.document.title
1238
+ end
1239
+
1240
+ # Return the status of the window, typically from the status bar at the bottom.
1241
+ def status
1242
+ raise NoStatusBarException if !@ie.statusBar
1243
+ return @ie.statusText()
1244
+ end
1245
+
1246
+ #
1247
+ # Navigation
1248
+ #
1249
+
1250
+ # Navigate to the specified URL.
1251
+ # * url - string - the URL to navigate to
1252
+ def goto( url )
1253
+ @ie.navigate(url)
1254
+ wait()
1255
+ sleep 0.2
1256
+ return @down_load_time
1257
+ end
1258
+
1259
+ # Go to the previous page - the same as clicking the browsers back button
1260
+ # an WIN32OLERuntimeError exception is raised if the browser cant go back
1261
+ def back
1262
+ @ie.GoBack()
1263
+ wait
1264
+ end
1265
+
1266
+ # Go to the next page - the same as clicking the browsers forward button
1267
+ # an WIN32OLERuntimeError exception is raised if the browser cant go forward
1268
+ def forward
1269
+ @ie.GoForward()
1270
+ wait
1271
+ end
1272
+
1273
+ # Refresh the current page - the same as clicking the browsers refresh button
1274
+ # an WIN32OLERuntimeError exception is raised if the browser cant refresh
1275
+ def refresh
1276
+ @ie.refresh2(3)
1277
+ wait
1278
+ end
1279
+
1280
+ # clear the list of urls that we have visited
1281
+ def clear_url_list
1282
+ @url_list.clear
1283
+ end
1284
+
1285
+ # Closes the Browser
1286
+ def close
1287
+ @ie.quit
1288
+ end
1289
+
1290
+ # Maximize the window (expands to fill the screen)
1291
+ def maximize; set_window_state (:SW_MAXIMIZE); end
1292
+
1293
+ # Minimize the window (appears as icon on taskbar)
1294
+ def minimize; set_window_state (:SW_MINIMIZE); end
1295
+
1296
+ # Restore the window (after minimizing or maximizing)
1297
+ def restore; set_window_state (:SW_RESTORE); end
1298
+
1299
+ # Make the window come to the front
1300
+ def bring_to_front
1301
+ autoit = WIN32OLE.new('AutoItX3.Control')
1302
+ autoit.WinActivate title, ''
1303
+ end
1304
+
1305
+ def front?
1306
+ autoit = WIN32OLE.new('AutoItX3.Control')
1307
+ 1 == autoit.WinActive(title, '')
1308
+ end
1309
+
1310
+ def set_window_state (state)
1311
+ autoit = WIN32OLE.new('AutoItX3.Control')
1312
+ autoit.WinSetState title, '', autoit.send(state)
1313
+ end
1314
+ private :set_window_state
1315
+
1316
+ # Send key events to IE window.
1317
+ # See http://www.autoitscript.com/autoit3/docs/appendix/SendKeys.htm
1318
+ # for complete documentation on keys supported and syntax.
1319
+ def send_keys (key_string)
1320
+ autoit = WIN32OLE.new 'AutoItX3.Control'
1321
+ autoit.WinActivate title
1322
+ autoit.Send key_string
1323
+ end
1324
+
1325
+ # used by the popup code only
1326
+ def dir
1327
+ return File.expand_path(File.dirname(__FILE__))
1328
+ end
1329
+
1330
+ #
1331
+ # Document and Document Data
1332
+ #
1333
+
1334
+ # Return the current document
1335
+ def document
1336
+ return @ie.document
1337
+ end
1338
+
1339
+ # returns the current url, as displayed in the address bar of the browser
1340
+ def url
1341
+ return @ie.LocationURL
1342
+ end
1343
+
1344
+ # Search the current page for specified text or regexp.
1345
+ # Returns true if the specified text was found.
1346
+ # Returns matchdata object if the specified regexp was found.
1347
+ # * text - string or regular expression - the string to look for
1348
+ def contains_text(text)
1349
+ returnValue = false
1350
+ retryCount = 0
1351
+ begin
1352
+ retryCount += 1
1353
+ returnValue =
1354
+ if text.kind_of? Regexp
1355
+ document.body.innerText.match(text)
1356
+ elsif text.kind_of? String
1357
+ document.body.innerText.index(text)
1358
+ else
1359
+ raise MissingWayOfFindingObjectException
1360
+ end
1361
+ rescue MissingWayOfFindingObjectException => e
1362
+ raise e
1363
+ rescue
1364
+ retry if retryCount < 2
1365
+ end
1366
+ return returnValue
1367
+ end
1368
+
1369
+ #
1370
+ # Synchronization
1371
+ #
1372
+
1373
+ # This method is used internally to cause an execution to stop until the page has loaded in Internet Explorer.
1374
+ def wait( noSleep = false )
1375
+ begin
1376
+ @down_load_time=0
1377
+ pageLoadStart = Time.now
1378
+ @pageHasReloaded= false
1379
+
1380
+ s= Spinner.new(@enable_spinner)
1381
+ while @ie.busy
1382
+ @pageHasReloaded = true
1383
+ sleep 0.02
1384
+ s.spin
1385
+ end
1386
+ s.reverse
1387
+
1388
+ log "wait: readystate=" + @ie.readyState.to_s
1389
+ until @ie.readyState == READYSTATE_COMPLETE
1390
+ @pageHasReloaded = true
1391
+ sleep 0.02
1392
+ s.spin
1393
+ end
1394
+ sleep 0.02
1395
+
1396
+ until @ie.document.readyState == "complete"
1397
+ sleep 0.02
1398
+ s.spin
1399
+ end
1400
+
1401
+
1402
+ if @ie.document.frames.length > 1
1403
+ begin
1404
+ 0.upto @ie.document.frames.length-1 do |i|
1405
+ until @ie.document.frames[i.to_s].document.readyState == "complete"
1406
+ sleep 0.02
1407
+ s.spin
1408
+ end
1409
+ @url_list << @ie.document.frames[i.to_s].document.url unless url_list.include?(@ie.document.frames[i.to_s].document.url)
1410
+ end
1411
+ rescue=>e
1412
+ @logger.warn 'frame error in wait' + e.to_s + "\n" + e.backtrace.join("\n")
1413
+ end
1414
+ else
1415
+ @url_list << @ie.document.url unless @url_list.include?(@ie.document.url)
1416
+ end
1417
+ @down_load_time = Time.now - pageLoadStart
1418
+
1419
+ run_error_checks
1420
+
1421
+ print "\b" unless @enable_spinner == false
1422
+
1423
+ s=nil
1424
+ rescue WIN32OLERuntimeError => e
1425
+ @logger.info "runtime error in wait: #{e}\n#{e.backtrace.join("\\\n")}"
1426
+ end
1427
+ sleep 0.01
1428
+ sleep @defaultSleepTime unless noSleep == true
1429
+ end
1430
+
1431
+ # Error checkers
1432
+
1433
+ # this method runs the predefined error checks
1434
+ def run_error_checks
1435
+ @error_checkers.each do |e|
1436
+ e.call(self)
1437
+ end
1438
+ end
1439
+
1440
+ # this method is used to add an error checker that gets executed on every page load
1441
+ # * checker Proc Object, that contains the code to be run
1442
+ def add_checker( checker)
1443
+ @error_checkers << checker
1444
+ end
1445
+
1446
+ # this allows a checker to be disabled
1447
+ # * checker Proc Object, the checker that is to be disabled
1448
+ def disable_checker( checker )
1449
+ @error_checkers.delete(checker)
1450
+ end
1451
+
1452
+ # The HTML of the current page
1453
+ def html
1454
+ return document.body.outerHTML
1455
+ end
1456
+
1457
+ # The text of the current document
1458
+ def text
1459
+ return document.body.innerText.strip
1460
+ end
1461
+
1462
+ #
1463
+ # Show me state
1464
+ #
1465
+
1466
+ # This method is used to display the available html frames that Internet Explorer currently has loaded.
1467
+ # This method is usually only used for debugging test scripts.
1468
+ def show_frames
1469
+ if allFrames = document.frames
1470
+ count = allFrames.length
1471
+ puts "there are #{count} frames"
1472
+ for i in 0..count-1 do
1473
+ begin
1474
+ fname = allFrames[i.to_s].name.to_s
1475
+ puts "frame index: #{i+1} name: #{fname}"
1476
+ rescue => e
1477
+ puts "frame index: #{i+1} --Access Denied--" if e.to_s.match(/Access is denied/)
1478
+ end
1479
+ end
1480
+ else
1481
+ puts "no frames"
1482
+ end
1483
+ end
1484
+
1485
+ # Show all forms displays all the forms that are on a web page.
1486
+ def show_forms
1487
+ if allForms = document.forms
1488
+ count = allForms.length
1489
+ puts "There are #{count} forms"
1490
+ for i in 0..count-1 do
1491
+ wrapped = FormWrapper.new(allForms.item(i))
1492
+ puts "Form name: #{wrapped.name}"
1493
+ puts " id: #{wrapped.id}"
1494
+ puts " method: #{wrapped.method}"
1495
+ puts " action: #{wrapped.action}"
1496
+ end
1497
+ else
1498
+ puts "No forms"
1499
+ end
1500
+ end
1501
+
1502
+ # this method shows all the images availble in the document
1503
+ def show_images
1504
+ doc = document
1505
+ index=1
1506
+ doc.images.each do |l|
1507
+ puts "image: name: #{l.name}"
1508
+ puts " id: #{l.invoke("id")}"
1509
+ puts " src: #{l.src}"
1510
+ puts " index: #{index}"
1511
+ index+=1
1512
+ end
1513
+ end
1514
+
1515
+ # this method shows all the links availble in the document
1516
+ def show_links
1517
+
1518
+ props= ["name" ,"id" , "href" ]
1519
+ print_sizes= [12 , 12, 60]
1520
+ doc = document
1521
+ index=0
1522
+ text_size = 60
1523
+ # draw the table header
1524
+ s = "index".ljust(6)
1525
+ props.each_with_index do |p,i|
1526
+ s=s+ p.ljust(print_sizes[i])
1527
+ end
1528
+ s=s + "text/src".ljust(text_size)
1529
+ s=s+"\n"
1530
+
1531
+ # now get the details of the links
1532
+ doc.links.each do |n|
1533
+ index+=1
1534
+ s = s + index.to_s.ljust(6)
1535
+ props.each_with_index do |prop,i|
1536
+ printsize=print_sizes[i]
1537
+ begin
1538
+ p = n.invoke(prop)
1539
+ temp_var = "#{p}".to_s.ljust(printsize)
1540
+ rescue
1541
+ # this object probably doesnt have this property
1542
+ temp_var = "".to_s.ljust(printsize)
1543
+ end
1544
+ s =s+ temp_var
1545
+ end
1546
+ s=s+ n.innerText
1547
+ if n.getElementsByTagName("IMG").length > 0
1548
+ s=s+ " / " + n.getElementsByTagName("IMG")[0.to_s].src
1549
+ end
1550
+ s=s+"\n"
1551
+ end
1552
+ puts s
1553
+ end
1554
+
1555
+ # this method shows the name, id etc of the object that is currently active - ie the element that has focus
1556
+ # its mostly used in irb when creating a script
1557
+ def show_active
1558
+ s = ""
1559
+
1560
+ current = document.activeElement
1561
+ begin
1562
+ s=s+current.invoke("type").to_s.ljust(16)
1563
+ rescue
1564
+ end
1565
+ props=["name", "id", "value", "alt", "src", "innerText", "href"]
1566
+ props.each do |prop|
1567
+ begin
1568
+ p = current.invoke(prop)
1569
+ s =s+ " " + "#{prop}=#{p}".to_s.ljust(18)
1570
+ rescue
1571
+ #this object probably doesnt have this property
1572
+ end
1573
+ end
1574
+ s=s+"\n"
1575
+ end
1576
+
1577
+ # This method shows the available objects on the current page.
1578
+ # This is usually only used for debugging or writing new test scripts.
1579
+ # This is a nice feature to help find out what HTML objects are on a page
1580
+ # when developing a test case using Watir.
1581
+ def show_all_objects
1582
+ puts "-----------Objects in page -------------"
1583
+ doc = document
1584
+ s = ""
1585
+ props=["name" ,"id" , "value" , "alt" , "src"]
1586
+ doc.all.each do |n|
1587
+ begin
1588
+ s=s+n.invoke("type").to_s.ljust(16)
1589
+ rescue
1590
+ next
1591
+ end
1592
+ props.each do |prop|
1593
+ begin
1594
+ p = n.invoke(prop)
1595
+ s =s+ " " + "#{prop}=#{p}".to_s.ljust(18)
1596
+ rescue
1597
+ # this object probably doesnt have this property
1598
+ end
1599
+ end
1600
+ s=s+"\n"
1601
+ end
1602
+ puts s+"\n\n\n"
1603
+ end
1604
+
1605
+ # this method shows all the divs availble in the document
1606
+ def show_divs
1607
+ divs = document.getElementsByTagName("DIV")
1608
+ puts "Found #{divs.length} div tags"
1609
+ index=1
1610
+ divs.each do |d|
1611
+ puts "#{index} id=#{d.invoke('id')} class=#{d.invoke("className")}"
1612
+ index+=1
1613
+ end
1614
+ end
1615
+
1616
+ # this method is used to show all the tables that are available
1617
+ def show_tables
1618
+ tables = document.getElementsByTagName("TABLE")
1619
+ puts "Found #{tables.length} tables"
1620
+ index=1
1621
+ tables.each do |d|
1622
+ puts "#{index} id=#{d.invoke('id')} rows=#{d.rows.length} columns=#{d.rows["0"].cells.length }"
1623
+ index+=1
1624
+ end
1625
+ end
1626
+
1627
+ # this method shows all the spans availble in the document
1628
+ def show_spans
1629
+ spans = document.getElementsByTagName("SPAN")
1630
+ puts "Found #{spans.length} span tags"
1631
+ index=1
1632
+ spans.each do |d|
1633
+ puts "#{index} id=#{d.invoke('id')} class=#{d.invoke("className")}"
1634
+ index+=1
1635
+ end
1636
+ end
1637
+
1638
+ def show_labels
1639
+ labels = document.getElementsByTagName("LABEL")
1640
+ puts "Found #{labels.length} label tags"
1641
+ index=1
1642
+ labels.each do |d|
1643
+ puts "#{index} text=#{d.invoke('innerText')} class=#{d.invoke("className")} for=#{d.invoke("htmlFor")}"
1644
+ index+=1
1645
+ end
1646
+ end
1647
+
1648
+ #
1649
+ # This method gives focus to the frame
1650
+ # It may be removed and become part of the frame object
1651
+ def focus
1652
+ document.activeElement.blur
1653
+ document.focus
1654
+ end
1655
+
1656
+ end # class IE
1657
+
1658
+ #
1659
+ # MOVETO: watir/popup.rb
1660
+ # Module Watir::Popup
1661
+ #
1662
+
1663
+ # POPUP object
1664
+ class PopUp
1665
+ def initialize( ieController )
1666
+ @ieController = ieController
1667
+ end
1668
+
1669
+ def button( caption )
1670
+ return JSButton.new( @ieController.getIE.hwnd , caption )
1671
+ end
1672
+ end
1673
+
1674
+ class JSButton
1675
+ def initialize( hWnd , caption )
1676
+ @hWnd = hWnd
1677
+ @caption = caption
1678
+ end
1679
+
1680
+ def startClicker( waitTime = 3 )
1681
+ clicker = WinClicker.new
1682
+ clicker.clickJSDialog_Thread
1683
+ # clickerThread = Thread.new( @caption ) {
1684
+ # sleep waitTime
1685
+ # puts "After the wait time in startClicker"
1686
+ # clickWindowsButton_hwnd(hwnd , buttonCaption )
1687
+ #}
1688
+ end
1689
+ end
1690
+
1691
+ #
1692
+ # Module Watir::Control or Watir::BrowserDriver
1693
+ #
1694
+
1695
+ class Frame < IE
1696
+
1697
+ def initialize(container, how, what)
1698
+ @container = container
1699
+ @frame = nil
1700
+
1701
+ frames = @container.document.frames
1702
+
1703
+ for i in 0 .. frames.length-1
1704
+ next unless @frame == nil
1705
+ this_frame = frames.item(i)
1706
+ if how == :index
1707
+ if i+1 == what
1708
+ @frame = this_frame
1709
+ end
1710
+ elsif how == :name
1711
+ begin
1712
+ if what.matches(this_frame.name)
1713
+ @frame = this_frame
1714
+ end
1715
+ rescue # access denied?
1716
+ end
1717
+ elsif how == :id
1718
+ # BUG: Won't work for IFRAMES
1719
+ if what.matches(@container.document.getElementsByTagName("FRAME").item(i).invoke("id"))
1720
+ @frame = this_frame
1721
+ end
1722
+ else
1723
+ raise ArgumentError, "Argument #{how} not supported"
1724
+ end
1725
+ end
1726
+
1727
+ unless @frame
1728
+ raise UnknownFrameException , "Unable to locate a frame with name #{ what} "
1729
+ end
1730
+
1731
+ @typingspeed = container.typingspeed
1732
+ @activeObjectHighLightColor = container.activeObjectHighLightColor
1733
+ end
1734
+
1735
+ def ie
1736
+ return @frame
1737
+ end
1738
+
1739
+ def document
1740
+ @frame.document
1741
+ end
1742
+
1743
+ def wait(no_sleep = false)
1744
+ @container.wait(no_sleep)
1745
+ end
1746
+ end
1747
+
1748
+
1749
+ # Forms
1750
+
1751
+ module FormAccess
1752
+ def name
1753
+ @form.getAttributeNode('name').value
1754
+ end
1755
+ def action
1756
+ @form.action
1757
+ end
1758
+ def method
1759
+ @form.invoke('method')
1760
+ end
1761
+ def id
1762
+ @form.invoke("id").to_s
1763
+ end
1764
+ end
1765
+
1766
+ # wraps around a form OLE object
1767
+ class FormWrapper
1768
+ include FormAccess
1769
+ def initialize ( ole_object )
1770
+ @form = ole_object
1771
+ end
1772
+ end
1773
+
1774
+ # Form Factory object
1775
+ class Form < IE
1776
+ include FormAccess
1777
+
1778
+ attr_accessor :form
1779
+
1780
+
1781
+ # * container - the containing object, normally an instance of IE
1782
+ # * how - symbol - how we access the form (:name, :id, :index, :action, :method)
1783
+ # * what - what we use to access the form
1784
+ def initialize( container, how, what )
1785
+ @container = container
1786
+ @formHow = how
1787
+ @formName = what
1788
+
1789
+ log "Get form formHow is #{@formHow} formName is #{@formName} "
1790
+ count = 1
1791
+ doc = @container.document
1792
+ doc.forms.each do |thisForm|
1793
+ next unless @form == nil
1794
+
1795
+ wrapped = FormWrapper.new(thisForm)
1796
+
1797
+ log "form on page, name is " + wrapped.name
1798
+
1799
+ @form =
1800
+ case @formHow
1801
+ when :name
1802
+ wrapped.name == @formName ? thisForm : nil
1803
+ when :id
1804
+ wrapped.id == @formName.to_s ? thisForm : nil
1805
+ when :index
1806
+ count == @formName.to_i ? thisForm : nil
1807
+ when :method
1808
+ wrapped.method.downcase == @formName.downcase ? thisForm : nil
1809
+ when :action
1810
+ @formName.matches(wrapped.action) ? thisForm : nil
1811
+ else
1812
+ raise MissingWayOfFindingObjectException
1813
+ end
1814
+ count = count +1
1815
+ end
1816
+
1817
+ @typingspeed = @container.typingspeed
1818
+ @activeObjectHighLightColor = @container.activeObjectHighLightColor
1819
+ end
1820
+
1821
+ def exists?
1822
+ @form ? true : false
1823
+ end
1824
+
1825
+ # Submit the data -- equivalent to pressing Enter or Return to submit a form.
1826
+ def submit
1827
+ raise UnknownFormException , "Unable to locate a form using #{@formHow} and #{@formName} " if @form == nil
1828
+ @form.submit
1829
+ @container.wait
1830
+ end
1831
+
1832
+ def getContainerContents
1833
+ raise UnknownFormException , "Unable to locate a form using #{@formHow} and #{@formName} " if @form == nil
1834
+ @form.elements.all
1835
+ end
1836
+ private :getContainerContents
1837
+
1838
+ def getContainer
1839
+ return @form
1840
+ end
1841
+
1842
+ def wait(no_sleep = false)
1843
+ @container.wait(no_sleep)
1844
+ end
1845
+
1846
+ # This method is responsible for setting and clearing the colored highlighting on the specified form.
1847
+ # use :set to set the highlight
1848
+ # :clear to clear the highlight
1849
+ def highLight( setOrClear , element , count)
1850
+
1851
+ if setOrClear == :set
1852
+ begin
1853
+ original_color = element.style.backgroundColor
1854
+ original_color = "" if original_color== nil
1855
+ element.style.backgroundColor = activeObjectHighLightColor
1856
+ rescue => e
1857
+ puts e
1858
+ puts e.backtrace.join("\n")
1859
+ original_color = ""
1860
+ end
1861
+ @original_styles[ count ] = original_color
1862
+ else
1863
+ begin
1864
+ element.style.backgroundColor = @original_styles[ count]
1865
+ rescue => e
1866
+ puts e
1867
+ # we could be here for a number of reasons...
1868
+ ensure
1869
+ end
1870
+ end
1871
+ end
1872
+ private :highLight
1873
+
1874
+ # causes the object to flash. Normally used in IRB when creating scripts
1875
+ def flash
1876
+ @original_styles = {}
1877
+ 10.times do
1878
+ count=0
1879
+ @form.elements.each do |element|
1880
+ highLight(:set , element , count)
1881
+ count +=1
1882
+ end
1883
+ sleep 0.05
1884
+ count = 0
1885
+ @form.elements.each do |element|
1886
+ highLight(:clear , element , count)
1887
+ count +=1
1888
+ end
1889
+ sleep 0.05
1890
+ end
1891
+ end
1892
+
1893
+ end # class Form
1894
+
1895
+ # Base class for most elements.
1896
+ # This is not a class that users would normally access.
1897
+ class Element
1898
+ include Watir::Exception
1899
+
1900
+ # number of spaces that seperate the property from the value in the to_s method
1901
+ TO_S_SIZE = 14
1902
+
1903
+ # o - the ole object for the element being wrapped
1904
+ def initialize( o )
1905
+ @o = o
1906
+ @originalColor = nil
1907
+ end
1908
+
1909
+ private
1910
+ def self.def_wrap(method_name)
1911
+ class_eval "def #{method_name}
1912
+ assert_exists
1913
+ @o.invoke('#{method_name}')
1914
+ end"
1915
+ end
1916
+ def self.def_wrap_guard(method_name)
1917
+ class_eval "def #{method_name}
1918
+ assert_exists
1919
+ begin
1920
+ @o.invoke('#{method_name}')
1921
+ rescue
1922
+ ''
1923
+ end
1924
+ end"
1925
+ end
1926
+ def assert_exists
1927
+ unless @o
1928
+ raise UnknownObjectException.new("Unable to locate object, using #{@how} and #{@what}")
1929
+ end
1930
+ end
1931
+ def assert_enabled
1932
+ unless enabled?
1933
+ raise ObjectDisabledException, "object #{@how} and #{@what} is disabled"
1934
+ end
1935
+ end
1936
+
1937
+ public
1938
+ def_wrap_guard :type
1939
+ def_wrap_guard :name
1940
+ def_wrap :id
1941
+ def_wrap :disabled
1942
+ def_wrap_guard :value
1943
+ def_wrap_guard :title
1944
+
1945
+ # returns the Object in its OLE form, allowing any methods of the DOM that Watir doesnt support to be used
1946
+ #--
1947
+ # BUG: should be renamed appropriately and then use an attribute reader
1948
+ #++
1949
+ def getOLEObject
1950
+ return @o
1951
+ end
1952
+
1953
+ # returns the outer html of the object - see http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/outerhtml.asp?frame=true
1954
+ def html
1955
+ assert_exists
1956
+ return @o.outerHTML
1957
+ end
1958
+
1959
+ # Returns an array with many of the properties, in a format to be used by the to_s method
1960
+ def string_creator
1961
+ n = []
1962
+ n << "type:".ljust(TO_S_SIZE) + self.type
1963
+ n << "id:".ljust(TO_S_SIZE) + self.id.to_s
1964
+ n << "name:".ljust(TO_S_SIZE) + self.name.to_s
1965
+ n << "value:".ljust(TO_S_SIZE) + self.value.to_s
1966
+ n << "disabled:".ljust(TO_S_SIZE) + self.disabled.to_s
1967
+ return n
1968
+ end
1969
+
1970
+ # This method displays basic details about the object. Sample output for a button is shown.
1971
+ # Raises UnknownObjectException if the object is not found.
1972
+ # name b4
1973
+ # type button
1974
+ # id b5
1975
+ # value Disabled Button
1976
+ # disabled true
1977
+ def to_s
1978
+ assert_exists
1979
+ return string_creator.join("\n")
1980
+ end
1981
+
1982
+ # This method is responsible for setting and clearing the colored highlighting on the currently active element.
1983
+ # use :set to set the highlight
1984
+ # :clear to clear the highlight
1985
+ def highLight( setOrClear )
1986
+ if setOrClear == :set
1987
+ begin
1988
+ @originalColor = @o.style.backgroundColor
1989
+ @o.style.backgroundColor = @ieController.activeObjectHighLightColor
1990
+ rescue
1991
+ @originalColor = nil
1992
+ end
1993
+ else # BUG: assumes is :clear, but could actually be anything
1994
+ begin
1995
+ @o.style.backgroundColor = @originalColor unless @originalColor == nil
1996
+ rescue
1997
+ # we could be here for a number of reasons...
1998
+ ensure
1999
+ @originalColor = nil
2000
+ end
2001
+ end
2002
+ end
2003
+ private :highLight
2004
+
2005
+ # This method clicks the active element.
2006
+ # raises: UnknownObjectException if the object is not found
2007
+ # ObjectDisabledException if the object is currently disabled
2008
+ def click
2009
+ assert_exists
2010
+ assert_enabled
2011
+
2012
+ highLight(:set)
2013
+ @o.click()
2014
+ @ieController.wait()
2015
+ highLight(:clear)
2016
+ end
2017
+
2018
+ # causes the object to flash. Normally used in IRB when creating scripts
2019
+ def flash
2020
+ assert_exists
2021
+ 10.times do
2022
+ highLight(:set)
2023
+ sleep 0.05
2024
+ highLight(:clear)
2025
+ sleep 0.05
2026
+ end
2027
+ nil
2028
+ end
2029
+
2030
+ # This method executes a user defined "fireEvent" for objects with JavaScript events tied to them such as DHTML menus.
2031
+ # usage: allows a generic way to fire javascript events on page objects such as "onMouseOver", "onClick", etc.
2032
+ # raises: UnknownObjectException if the object is not found
2033
+ # ObjectDisabledException if the object is currently disabled
2034
+ def fireEvent(event)
2035
+ assert_exists
2036
+ assert_enabled
2037
+
2038
+ highLight(:set)
2039
+ @o.fireEvent(event)
2040
+ @ieController.wait()
2041
+ highLight(:clear)
2042
+ end
2043
+ alias fire_event fireEvent
2044
+
2045
+ # This method sets focus on the active element.
2046
+ # raises: UnknownObjectException if the object is not found
2047
+ # ObjectDisabledException if the object is currently disabled
2048
+ def focus()
2049
+ assert_exists
2050
+ assert_enabled
2051
+ @o.focus()
2052
+ end
2053
+
2054
+ # This methods checks to see if the current element actually exists.
2055
+ def exists?
2056
+ @o? true: false
2057
+ end
2058
+
2059
+ # Returns true if the element is enabled, false if it isn't.
2060
+ # raises: UnknownObjectException if the object is not found
2061
+ def enabled?
2062
+ assert_exists
2063
+ return ! @o.invoke("disabled")
2064
+ end
2065
+ end
2066
+
2067
+
2068
+ # this class is the super class for the iterator classes ( buttons, links, spans etc
2069
+ # it would normally only be accessed by the iterator methods ( spans , links etc) of IE
2070
+ class ElementCollections
2071
+ include Enumerable
2072
+
2073
+ # Super class for all the iteractor classes
2074
+ # * ieController - an instance of an IE object
2075
+ def initialize( ieController)
2076
+ @ieController = ieController
2077
+ @length = length() # defined by subclasses
2078
+
2079
+ # set up the items we want to display when the show method s used
2080
+ set_show_items
2081
+ end
2082
+
2083
+ def set_show_items
2084
+ @show_attributes = AttributeLengthPairs.new( "id" , 20)
2085
+ @show_attributes.add( "name" , 20)
2086
+ end
2087
+
2088
+ def get_length_of_input_objects(object_type)
2089
+ object_types =
2090
+ if object_type.kind_of? Array
2091
+ object_type
2092
+ else
2093
+ [ object_type ]
2094
+ end
2095
+
2096
+ length = 0
2097
+ objects = @ieController.getContainer.getElementsByTagName("INPUT")
2098
+ if objects.length > 0
2099
+ objects.each do |o|
2100
+ length += 1 if object_types.include?(o.invoke("type").downcase )
2101
+ end
2102
+ end
2103
+ return length
2104
+ end
2105
+
2106
+ # iterate through each of the elements in the collection in turn
2107
+ def each
2108
+ 0.upto( @length-1 ) { |i | yield iterator_object(i) }
2109
+ end
2110
+
2111
+ # allows access to a specific item in the collection
2112
+ def [](n)
2113
+ return iterator_object(n-1)
2114
+ end
2115
+
2116
+ # this method is the way to show the objects, normally used from irb
2117
+ def show
2118
+ s="index".ljust(6)
2119
+ @show_attributes.each do |attribute_length_pair|
2120
+ s=s + attribute_length_pair.attribute.ljust(attribute_length_pair.length)
2121
+ end
2122
+
2123
+ index = 1
2124
+ self.each do |o|
2125
+ s= s+"\n"
2126
+ s=s + index.to_s.ljust(6)
2127
+ @show_attributes.each do |attribute_length_pair|
2128
+ begin
2129
+ s=s + eval( 'o.getOLEObject.invoke("#{attribute_length_pair.attribute}")').to_s.ljust( attribute_length_pair.length )
2130
+ rescue=>e
2131
+ s=s+ " ".ljust( attribute_length_pair.length )
2132
+ end
2133
+ end
2134
+ index+=1
2135
+ end
2136
+ puts s
2137
+ end
2138
+
2139
+ # this method creates an object of the correct type that the iterators use
2140
+ private
2141
+ def iterator_object(i)
2142
+ element_class.new(@ieController, :index, i+1)
2143
+ end
2144
+ end
2145
+
2146
+ # this class contains items that are common between the span and div objects
2147
+ # it would not normally be used directly
2148
+ #
2149
+ # many of the methods available to this object are inherited from the Element class
2150
+ #
2151
+ class SpanDivCommon < Element
2152
+ include Watir::Exception
2153
+ include SupportsSubElements
2154
+
2155
+ attr_reader :typingspeed
2156
+
2157
+ def initialize( ieController, how , what )
2158
+ @ieController = ieController
2159
+ @how = how
2160
+ @what = what
2161
+ @o = @ieController.getNonControlObject(tag , @how, @what )
2162
+ super( @o )
2163
+ @typingspeed = @ieController.typingspeed
2164
+ @activeObjectHighLightColor = @ieController.activeObjectHighLightColor
2165
+ end
2166
+
2167
+ def getContainerContents()
2168
+ return @o.all
2169
+ end
2170
+ private :getContainerContents
2171
+
2172
+ def getContainer()
2173
+ return @o
2174
+ end
2175
+
2176
+ # this method returns the innerText of the object
2177
+ # raises an ObjectNotFound exception if the object cannot be found
2178
+ def text
2179
+ assert_exists
2180
+ return @o.innerText.strip
2181
+ end
2182
+
2183
+ # returns the class name of the span or div is using
2184
+ # raises an ObjectNotFound exception if the object cannot be found
2185
+ def class_name
2186
+ assert_exists
2187
+ return @o.invoke("className")
2188
+ end
2189
+
2190
+ # this method returns the type of object
2191
+ # raises an ObjectNotFound exception if the object cannot be found
2192
+ def type
2193
+ assert_exists
2194
+ return self.class.name[self.class.name.index("::")+2 .. self.class.name.length ]
2195
+ end
2196
+
2197
+ # this method is used to populate the properties in the to_s method
2198
+ def span_div_string_creator
2199
+ n = []
2200
+ n << "class:".ljust(TO_S_SIZE) + self.class_name
2201
+ n << "text:".ljust(TO_S_SIZE) + self.text
2202
+ return n
2203
+ end
2204
+ private :span_div_string_creator
2205
+
2206
+ # returns the properties of the object in a string
2207
+ # raises an ObjectNotFound exception if the object cannot be found
2208
+ def to_s
2209
+ assert_exists
2210
+ r = string_creator
2211
+ r=r + span_div_string_creator
2212
+ return r.join("\n")
2213
+ end
2214
+ end
2215
+
2216
+ class P < SpanDivCommon
2217
+ TAG = 'P'
2218
+ def tag; TAG; end
2219
+ def self.tag; TAG; end
2220
+ end
2221
+
2222
+ # this class is used to deal with Div tags in the html page. http://msdn.microsoft.com/workshop/author/dhtml/reference/objects/div.asp?frame=true
2223
+ # It would not normally be created by users
2224
+ class Div < SpanDivCommon
2225
+ TAG = 'DIV'
2226
+ def tag; TAG; end
2227
+ def self.tag; TAG; end
2228
+ end
2229
+
2230
+ # this class is used to deal with Span tags in the html page. It would not normally be created by users
2231
+ class Span < SpanDivCommon
2232
+ TAG = 'SPAN'
2233
+ def tag; TAG; end
2234
+ def self.tag; TAG; end
2235
+ end
2236
+
2237
+ # this class is used to access a label object on the html page - http://msdn.microsoft.com/workshop/author/dhtml/reference/objects/label.asp?frame=true
2238
+ #
2239
+ # many of the methods available to this object are inherited from the Element class
2240
+ #
2241
+ class Label < Element
2242
+ def initialize( ieController , how, what)
2243
+ @ieController = ieController
2244
+ @how = how
2245
+ @what = what
2246
+ @o = @ieController.getNonControlObject("LABEL" , @how, @what )
2247
+ super( @o )
2248
+ end
2249
+
2250
+ # return the type of this object
2251
+ def type
2252
+ assert_exists
2253
+ return "Label"
2254
+ end
2255
+
2256
+ # return the ID of the control that this label is associated with
2257
+ def for
2258
+ assert_exists
2259
+ return @o.htmlFor
2260
+ end
2261
+
2262
+ def text
2263
+ assert_exists
2264
+ return @o.innerText.strip
2265
+ end
2266
+ alias innerText :text
2267
+
2268
+ # this method is used to populate the properties in the to_s method
2269
+ def label_string_creator
2270
+ n = []
2271
+ n << "for:".ljust(TO_S_SIZE) + self.for
2272
+ n << "inner text:".ljust(TO_S_SIZE) + self.innerText
2273
+ return n
2274
+ end
2275
+ private :label_string_creator
2276
+
2277
+ # returns the properties of the object in a string
2278
+ # raises an ObjectNotFound exception if the object cannot be found
2279
+ def to_s
2280
+ assert_exists
2281
+ r = string_creator
2282
+ r=r + label_string_creator
2283
+ return r.join("\n")
2284
+ end
2285
+
2286
+ end
2287
+
2288
+ # This class is used for dealing with tables.
2289
+ # Normally a user would not need to create this object as it is returned by the Watir::SupportsSubElements#table method
2290
+ #
2291
+ # many of the methods available to this object are inherited from the Element class
2292
+ #
2293
+ class Table < Element
2294
+
2295
+ # Returns an initialized instance of the table object to wich anElement belongs
2296
+ # * ieController - an instance of an IE object
2297
+ # * anElement - a Watir object (TextField, Button, etc.)
2298
+ def Table.create_from_element(ieController,anElement)
2299
+ o = anElement.getOLEObject.parentElement
2300
+ while(o && o.tagName != 'TABLE')
2301
+ o = o.parentElement
2302
+ end
2303
+ return Table.new(ieController,:from_object,o)
2304
+ end
2305
+
2306
+ # Returns an initialized instance of a table object
2307
+ # * parent - an instance of an IEController ( or a frame etc )
2308
+ # * how - symbol - how we access the table
2309
+ # * what - what we use to access the table - id, name index etc
2310
+ def initialize( parent, how , what )
2311
+ @ieController = parent
2312
+ @how = how
2313
+ @what = what
2314
+
2315
+ table = nil
2316
+
2317
+ if(@how != :from_object) then
2318
+ table=get_table
2319
+ else
2320
+ table = @what
2321
+ end
2322
+
2323
+ parent.log "table - #{@what}, #{@how} Not found " if table == nil
2324
+ @o = table
2325
+ super( @o )
2326
+ end
2327
+
2328
+ # ---
2329
+ # BUG: should be private
2330
+ # +++
2331
+ # this method finds the specified table on the page
2332
+ def get_table
2333
+ allTables = @ieController.document.getElementsByTagName("TABLE")
2334
+ @ieController.log "There are #{ allTables.length } tables"
2335
+ tableIndex = 1
2336
+ table=nil
2337
+ allTables.each do |t|
2338
+ next unless table == nil
2339
+ case @how
2340
+ when :id
2341
+ if @what.matches( t.invoke("id").to_s )
2342
+ table = t
2343
+ end
2344
+ when :index
2345
+ if tableIndex == @what.to_i
2346
+ table = t
2347
+ end
2348
+ end
2349
+ tableIndex = tableIndex + 1
2350
+ end
2351
+ return table
2352
+ end
2353
+
2354
+
2355
+ # override the highlight method, as if the tables rows are set to have a background color,
2356
+ # this will override the table background color, and the normal flsh method wont work
2357
+ def highLight(setOrClear )
2358
+
2359
+ if setOrClear == :set
2360
+ begin
2361
+ @original_border = @o.border.to_i
2362
+ if @o.border.to_i==1
2363
+ @o.border = 2
2364
+ else
2365
+ @o.border=1
2366
+ end
2367
+ rescue
2368
+ @original_border = nil
2369
+ end
2370
+ else
2371
+ begin
2372
+ @o.border= @original_border unless @original_border == nil
2373
+ @original_border = nil
2374
+ rescue
2375
+ # we could be here for a number of reasons...
2376
+ ensure
2377
+ @original_border = nil
2378
+ end
2379
+ end
2380
+ super
2381
+ end
2382
+
2383
+ # this method is used to ppulate the properties in the to_s method
2384
+ def table_string_creator
2385
+ n = []
2386
+ n << "rows:".ljust(TO_S_SIZE) + self.row_count.to_s
2387
+ n << "cols:".ljust(TO_S_SIZE) + self.column_count.to_s
2388
+ return n
2389
+ end
2390
+ private :table_string_creator
2391
+
2392
+ # returns the properties of the object in a string
2393
+ # raises an ObjectNotFound exception if the object cannot be found
2394
+ def to_s
2395
+ assert_exists
2396
+ r = string_creator
2397
+ r=r + table_string_creator
2398
+ return r.join("\n")
2399
+ end
2400
+
2401
+ # iterates through the rows in the table. Yields a TableRow object
2402
+ def each
2403
+ assert_exists
2404
+ 1.upto( @o.getElementsByTagName("TR").length ) { |i | yield TableRow.new(@ieController ,:direct, row(i) ) }
2405
+ end
2406
+
2407
+ # Returns a row in the table
2408
+ # * index - the index of the row
2409
+ def [](index)
2410
+ raise UnknownTableException , "Unable to locate a table using #{@how} and #{@what} " if @o == nil
2411
+ return TableRow.new(@ieController ,:direct, row(index) )
2412
+ end
2413
+
2414
+ # This method returns the number of rows in the table.
2415
+ # Raises an UnknownTableException if the table doesnt exist.
2416
+ def row_count
2417
+ raise UnknownTableException , "Unable to locate a table using #{@how} and #{@what} " if @o == nil
2418
+ #return table_body.children.length
2419
+ return @o.getElementsByTagName("TR").length
2420
+ end
2421
+
2422
+ # This method returns the number of columns in a row of the table.
2423
+ # Raises an UnknownTableException if the table doesn't exist.
2424
+ # * index - the index of the row
2425
+ def column_count(index=1)
2426
+ raise UnknownTableException , "Unable to locate a table using #{@how} and #{@what} " if @o == nil
2427
+ row(index).cells.length
2428
+ end
2429
+
2430
+ # This method returns the table as a 2 dimensional array. Dont expect too much if there are nested tables, colspan etc.
2431
+ # Raises an UnknownTableException if the table doesn't exist.
2432
+ def to_a
2433
+ raise UnknownTableException , "Unable to locate a table using #{@how} and #{@what} " if @o == nil
2434
+ y = []
2435
+ table_rows = @o.getElementsByTagName("TR")
2436
+ for row in table_rows
2437
+ x = []
2438
+ for td in row.getElementsbyTagName("TD")
2439
+ x << td.innerText.strip
2440
+ end
2441
+ y << x
2442
+ end
2443
+ return y
2444
+
2445
+ end
2446
+
2447
+ def table_body(index=1)
2448
+ return @o.getElementsByTagName('TBODY')[index]
2449
+ end
2450
+ private :table_body
2451
+
2452
+ def body( how , what )
2453
+ return TableBody.new( @ieController, how, what , self)
2454
+ end
2455
+
2456
+ def bodies
2457
+ return TableBodies.new(@ieController, :direct , @o)
2458
+ end
2459
+
2460
+ def row(index)
2461
+ return @o.invoke("rows")[(index-1).to_s]
2462
+ end
2463
+ private :row
2464
+
2465
+ # Returns an array containing all the text values in the specified column
2466
+ # Raises an UnknownCellException if the specified column does not exist in every
2467
+ # Raises an UnknownTableException if the table doesn't exist.
2468
+ # row of the table
2469
+ # * columnnumber - column index to extract values from
2470
+ def column_values(columnnumber)
2471
+ return (1..row_count).collect {|idx| self[idx][columnnumber].text}
2472
+ end
2473
+
2474
+ # Returns an array containing all the text values in the specified row
2475
+ # Raises an UnknownTableException if the table doesn't exist.
2476
+ # * rownumber - row index to extract values from
2477
+ def row_values(rownumber)
2478
+ return (1..column_count(rownumber)).collect {|idx| self[rownumber][idx].text}
2479
+ end
2480
+
2481
+ end
2482
+
2483
+
2484
+ # this class is a collection of the table body objects that exist in the table
2485
+ # it wouldnt normally be created by a user, but gets returned by the bodies method of the Table object
2486
+ # many of the methods available to this object are inherited from the Element class
2487
+ #
2488
+ class TableBodies<Element
2489
+ def initialize(ieController, how, what )
2490
+ @ieController = ieController
2491
+ @o= nil
2492
+ if how == :direct
2493
+ @o = what # in this case, @o is the parent table
2494
+ end
2495
+ end
2496
+
2497
+ # returns the number of TableBodies that exist in the table
2498
+ def length
2499
+ assert_exists
2500
+ return @o.tBodies.length
2501
+ end
2502
+
2503
+ # returns the n'th Body as a Watir TableBody object
2504
+ def []n
2505
+ assert_exists
2506
+ return TableBody.new( @ieController , :direct , @o.tBodies[(n-1).to_s] )
2507
+ end
2508
+
2509
+ def get_IE_table_body_at_index( n )
2510
+ return @o.tBodies[(n-1).to_s]
2511
+ end
2512
+
2513
+ # iterates through each of the TableBodies in the Table. Yields a TableBody object
2514
+ def each
2515
+ 0.upto( @o.tBodies.length-1 ) { |i | yield TableBody.new( @ieController , :direct , @o.tBodies[i.to_s] ) }
2516
+ end
2517
+
2518
+ end
2519
+
2520
+
2521
+ # this class is a table body
2522
+ class TableBody<Element
2523
+ def initialize(ieController, how, what, parent_table=nil )
2524
+ @ieController = ieController
2525
+ @o= nil
2526
+ if how == :direct
2527
+ @o = what # in this case, @o is the table body
2528
+ elsif how == :index
2529
+ @o=parent_table.bodies.get_IE_table_body_at_index( what )
2530
+ end
2531
+ @rows = []
2532
+ update_rows
2533
+ super(@o)
2534
+ end
2535
+
2536
+ # This method updates the internal representation of the table. It can be used on dynamic tables to update the watir representation
2537
+ # after the table has changed
2538
+ # BUG: Remove
2539
+ def update_rows
2540
+ if @o
2541
+ @o.rows.each do |oo|
2542
+ @rows << TableRow.new(@ieController, :direct, oo)
2543
+ end
2544
+ end
2545
+ end
2546
+
2547
+ # returns the specified row as a TableRow object
2548
+ def []n
2549
+ assert_exists
2550
+ return TableRow.new( @ieController , :direct , @rows[n-1] )
2551
+ end
2552
+
2553
+ # iterates through all the rows in the table body
2554
+ def each
2555
+ 0.upto( @rows.length-1 ) { |i | yield @rows[i] }
2556
+ end
2557
+
2558
+ # returns the number of rows in this table body.
2559
+ def length
2560
+ return @rows.length
2561
+ end
2562
+ end
2563
+
2564
+
2565
+ # this class is a table row
2566
+ class TableRow < Element
2567
+
2568
+ # Returns an initialized instance of a table row
2569
+ # * o - the object contained in the row
2570
+ # * ieController - an instance of an IE object
2571
+ # * how - symbol - how we access the row
2572
+ # * what - what we use to access the row - id, index etc. If how is :direct then what is a Internet Explorer Raw Row
2573
+ def initialize(ieController , how, what)
2574
+ @ieController = ieController
2575
+ @how = how
2576
+ @what = what
2577
+ @o=nil
2578
+ if how == :direct
2579
+ @o = what
2580
+ else
2581
+ @o = ieController.getTablePart( "TR" , how , what )
2582
+ end
2583
+ update_row_cells
2584
+ super( @o )
2585
+ end
2586
+
2587
+
2588
+ # this method updates the internal list of cells.
2589
+ def update_row_cells
2590
+ if @o # cant call the assert_exists here, as an exists? method call will fail
2591
+ @cells=[]
2592
+ @o.cells.each do |oo|
2593
+ @cells << TableCell.new(@ieController, :direct, oo)
2594
+ end
2595
+ end
2596
+ end
2597
+
2598
+ # this method iterates through each of the cells in the row. Yields a TableCell object
2599
+ def each
2600
+ 0.upto( @cells.length-1 ) { |i | yield @cells[i] }
2601
+ end
2602
+
2603
+ # Returns an element from the row as a TableCell object
2604
+ def [](index)
2605
+ assert_exists
2606
+ raise UnknownCellException , "Unable to locate a cell at index #{index}" if @cells.length < index
2607
+ return @cells[(index-1)]
2608
+ end
2609
+
2610
+ #defaults all missing methods to the array of elements, to be able to
2611
+ # use the row as an array
2612
+ def method_missing(aSymbol,*args)
2613
+ return @o.send(aSymbol,*args)
2614
+ end
2615
+
2616
+ def column_count
2617
+ @cells.length
2618
+ end
2619
+ end
2620
+
2621
+ # this class is a table cell - when called via the Table object
2622
+ class TableCell <Element
2623
+ include Watir::Exception
2624
+ include SupportsSubElements
2625
+
2626
+ attr_reader :typingspeed
2627
+ attr_reader :activeObjectHighLightColor
2628
+
2629
+ # Returns an initialized instance of a table cell
2630
+ # * ieController - an IE object
2631
+ # * how - symbol - how we access the cell
2632
+ # * what - what we use to access the cell - id, name index etc
2633
+ def initialize( ieController, how , what )
2634
+ @ieController = ieController
2635
+ #puts "How = #{how}"
2636
+ if how == :direct
2637
+ @o = what
2638
+ #puts "@o.class=#{@o.class}"
2639
+ else
2640
+ @o = ieController.getTablePart( "TD" , how , what )
2641
+ end
2642
+ super( @o )
2643
+ @how = how
2644
+ @what = what
2645
+ @typingspeed = @ieController.typingspeed
2646
+ @activeObjectHighLightColor = @ieController.activeObjectHighLightColor
2647
+ end
2648
+
2649
+ def getContainerContents
2650
+ return @o.all
2651
+ end
2652
+ private :getContainerContents
2653
+
2654
+ def getContainer
2655
+ return @o
2656
+ end
2657
+
2658
+ def document
2659
+ return @o
2660
+ end
2661
+
2662
+ # returns the contents of the cell as text
2663
+ def text
2664
+ raise UnknownObjectException , "Unable to locate table cell with #{@how} of #{@what}" if @o == nil
2665
+ return @o.innerText.strip
2666
+ end
2667
+ alias to_s text
2668
+
2669
+ def colspan
2670
+ @o.colSpan
2671
+ end
2672
+
2673
+ end
2674
+
2675
+ # This class is the means of accessing an image on a page.
2676
+ # Normally a user would not need to create this object as it is returned by the Watir::SupportsSubElements#image method
2677
+ #
2678
+ # many of the methods available to this object are inherited from the Element class
2679
+ #
2680
+ class Image < Element
2681
+
2682
+ # Returns an initialized instance of a image object
2683
+ # * ieController - an instance of an IEController
2684
+ # * how - symbol - how we access the image
2685
+ # * what - what we use to access the image, name, src, index, id or alt
2686
+ def initialize( ieController, how , what )
2687
+ @ieController = ieController
2688
+ @how = how
2689
+ @what = what
2690
+ @o = @ieController.getImage(@how, @what)
2691
+ super( @o )
2692
+ end
2693
+
2694
+ # this method produces the properties for an image as an array
2695
+ def image_string_creator
2696
+ n = []
2697
+ n << "src:".ljust(TO_S_SIZE) + self.src.to_s
2698
+ n << "file date:".ljust(TO_S_SIZE) + self.fileCreatedDate.to_s
2699
+ n << "file size:".ljust(TO_S_SIZE) + self.fileSize.to_s
2700
+ n << "width:".ljust(TO_S_SIZE) + self.width.to_s
2701
+ n << "height:".ljust(TO_S_SIZE) + self.height.to_s
2702
+ n << "alt:".ljust(TO_S_SIZE) + self.alt.to_s
2703
+ return n
2704
+ end
2705
+ private :image_string_creator
2706
+
2707
+ # returns a string representation of the object
2708
+ def to_s
2709
+ assert_exists
2710
+ r = string_creator
2711
+ r=r + image_string_creator
2712
+ return r.join("\n")
2713
+ end
2714
+
2715
+ def_wrap :src
2716
+
2717
+ # this method returns the file created date of the image
2718
+ def fileCreatedDate
2719
+ assert_exists
2720
+ return @o.invoke("fileCreatedDate")
2721
+ end
2722
+
2723
+ # this method returns the filesize of the image
2724
+ def fileSize
2725
+ assert_exists
2726
+ return @o.invoke("fileSize").to_s
2727
+ end
2728
+
2729
+ # returns the width in pixels of the image, as a string
2730
+ def width
2731
+ assert_exists
2732
+ return @o.invoke("width").to_s
2733
+ end
2734
+
2735
+ # returns the alt text of the image
2736
+ def alt
2737
+ assert_exists
2738
+ return @o.invoke("alt").to_s
2739
+ end
2740
+
2741
+
2742
+ # returns the height in pixels of the image, as a string
2743
+ def height
2744
+ assert_exists
2745
+ return @o.invoke("height").to_s
2746
+ end
2747
+
2748
+ # returns the type of the object - 'image'
2749
+ def type
2750
+ assert_exists
2751
+ return "image"
2752
+ end
2753
+
2754
+ # This method attempts to find out if the image was actually loaded by the web browser.
2755
+ # If the image was not loaded, the browser is unable to determine some of the properties.
2756
+ # We look for these missing properties to see if the image is really there or not.
2757
+ # If the Disk cache is full ( tools menu -> Internet options -> Temporary Internet Files) , it may produce incorrect responses.
2758
+ def hasLoaded?
2759
+ raise UnknownObjectException , "Unable to locate image using #{@how} and #{@what} " if @o==nil
2760
+ return false if @o.fileCreatedDate == "" and @o.fileSize.to_i == -1
2761
+ return true
2762
+ end
2763
+
2764
+ # this method highlights the image ( in fact it adds or removes a border around the image)
2765
+ # * setOrClear - symbol - :set to set the border, :clear to remove it
2766
+ def highLight( setOrClear )
2767
+ if setOrClear == :set
2768
+ begin
2769
+ @original_border = @o.border
2770
+ @o.border = 1
2771
+ rescue
2772
+ @original_border = nil
2773
+ end
2774
+ else
2775
+ begin
2776
+ @o.border = @original_border
2777
+ @original_border = nil
2778
+ rescue
2779
+ # we could be here for a number of reasons...
2780
+ ensure
2781
+ @original_border = nil
2782
+ end
2783
+ end
2784
+ end
2785
+ private :highLight
2786
+
2787
+ # This method saves the image to the file path that is given. The
2788
+ # path must be in windows format (c:\\dirname\\somename.gif). This method
2789
+ # will not overwrite a previously existing image. If an image already
2790
+ # exists at the given path then a dialog will be displayed prompting
2791
+ # for overwrite.
2792
+ # Raises a WatirException if AutoIt is not correctly installed
2793
+ # path - directory path and file name of where image should be saved
2794
+ def save(path)
2795
+ require 'watir/windowhelper'
2796
+ WindowHelper.check_autoit_installed
2797
+ @ieController.goto(src)
2798
+ begin
2799
+ thrd = fill_save_image_dialog(path)
2800
+ @ieController.document.execCommand("SaveAs")
2801
+ thrd.join(5)
2802
+ ensure
2803
+ @ieController.back
2804
+ end
2805
+ end
2806
+
2807
+ def fill_save_image_dialog(path)
2808
+ Thread.new do
2809
+ system("ruby -e \"require 'win32ole'; @autoit = WIN32OLE.new('AutoItX3.Control'); waitresult = @autoit.WinWait 'Save Picture', '', 15; if waitresult == 1\" -e \"@autoit.ControlSetText 'Save Picture', '', '1148', '#{path}'; @autoit.ControlSend 'Save Picture', '', '1', '{ENTER}';\" -e \"end\"")
2810
+ end
2811
+ end
2812
+ private :fill_save_image_dialog
2813
+ end
2814
+
2815
+
2816
+ # This class is the means of accessing a link on a page
2817
+ # Normally a user would not need to create this object as it is returned by the Watir::SupportsSubElements#link method
2818
+ # many of the methods available to this object are inherited from the Element class
2819
+ #
2820
+ class Link < Element
2821
+ # Returns an initialized instance of a link object
2822
+ # * ieController - an instance of an IEController
2823
+ # * how - symbol - how we access the link
2824
+ # * what - what we use to access the link, text, url, index etc
2825
+ def initialize( ieController, how , what )
2826
+ @ieController = ieController
2827
+ @how = how
2828
+ @what = what
2829
+ begin
2830
+ @o = @ieController.getLink( @how, @what )
2831
+ rescue UnknownObjectException
2832
+ @o = nil
2833
+ end
2834
+ super( @o )
2835
+ end
2836
+
2837
+ # returns 'link' as the object type
2838
+ def type
2839
+ assert_exists
2840
+ return "link"
2841
+ end
2842
+
2843
+ # returns the text displayed by the link
2844
+ def innerText
2845
+ assert_exists
2846
+ return @o.innerText.strip
2847
+ end
2848
+ alias text innerText
2849
+
2850
+ # returns the url the link points to
2851
+ def_wrap :href
2852
+
2853
+ # if an image is used as part of the link, this will return true
2854
+ def link_has_image
2855
+ return true if @o.getElementsByTagName("IMG").length > 0
2856
+ return false
2857
+ end
2858
+
2859
+ # this method returns the src of an image, if an image is used as part of the link
2860
+ def src
2861
+ if @o.getElementsByTagName("IMG").length > 0
2862
+ return @o.getElementsByTagName("IMG")[0.to_s].src
2863
+ else
2864
+ return ""
2865
+ end
2866
+ end
2867
+
2868
+ def link_string_creator
2869
+ n = []
2870
+ n << "href:".ljust(TO_S_SIZE) + self.href
2871
+ n << "inner text:".ljust(TO_S_SIZE) + self.innerText
2872
+ n << "img src:".ljust(TO_S_SIZE) + self.src if self.link_has_image
2873
+ return n
2874
+ end
2875
+
2876
+ # returns a textual description of the link
2877
+ def to_s
2878
+ assert_exists
2879
+ r = string_creator
2880
+ r=r + link_string_creator
2881
+ return r.join("\n")
2882
+ end
2883
+ end
2884
+
2885
+ # This class is the way in which select boxes are manipulated.
2886
+ # Normally a user would not need to create this object as it is returned by the Watir::SupportsSubElements#select_list method
2887
+ #
2888
+ # many of the methods available to this object are inherited from the Element class
2889
+ #
2890
+ class SelectList < Element
2891
+ # returns an initialized instance of a SelectList object
2892
+ # * ieController - an instance of an IEController
2893
+ # * how - symbol - how we access the select box
2894
+ # * what - what we use to access the select box, name, id etc
2895
+ def initialize( ieController, how , what )
2896
+ @ieController = ieController
2897
+ @how = how
2898
+ @what = what
2899
+ @o = @ieController.getObject(@how, @what, ["select-one", "select-multiple"])
2900
+ super( @o )
2901
+ end
2902
+
2903
+ attr :o
2904
+
2905
+ # This method clears the selected items in the select box
2906
+ def clearSelection
2907
+ assert_exists
2908
+ highLight( :set)
2909
+ wait = false
2910
+ @o.each do |selectBoxItem|
2911
+ if selectBoxItem.selected
2912
+ selectBoxItem.selected = false
2913
+ wait = true
2914
+ end
2915
+ end
2916
+ @ieController.wait if wait
2917
+ highLight( :clear)
2918
+ end
2919
+ # private :clearSelection
2920
+
2921
+ # This method selects an item, or items in a select box, by text.
2922
+ # Raises NoValueFoundException if the specified value is not found.
2923
+ # * item - the thing to select, string, reg exp or an array of string and reg exps
2924
+ def select( item )
2925
+ select_item_in_select_list( :text , item )
2926
+ end
2927
+
2928
+ # Selects an item, or items in a select box, by value.
2929
+ # Raises NoValueFoundException if the specified value is not found.
2930
+ # * item - the value of the thing to select, string, reg exp or an array of string and reg exps
2931
+ def select_value( item )
2932
+ select_item_in_select_list( :value , item )
2933
+ end
2934
+
2935
+ # BUG: Should be private
2936
+ # Selects something from the select box
2937
+ # * name - symbol :value or :text - how we find an item in the select box
2938
+ # * item - string or reg exp - what we are looking for
2939
+ def select_item_in_select_list( attribute, value )
2940
+ assert_exists
2941
+ highLight( :set )
2942
+ doBreak = false
2943
+ @ieController.log "Setting box #{@o.name} to #{attribute} #{value} "
2944
+ @o.each do |option| # items in the list
2945
+ if value.matches( option.invoke(attribute.to_s))
2946
+ if option.selected
2947
+ doBreak = true
2948
+ break
2949
+ else
2950
+ option.selected = true
2951
+ @o.fireEvent("onChange")
2952
+ @ieController.wait
2953
+ doBreak = true
2954
+ break
2955
+ end
2956
+ end
2957
+ end
2958
+ unless doBreak
2959
+ raise NoValueFoundException,
2960
+ "No option with #{attribute.to_s} of #{value} in this select element"
2961
+ end
2962
+ highLight( :clear )
2963
+ end
2964
+
2965
+ # Returns all the items in the select list as an array.
2966
+ # An empty array is returned if the select box has no contents.
2967
+ # Raises UnknownObjectException if the select box is not found
2968
+ def getAllContents()
2969
+ assert_exists
2970
+ @ieController.log "There are #{@o.length} items"
2971
+ returnArray = []
2972
+ @o.each { |thisItem| returnArray << thisItem.text }
2973
+ return returnArray
2974
+ end
2975
+
2976
+ # Returns the selected items as an array.
2977
+ # Raises UnknownObjectException if the select box is not found.
2978
+ def getSelectedItems
2979
+ assert_exists
2980
+ returnArray = []
2981
+ @ieController.log "There are #{@o.length} items"
2982
+ @o.each do |thisItem|
2983
+ if thisItem.selected
2984
+ @ieController.log "Item ( #{thisItem.text} ) is selected"
2985
+ returnArray << thisItem.text
2986
+ end
2987
+ end
2988
+ return returnArray
2989
+ end
2990
+
2991
+ def option (attribute, value)
2992
+ Option.new(self, attribute, value)
2993
+ end
2994
+ end
2995
+
2996
+ module OptionAccess
2997
+ def text
2998
+ @option.text
2999
+ end
3000
+ def value
3001
+ @option.value
3002
+ end
3003
+ def selected
3004
+ @option.selected
3005
+ end
3006
+ end
3007
+
3008
+ class OptionWrapper
3009
+ include OptionAccess
3010
+ def initialize (option)
3011
+ @option = option
3012
+ end
3013
+ end
3014
+
3015
+ # An item in a select list
3016
+ class Option
3017
+ include OptionAccess
3018
+ include Watir::Exception
3019
+ def initialize (select_list, attribute, value)
3020
+ @select_list = select_list
3021
+ @how = attribute
3022
+ @what = value
3023
+ @option = nil
3024
+
3025
+ unless [:text, :value].include? attribute
3026
+ raise MissingWayOfFindingObjectException,
3027
+ "Option does not support attribute #{@how}"
3028
+ end
3029
+ @select_list.o.each do |option| # items in the list
3030
+ if value.matches( option.invoke(attribute.to_s))
3031
+ @option = option
3032
+ break
3033
+ end
3034
+ end
3035
+
3036
+ end
3037
+ def assert_exists
3038
+ unless @option
3039
+ raise UnknownObjectException,
3040
+ "Unable to locate an option using #{@how} and #{@what}"
3041
+ end
3042
+ end
3043
+ private :assert_exists
3044
+ def select
3045
+ assert_exists
3046
+ @select_list.select_item_in_select_list(@how, @what)
3047
+ end
3048
+ end
3049
+
3050
+ # This is the main class for accessing buttons.
3051
+ # Normally a user would not need to create this object as it is returned by the Watir::SupportsSubElements#button method
3052
+ #
3053
+ # most of the methods available to Button objects are inherited from the Element class
3054
+ #
3055
+ class Button < Element
3056
+ def initialize( ieController, how , what )
3057
+ @ieController = ieController
3058
+ @how = how
3059
+ @what = what
3060
+ if(how == :from_object) then
3061
+ @o = what
3062
+ else
3063
+ @o = @ieController.getObject( @how, @what , object_types)
3064
+ end
3065
+ super( @o )
3066
+ end
3067
+
3068
+ def object_types
3069
+ return ["button" , "submit" , "image" , "reset" ]
3070
+ end
3071
+
3072
+ end
3073
+
3074
+
3075
+ # File dialog
3076
+ class FileField < Element
3077
+ # Create an instance of the file object
3078
+ def initialize( ieController, how , what )
3079
+ @ieController = ieController
3080
+ @how = how
3081
+ @what = what
3082
+ super( @o )
3083
+ @o = @ieController.getObject( @how, @what , ["file"] )
3084
+
3085
+ end
3086
+
3087
+ def set(setPath)
3088
+ assert_exists
3089
+ Thread.new {
3090
+ clicker = WinClicker.new
3091
+ clicker.setFileRequesterFileName_newProcess(setPath)
3092
+ }
3093
+ # may need to experiment with this value. if it takes longer than this
3094
+ # to open the new external Ruby process, the current thread may become
3095
+ # blocked by the file chooser.
3096
+ sleep(1)
3097
+ self.click
3098
+ end
3099
+ end
3100
+
3101
+ # This class is the class for radio buttons and check boxes.
3102
+ # It contains methods common to both.
3103
+ # Normally a user would not need to create this object as it is returned by the Watir::SupportsSubElements#checkbox or Watir::SupportsSubElements#radio methods
3104
+ #
3105
+ # most of the methods available to this element are inherited from the Element class
3106
+ #
3107
+ class RadioCheckCommon < Element
3108
+
3109
+ def initialize( ieController, how , what , type, value=nil )
3110
+ @ieController = ieController
3111
+ @how = how
3112
+ @what = what
3113
+ @type = type
3114
+ @value = value
3115
+ @o = @ieController.getObject(@how, @what, @type, @value)
3116
+ super( @o )
3117
+ end
3118
+
3119
+ # This method determines if a radio button or check box is set.
3120
+ # Returns true is set/checked or false if not set/checked.
3121
+ # Raises UnknownObjectException if its unable to locate an object.
3122
+ def isSet?
3123
+ assert_exists
3124
+ return @o.checked
3125
+ end
3126
+ alias getState isSet?
3127
+ alias checked? isSet?
3128
+
3129
+ # This method clears a radio button or check box. Note, with radio buttons one of them will almost always be set.
3130
+ # Returns true if set or false if not set.
3131
+ # Raises UnknownObjectException if its unable to locate an object
3132
+ # ObjectDisabledException IF THE OBJECT IS DISABLED
3133
+ def clear
3134
+ assert_exists
3135
+ assert_enabled
3136
+ highLight( :set)
3137
+ set_clear_item( false )
3138
+ highLight( :clear )
3139
+ end
3140
+
3141
+ # This method sets the radio list item or check box.
3142
+ # Raises UnknownObjectException if its unable to locate an object
3143
+ # ObjectDisabledException if the object is disabled
3144
+ def set
3145
+ assert_exists
3146
+ assert_enabled
3147
+ highLight( :set)
3148
+ set_clear_item( true )
3149
+ highLight( :clear )
3150
+ end
3151
+
3152
+ # This method is the common code for setting or clearing checkboxes and radio. A user would normalyy not access this, but use Checkbox#set etc
3153
+ def set_clear_item( set )
3154
+ @o.checked = set
3155
+ @o.fireEvent("onClick")
3156
+ @ieController.wait
3157
+ end
3158
+ private :set_clear_item
3159
+
3160
+ end
3161
+
3162
+ #--
3163
+ # this class is only used to change the name of the class that radio buttons use to something more meaningful
3164
+ # and to make the docs better
3165
+ #++
3166
+ # This class is the watir representation of a radio button.
3167
+ class Radio < RadioCheckCommon
3168
+
3169
+ end
3170
+
3171
+
3172
+ # This class is the watir representation of a check box.
3173
+ class CheckBox < RadioCheckCommon
3174
+
3175
+ # This method, with no arguments supplied, sets the check box.
3176
+ # If the optional set_or_clear is supplied, the checkbox is set, when its true and cleared when its false
3177
+ # Raises UnknownObjectException if its unable to locate an object
3178
+ # ObjectDisabledException if the object is disabled
3179
+ def set( set_or_clear=true )
3180
+ assert_exists
3181
+ assert_enabled
3182
+ highLight( :set)
3183
+
3184
+ if set_or_clear == true
3185
+ if @o.checked == false
3186
+ set_clear_item( true )
3187
+ end
3188
+ else
3189
+ self.clear
3190
+ end
3191
+ highLight( :clear )
3192
+ end
3193
+
3194
+ # This method clears a check box.
3195
+ # Returns true if set or false if not set.
3196
+ # Raises UnknownObjectException if its unable to locate an object
3197
+ # ObjectDisabledException if the object is disabled
3198
+ def clear
3199
+ assert_exists
3200
+ assert_enabled
3201
+ highLight( :set)
3202
+ if @o.checked == true
3203
+ set_clear_item( false )
3204
+ end
3205
+ highLight( :clear)
3206
+ end
3207
+
3208
+
3209
+ end
3210
+
3211
+
3212
+ # This class is the main class for Text Fields
3213
+ # Normally a user would not need to create this object as it is returned by the Watir::SupportsSubElements#text_field method
3214
+ #
3215
+ # most of the methods available to this element are inherited from the Element class
3216
+ #
3217
+ class TextField < Element
3218
+
3219
+ def initialize( ieController, how , what )
3220
+ @ieController = ieController
3221
+ @how = how
3222
+ @what = what
3223
+
3224
+ if(how != :from_object) then
3225
+ @o = @ieController.getObject(@how, @what, supported_types)
3226
+ else
3227
+ @o = what
3228
+ end
3229
+ super( @o )
3230
+ end
3231
+
3232
+ def supported_types
3233
+ return ["text" , "password", "textarea"]
3234
+ end
3235
+ private :supported_types
3236
+
3237
+ def size
3238
+ assert_exists
3239
+ begin
3240
+ s=@o.size
3241
+ rescue
3242
+ # TextArea does not support size
3243
+ s=""
3244
+ end
3245
+ return s
3246
+
3247
+ end
3248
+
3249
+ def maxLength
3250
+ assert_exists
3251
+ begin
3252
+ s=@o.maxlength
3253
+ rescue
3254
+ # TextArea does not support maxLength
3255
+ s=""
3256
+ end
3257
+ return s
3258
+ end
3259
+
3260
+ def text_string_creator
3261
+ n = []
3262
+ n << "length:".ljust(TO_S_SIZE) + self.size.to_s
3263
+ n << "max length:".ljust(TO_S_SIZE) + self.maxLength.to_s
3264
+ n << "read only:".ljust(TO_S_SIZE) + self.readonly?.to_s
3265
+
3266
+ return n
3267
+ end
3268
+
3269
+ def to_s
3270
+ assert_exists
3271
+ r = string_creator
3272
+ r=r + text_string_creator
3273
+ return r.join("\n")
3274
+ end
3275
+
3276
+ # This method returns true or false if the text field is read only.
3277
+ # Raises UnknownObjectException if the object can't be found.
3278
+ def readonly?
3279
+ assert_exists
3280
+ return @o.readOnly
3281
+ end
3282
+ alias readOnly? :readonly?
3283
+
3284
+ def assert_not_readonly
3285
+ raise ObjectReadOnlyException , "Textfield #{@how} and #{@what} is read only" if self.readonly?
3286
+ end
3287
+ #--
3288
+ # BUG: rename me
3289
+ #++
3290
+ # This method returns the current contents of the text field as a string.
3291
+ # Raises UnknownObjectException if the object can't be found
3292
+ def getContents()
3293
+ assert_exists
3294
+ return self.value
3295
+ end
3296
+
3297
+ # This method returns true orfalse if the text field contents is either a string match
3298
+ # or a regular expression match to the supplied value.
3299
+ # Raises UnknownObjectException if the object can't be found
3300
+ # * containsThis - string or reg exp - the text to verify
3301
+ def verify_contains( containsThis )
3302
+ assert_exists
3303
+ if containsThis.kind_of? String
3304
+ return true if self.value == containsThis
3305
+ elsif containsThis.kind_of? Regexp
3306
+ return true if self.value.match(containsThis) != nil
3307
+ end
3308
+ return false
3309
+ end
3310
+
3311
+ # this method is used to drag the entire contents of the text field to another text field
3312
+ # 19 Jan 2005 - It is added as prototype functionality, and may change
3313
+ # * destination_how - symbol, :id, :name how we identify the drop target
3314
+ # * destination_what - string or regular expression, the name, id, etc of the text field that will be the drop target
3315
+ def dragContentsTo( destination_how , destination_what)
3316
+ assert_exists
3317
+ destination = @ieController.textField(destination_how , destination_what)
3318
+
3319
+ raise UnknownObjectException , "Unable to locate destination using #{destination_how } and #{destination_what } " if destination.exists? == false
3320
+
3321
+ @o.focus
3322
+ @o.select()
3323
+ value = self.value
3324
+
3325
+ @o.fireEvent("onSelect")
3326
+ @o.fireEvent("ondragstart")
3327
+ @o.fireEvent("ondrag")
3328
+ destination.fireEvent("onDragEnter")
3329
+ destination.fireEvent("onDragOver")
3330
+ destination.fireEvent("ondrop")
3331
+
3332
+ @o.fireEvent("ondragend")
3333
+ destination.value= ( destination.value + value.to_s )
3334
+ self.value = ""
3335
+ end
3336
+
3337
+ # This method clears the contents of the text box.
3338
+ # Raises UnknownObjectException if the object can't be found
3339
+ # Raises ObjectDisabledException if the object is disabled
3340
+ # Raises ObjectReadOnlyException if the object is read only
3341
+ def clear
3342
+ assert_exists
3343
+ assert_enabled
3344
+ assert_not_readonly
3345
+
3346
+ highLight(:set)
3347
+
3348
+ @o.scrollIntoView
3349
+ @o.focus
3350
+ @o.select()
3351
+ @o.fireEvent("onSelect")
3352
+ @o.value = ""
3353
+ @o.fireEvent("onKeyPress")
3354
+ @o.fireEvent("onChange")
3355
+ @ieController.wait()
3356
+ highLight(:clear)
3357
+ end
3358
+
3359
+ # This method appens the supplied text to the contents of the text box.
3360
+ # Raises UnknownObjectException if the object cant be found
3361
+ # Raises ObjectDisabledException if the object is disabled
3362
+ # Raises ObjectReadOnlyException if the object is read only
3363
+ # * setThis - string - the text to append
3364
+ def append( setThis)
3365
+ assert_exists
3366
+ assert_enabled
3367
+ assert_not_readonly
3368
+
3369
+ highLight(:set)
3370
+ @o.scrollIntoView
3371
+ @o.focus
3372
+ doKeyPress( setThis )
3373
+ highLight(:clear)
3374
+ end
3375
+
3376
+ # This method sets the contents of the text box to the supplied text
3377
+ # Raises UnknownObjectException if the object cant be found
3378
+ # Raises ObjectDisabledException if the object is disabled
3379
+ # Raises ObjectReadOnlyException if the object is read only
3380
+ # * setThis - string - the text to set
3381
+ def set( setThis )
3382
+ assert_exists
3383
+ assert_enabled
3384
+ assert_not_readonly
3385
+
3386
+ highLight(:set)
3387
+ @o.scrollIntoView
3388
+ @o.focus
3389
+ @o.select()
3390
+ @o.fireEvent("onSelect")
3391
+ @o.value = ""
3392
+ @o.fireEvent("onKeyPress")
3393
+ doKeyPress( setThis )
3394
+ highLight(:clear)
3395
+ @o.fireEvent("onChange")
3396
+ @o.fireEvent("onBlur")
3397
+ end
3398
+
3399
+ # this method sets the value of the text field directly. It causes no events to be fired or exceptions to be raised, so generally shouldnt be used
3400
+ # it is preffered to use the set method.
3401
+ def value=(v)
3402
+ assert_exists
3403
+ @o.value = v.to_s
3404
+ end
3405
+
3406
+ def fire_key_events
3407
+ @o.fireEvent("onKeyDown")
3408
+ @o.fireEvent("onKeyPress")
3409
+ @o.fireEvent("onKeyUp")
3410
+ end
3411
+ private :fire_key_events
3412
+
3413
+ # This method is used internally by setText and appendText
3414
+ # It should not be used externally.
3415
+ # * value - string - The string to enter into the text field
3416
+ def doKeyPress( value )
3417
+ begin
3418
+ maxLength = @o.maxLength
3419
+ if value.length > maxLength
3420
+ value = suppliedValue[0 .. maxLength ]
3421
+ @ieController.log " Supplied string is #{suppliedValue.length} chars, which exceeds the max length (#{maxLength}) of the field. Using value: #{value}"
3422
+ end
3423
+ rescue
3424
+ # probably a text area - so it doesnt have a max Length
3425
+ maxLength = -1
3426
+ end
3427
+ for i in 0 .. value.length-1
3428
+ sleep @ieController.typingspeed # typing speed
3429
+ c = value[i,1]
3430
+ #@ieController.log " adding c.chr " + c #.chr.to_s
3431
+ @o.value = @o.value.to_s + c #c.chr
3432
+ fire_key_events
3433
+ end
3434
+
3435
+ end
3436
+ private :doKeyPress
3437
+ end
3438
+
3439
+ # this class can be used to access hidden field objects
3440
+ # Normally a user would not need to create this object as it is returned by the Watir::SupportsSubElements#hidden method
3441
+ #
3442
+ # most of the methods available to this element are inherited from the Element class
3443
+ #
3444
+ class Hidden < TextField
3445
+
3446
+ def initialize( ieController, how , what )
3447
+ super
3448
+ end
3449
+
3450
+ def supported_types
3451
+ return ["hidden"]
3452
+ end
3453
+
3454
+
3455
+ # set is overriden in this class, as there is no way to set focus to a hidden field
3456
+ def set(n)
3457
+ self.value=n
3458
+ end
3459
+
3460
+ # override the append method, so that focus isnt set to the hidden object
3461
+ def append(n)
3462
+ self.value = self.value.to_s + n.to_s
3463
+ end
3464
+
3465
+ # override the clear method, so that focus isnt set to the hidden object
3466
+ def clear
3467
+ self.value = ""
3468
+ end
3469
+
3470
+ # this method will do nothing, as you cant set focus to a hidden field
3471
+ def focus
3472
+ # do nothing!
3473
+ end
3474
+
3475
+ end
3476
+
3477
+ #--
3478
+ # These classes are not for public consumption, so we switch off rdoc
3479
+
3480
+
3481
+ # presumes element_class or element_tag is defined
3482
+ # for subclasses of ElementCollections
3483
+ module CommonCollection
3484
+ def element_tag
3485
+ element_class.tag
3486
+ end
3487
+ def length
3488
+ @ieController.getContainer.getElementsByTagName(element_tag).length
3489
+ end
3490
+ end
3491
+
3492
+ # This class is used as part of the .show method of the iterators class
3493
+ # it would not normally be used by a user
3494
+ class AttributeLengthPairs
3495
+
3496
+ # This class is used as part of the .show method of the iterators class
3497
+ # it would not normally be used by a user
3498
+ class AttributeLengthHolder
3499
+ attr_accessor :attribute
3500
+ attr_accessor :length
3501
+
3502
+ def initialize( attrib, length)
3503
+ @attribute = attrib
3504
+ @length = length
3505
+ end
3506
+ end
3507
+
3508
+ def initialize( attrib=nil , length=nil)
3509
+ @attr=[]
3510
+ add( attrib , length ) if attrib
3511
+ @index_counter=0
3512
+ end
3513
+
3514
+ # BUG: Untested. (Null implementation passes all tests.)
3515
+ def add( attrib , length)
3516
+ @attr << AttributeLengthHolder.new( attrib , length )
3517
+ end
3518
+
3519
+ def delete(attrib)
3520
+ item_to_delete=nil
3521
+ @attr.each_with_index do |e,i|
3522
+ item_to_delete = i if e.attribute==attrib
3523
+ end
3524
+ @attr.delete_at(item_to_delete ) unless item_to_delete == nil
3525
+ end
3526
+
3527
+ def next
3528
+ temp = @attr[@index_counter]
3529
+ @index_counter +=1
3530
+ return temp
3531
+ end
3532
+
3533
+ def each
3534
+ 0.upto( @attr.length-1 ) { |i | yield @attr[i] }
3535
+ end
3536
+ end
3537
+
3538
+ # resume rdoc
3539
+ #++
3540
+
3541
+
3542
+ # this class accesses the buttons in the document as a collection
3543
+ # it would normally only be accessed by the Watir::SupportsSubElements#buttons method
3544
+ #
3545
+ class Buttons < ElementCollections
3546
+ def element_class; Button; end
3547
+ def length
3548
+ get_length_of_input_objects(["button", "submit", "image"])
3549
+ end
3550
+
3551
+ def set_show_items
3552
+ super
3553
+ @show_attributes.add( "disabled" , 9)
3554
+ @show_attributes.add( "value" , 20)
3555
+ end
3556
+ end
3557
+
3558
+
3559
+ # this class accesses the file fields in the document as a collection
3560
+ # it would normally only be accessed by the Watir::SupportsSubElements#file_fields method
3561
+ #
3562
+ class FileFields< ElementCollections
3563
+ def element_class; FileField; end
3564
+ def length
3565
+ get_length_of_input_objects(["file"])
3566
+ end
3567
+
3568
+ def set_show_items
3569
+ super
3570
+ @show_attributes.add( "disabled" , 9)
3571
+ @show_attributes.add( "value" , 20)
3572
+ end
3573
+ end
3574
+
3575
+
3576
+ # this class accesses the check boxes in the document as a collection
3577
+ # Normally a user would not need to create this object as it is returned by the Watir::SupportsSubElements#checkboxes method
3578
+ #
3579
+ class CheckBoxes < ElementCollections
3580
+ def element_class; CheckBox; end
3581
+ def length
3582
+ get_length_of_input_objects("checkbox")
3583
+ end
3584
+ # this method creates an object of the correct type that the iterators use
3585
+ private
3586
+ def iterator_object(i)
3587
+ @ieController.checkbox(:index, i+1)
3588
+ end
3589
+ end
3590
+
3591
+ # this class accesses the radio buttons in the document as a collection
3592
+ # Normally a user would not need to create this object as it is returned by the Watir::SupportsSubElements#radios method
3593
+ #
3594
+ class Radios < ElementCollections
3595
+ def element_class; Radio; end
3596
+ def length
3597
+ get_length_of_input_objects("radio")
3598
+ end
3599
+ # this method creates an object of the correct type that the iterators use
3600
+ private
3601
+ def iterator_object(i)
3602
+ @ieController.radio(:index, i+1)
3603
+ end
3604
+ end
3605
+
3606
+ # this class accesses the select boxes in the document as a collection
3607
+ # Normally a user would not need to create this object as it is returned by the Watir::SupportsSubElements#select_lists method
3608
+ #
3609
+ class SelectLists < ElementCollections
3610
+ include CommonCollection
3611
+ def element_class; SelectList; end
3612
+ def element_tag; 'SELECT'; end
3613
+ end
3614
+
3615
+ # this class accesses the links in the document as a collection
3616
+ # Normally a user would not need to create this object as it is returned by the Watir::SupportsSubElements#links method
3617
+ #
3618
+ class Links < ElementCollections
3619
+ include CommonCollection
3620
+ def element_class; Link; end
3621
+ def element_tag; 'A'; end
3622
+
3623
+ def set_show_items
3624
+ super
3625
+ @show_attributes.add("href", 60)
3626
+ @show_attributes.add("innerText" , 60)
3627
+ end
3628
+
3629
+ end
3630
+
3631
+ # this class accesses the imnages in the document as a collection
3632
+ # Normally a user would not need to create this object as it is returned by the Watir::SupportsSubElements#images method
3633
+ #
3634
+ class Images < ElementCollections
3635
+ def element_class; Image; end
3636
+ def length
3637
+ @ieController.document.images.length
3638
+ end
3639
+
3640
+ def set_show_items
3641
+ super
3642
+ @show_attributes.add("src", 60)
3643
+ @show_attributes.add("alt", 30)
3644
+ end
3645
+
3646
+ end
3647
+
3648
+ # this class accesses the text fields in the document as a collection
3649
+ # Normally a user would not need to create this object as it is returned by the Watir::SupportsSubElements#text_fields method
3650
+ #
3651
+ class TextFields < ElementCollections
3652
+ def element_class; TextField; end
3653
+ def length
3654
+ # text areas are also included inthe Text_filds, but we need to get them seperately
3655
+ get_length_of_input_objects( ["text" , "password"] ) +
3656
+ @ieController.ie.document.body.getElementsByTagName("textarea").length
3657
+ end
3658
+ end
3659
+
3660
+ # this class accesses the hidden fields in the document as a collection
3661
+ # Normally a user would not need to create this object as it is returned by the Watir::SupportsSubElements#hiddens method
3662
+ class Hiddens < ElementCollections
3663
+ def element_class; Hidden; end
3664
+ def length
3665
+ get_length_of_input_objects("hidden")
3666
+ end
3667
+ end
3668
+
3669
+ # this class accesses the text fields in the document as a collection
3670
+ # Normally a user would not need to create this object as it is returned by the Watir::SupportsSubElements#tables method
3671
+ #
3672
+ class Tables < ElementCollections
3673
+ include CommonCollection
3674
+ def element_class; Table; end
3675
+ def element_tag; 'TABLE'; end
3676
+
3677
+ def set_show_items
3678
+ super
3679
+ @show_attributes.delete( "name")
3680
+ end
3681
+ end
3682
+
3683
+ # this class accesses the labels in the document as a collection
3684
+ # Normally a user would not need to create this object as it is returned by the Watir::SupportsSubElements#labels method
3685
+ #
3686
+ class Labels < ElementCollections
3687
+ include CommonCollection
3688
+ def element_class; Label; end
3689
+ def element_tag; 'LABEL'; end
3690
+
3691
+ def set_show_items
3692
+ super
3693
+ @show_attributes.add("htmlFor", 20)
3694
+ end
3695
+ end
3696
+
3697
+ # this class accesses the p tags in the document as a collection
3698
+ # Normally a user would not need to create this object as it is returned by the Watir::SupportsSubElements#ps method
3699
+ #
3700
+ class Ps < ElementCollections
3701
+ include CommonCollection
3702
+ def element_class; P; end
3703
+
3704
+ def set_show_items
3705
+ super
3706
+ @show_attributes.delete( "name")
3707
+ @show_attributes.add( "className" , 20)
3708
+ end
3709
+
3710
+ end
3711
+
3712
+ # this class accesses the spans in the document as a collection
3713
+ # Normally a user would not need to create this object as it is returned by the Watir::SupportsSubElements#spans method
3714
+ #
3715
+ class Spans < ElementCollections
3716
+ include CommonCollection
3717
+ def element_class; Span; end
3718
+
3719
+ def set_show_items
3720
+ super
3721
+ @show_attributes.delete( "name")
3722
+ @show_attributes.add( "className" , 20)
3723
+ end
3724
+
3725
+ end
3726
+
3727
+ # this class accesses the divs in the document as a collection
3728
+ # Normally a user would not need to create this object as it is returned by the Watir::SupportsSubElements#divs method
3729
+ #
3730
+ class Divs < ElementCollections
3731
+ include CommonCollection
3732
+ def element_class; Div; end
3733
+
3734
+ def set_show_items
3735
+ super
3736
+ @show_attributes.delete( "name")
3737
+ @show_attributes.add( "className" , 20)
3738
+ end
3739
+
3740
+ end
3741
+
3742
+ end
3743
+
3744
+ require 'watir/camel_case'