rwebunit 0.7.2 → 0.8.9

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,9 +1,41 @@
1
1
  CHANGELOG
2
2
  =========
3
+ == 0.8.9
4
+ - support Watir 1.5.4 zippy mode, set it as default
3
5
 
6
+ == 0.8.8
7
+ - support iTest hiding browse option
8
+
9
+ == 0.8.7
10
+ - support delay between operations (must be click_... type operation) for iTest2
11
+
12
+ == 0.8.6
13
+ - Add dependency on activesupport 2.0.x, xml_simple to support 1.days.ago
14
+ - RSpec Helper, overwrite rspec patch
15
+
16
+ == 0.8.5
17
+ - click button with image
18
+ - better handling new pop up window
19
+ - fixes links_with_text
20
+
21
+ == 0.8.4
22
+ - better support for iTest
23
+ - for firefox support, don't do slow typing, just set text in textfield
24
+
25
+ == 0.8.2
26
+ - fixed assert_link_not_present has .Text
27
+
28
+ == 0.8.1
29
+ - fixed attach_browser issue
30
+
31
+ == 0.8 (2008-01-18)
32
+ - change click_link to click_link_with_text, to for id click, use click_link_with_id
33
+ - change click_button to click_button_with_text, to for id click, use click_button_with_id
34
+
4
35
  == 0.7.2 (2007-12-31)
5
36
  - Change dependency from Watir => Watir or FireWatir
6
37
  Now can run on Mac or Linux
38
+ - Fixes: shall_not_allow syntax error
7
39
 
8
40
  == 0.7.1 (2007-12-24)
9
41
  - Fixes error when firefox is not available
@@ -41,7 +73,7 @@ CHANGELOG
41
73
  - add method contains_text
42
74
  - make faster checkbox operations
43
75
  - make faster radio operations
44
- - added radio opration in driver.rb
76
+ - added radio operation in driver.rb
45
77
  - renamed ajax_wait_for_element
46
78
  - added some comments
47
79
 
data/Rakefile CHANGED
@@ -6,7 +6,7 @@ Gem::manage_gems
6
6
  require 'rake/gempackagetask'
7
7
 
8
8
  $:.unshift(File.dirname(__FILE__) + "/lib")
9
- require 'rwebunit'
9
+ #require 'rwebunit'
10
10
 
11
11
  desc "Default task"
12
12
  task :default => [ :clean, :test, :doc, :gem]
@@ -36,12 +36,12 @@ Rake::RDocTask.new { |rdoc|
36
36
  spec = Gem::Specification.new do |s|
37
37
  s.platform= Gem::Platform::RUBY
38
38
  s.name = "rwebunit"
39
- s.version = "0.7.2"
39
+ s.version = "0.8.9"
40
40
  s.summary = "An wrap of WATIR/FireWatir for functional testing of web applications"
41
41
  # s.description = ""
42
42
 
43
43
  s.author = "Zhimin Zhan"
44
- s.email = "zhimin@zhimin.com"
44
+ s.email = "zhimin@agileway.net"
45
45
  s.homepage= "http://code.google.com/p/rwebunit/"
46
46
  # s.rubyforge_project = ""
47
47
 
@@ -3,11 +3,21 @@
3
3
  #* Distributed open-source, see full license in MIT-LICENSE
4
4
  #***********************************************************
5
5
 
6
+ # Load active_support, so that we can use 1.days.ago
7
+ begin
8
+ require 'active_support/basic_object'
9
+ require 'active_support/duration'
10
+ rescue LoadError => no_as1_err
11
+ # active_support 2.0 loaded error
12
+ end
13
+ require 'active_support/core_ext'
14
+
6
15
  # Extra full path to load libraries
7
16
  require File.dirname(__FILE__) + "/rwebunit/test_utils"
8
17
  require File.dirname(__FILE__) + "/rwebunit/web_page"
9
18
  require File.dirname(__FILE__) + "/rwebunit/assert"
10
- require File.dirname(__FILE__) + "/rwebunit/web_testcase"
19
+ #This cause some unit test loaded, to use it, load specifiically
20
+ #require File.dirname(__FILE__) + "/rwebunit/web_testcase"
11
21
  require File.dirname(__FILE__) + "/rwebunit/web_tester"
12
22
  require File.dirname(__FILE__) + "/rwebunit/test_context"
13
23
  require File.dirname(__FILE__) + "/rwebunit/driver"
@@ -212,7 +212,7 @@ module RWebUnit
212
212
 
213
213
  def assert_link_not_present_with_text(linkText)
214
214
  @web_tester.links.each { |link|
215
- assert(!link.Text.include?(linkText), "unexpected link containing: #{linkText} found")
215
+ assert(!link.text.include?(linkText), "unexpected link containing: #{linkText} found")
216
216
  }
217
217
  end
218
218
 
@@ -1,296 +1,424 @@
1
- # The Mixin is normally included in the spec/tests and pages, provide
2
- # convenient methods to drive the browser.
3
- #
4
- # Instead of
5
- # browser.click_button("submit")
6
- # You can just use
7
- # click_button("submit")
8
- #
9
-
10
- module RWebUnit
11
- module Driver
12
-
13
- # Verify the next page following an operation.
14
- #
15
- # Typical usage:
16
- # login_page.click_login
17
- # expect_page HomePage
18
- def expect_page(page_clazz)
19
- page_clazz.new(@web_tester)
20
- end
21
-
22
- # Using Ruby block syntax to create interesting domain specific language,
23
- # may be appeal to someone.
24
-
25
- # Example:
26
- # on @page do |i|
27
- # i.enter_text('btn1')
28
- # i.click_button('btn1')
29
- # end
30
- def on(page, &block)
31
- yield page
32
- end
33
-
34
- def test_context
35
- @web_tester.test_context
36
- end
37
-
38
- def begin_at(url)
39
- @web_tester.begin_at(url)
40
- end
41
-
42
- def ie; @web_tester.ie; end
43
-
44
- def close_browser
45
- @web_tester.close_browser
46
- end
47
- alias close_ie close_browser
48
-
49
- # browser navigation
50
- def go_back; @web_tester.go_back; end
51
- def go_forward; @web_tester.go_forward; end
52
- def goto_page(page); @web_tester.goto_page(page); end
53
- def refresh; @web_tester.refresh; end
54
- alias refresh_page refresh
55
-
56
- def attach_browser(how, what); WebTester.attach_browser(how, what); end
57
-
58
- ##
59
- # Delegate to WebTester
60
- #
61
-
62
- # Depends on which object type, you can use following attribute
63
- # More details: http://wiki.openqa.org/display/WTR/Methods+supported+by+Element
64
- #
65
- # :id Used to find an element that has an "id=" attribute. Since each id should be unique, according to the XHTML specification, this is recommended as the most reliable method to find an object. *
66
- # :name Used to find an element that has a "name=" attribute. This is useful for older versions of HTML, but "name" is deprecated in XHTML. *
67
- # :value Used to find a text field with a given default value, or a button with a given caption, or a text field
68
- # :text Used for links, spans, divs and other element that contain text.
69
- # :index Used to find the nth element of the specified type on a page. For example, button(:index, 2) finds the second button. Current versions of WATIR use 1-based indexing, but future versions will use 0-based indexing.
70
- # :class Used for an element that has a "class=" attribute.
71
- # :title Used for an element that has a "title=" attribute.
72
- # :xpath Finds the item using xpath query.
73
- # :method Used only for forms, the method attribute of a form is either GET or POST.
74
- # :action Used only for form elements, specifies the URL where the form is to be submitted.
75
- # :href Used to identify a link by its "href=" attribute.
76
- # :src Used to identify an image by its URL.
77
- #
78
-
79
- # area <area> tags
80
- # button <input> tags with type=button, submit, image or reset
81
- # check_box <input> tags with type=checkbox
82
- # div <div> tags
83
- # form <form> tags
84
- # frame frames, including both the <frame> elements and the corresponding pages
85
- # h1 - h6 <h1>, <h2>, <h3>, <h4>, <h5>, <h6> tags
86
- # hidden <input> tags with type=hidden
87
- # image <img> tags
88
- # label <label> tags (including "for" attribute)
89
- # li <li> tags
90
- # link <a> (anchor) tags
91
- # map <map> tags
92
- # radio <input> tags with the type=radio; known as radio buttons
93
- # select_list <select> tags, known as drop-downs or drop-down lists
94
- # span <span> tags
95
- # table <table> tags, including row and cell methods for accessing nested elements
96
- # text_field <input> tags with the type=text (single-line), type=textarea (multi-line), and type=password
97
- # p <p> (paragraph) tags, because
98
- def area(*args); @web_tester.area(*args); end
99
- def button(*args); @web_tester.button(*args); end
100
- def cell(*args); @web_tester.cell(*args); end
101
- alias td cell
102
- def checkbox(*args); @web_tester.checkbox(*args); end
103
- alias check_box checkbox # seems watir doc is wrong, checkbox not check_box
104
- def div(*args); @web_tester.div(*args); end
105
- def form(*args); @web_tester.form(*args); end
106
- def frame(*args); @web_tester.frame(*args); end
107
- def h1(*args); @web_tester.h1(*args); end
108
- def h2(*args); @web_tester.h2(*args); end
109
- def h3(*args); @web_tester.h3(*args); end
110
- def h4(*args); @web_tester.h4(*args); end
111
- def h5(*args); @web_tester.h5(*args); end
112
- def h6(*args); @web_tester.h6(*args); end
113
- def hidden(*args); @web_tester.hidden(*args); end
114
- def image(*args); @web_tester.image(*args); end
115
- def li(*args); @web_tester.li(*args); end
116
- def link(*args); @web_tester.link(*args); end
117
- def map(*args); @web_tester.map(*args); end
118
- def pre(*args); @web_tester.pre(*args); end
119
- def row(*args); @web_tester.row(*args); end
120
- alias tr row
121
- def radio(*args); @web_tester.radio(*args); end
122
- def select_list(*args); @web_tester.select_list(*args); end
123
- def span(*args); @web_tester.span(*args); end
124
- def table(*args); @web_tester.table(*args); end
125
- def text_field(*args); @web_tester.text_field(*args); end
126
-
127
- def paragraph(*args); @web_tester.paragraph(*args); end
128
- def file_field(*args); @web_tester.file_field(*args); end
129
- def label(*args); @web_tester.span(*args); end
130
-
131
- def contains_text(text); @web_tester.contains_text(text); end
132
-
133
-
134
- def links; @web_tester.links; end
135
- def buttons; @web_tester.buttons; end
136
- def select_lists; @web_tester.select_lists; end
137
- def checkboxes; @web_tester.checkboxes; end
138
- def radios; @web_tester.radios; end
139
- def text_fields; @web_tester.text_fields; end
140
-
141
-
142
- # enter text into a text field
143
- def enter_text(elementName, elementValue)
144
- @web_tester.set_form_element(elementName, elementValue)
145
- end
146
- alias set_form_element enter_text
147
-
148
-
149
- #links
150
- def click_link_with_text(linkText)
151
- @web_tester.click_link_with_text(linkText)
152
- end
153
-
154
- def click_link_with_id(link_id)
155
- @web_tester.click_link_with_id(link_id)
156
- end
157
- alias click_link click_link_with_id
158
-
159
- ##
160
- # buttons
161
-
162
- # submit the form using the first (index) submit button
163
- def submit()
164
- @web_tester.submit()
165
- end
166
-
167
- # click a form submit button with specified button id
168
- def submit(button_id)
169
- @web_tester.submit(button_id)
170
- end
171
-
172
- def click_button(button_id)
173
- @web_tester.click_button(button_id)
174
- end
175
- alias click_button_with_id click_button
176
-
177
- def click_button_with_caption(caption)
178
- @web_tester.click_button_with_caption(caption)
179
- end
180
- alias click_button_with_text click_button_with_caption
181
-
182
- def click_button_with_value(value)
183
- @web_tester.click_button_with_value(value)
184
- end
185
-
186
- # Radios
187
- def click_radio_option(name, value)
188
- @web_tester.click_radio_option(name, value)
189
- end
190
- alias click_radio_button click_radio_option
191
-
192
- def clear_radio_option(name, value)
193
- @web_tester.clear_radio_option(name, value)
194
- end
195
- alias clear_radio_button clear_radio_option
196
-
197
- # Filefield
198
- def select_file_for_upload(file_field, file_path)
199
- @web_tester.select_file_for_upload(file_field, file_path)
200
- end
201
-
202
- # Check one or more checkboxes with same name, can accept a string or an array of string as values checkbox, pass array as values will try to set mulitple checkboxes.
203
- #
204
- # page.check_checkbox('bad_ones', 'Chicken Little')
205
- # page.check_checkbox('good_ones', ['Cars', 'Toy Story'])
206
- def check_checkbox(name, value=nil)
207
- @web_tester.check_checkbox(name, value)
208
- end
209
-
210
- # Uncheck one or more checkboxes with same name
211
- def uncheck_checkbox(name, value=nil)
212
- @web_tester.uncheck_checkbox(name, value)
213
- end
214
-
215
- # combo box
216
- def select_option(selectName, option)
217
- @web_tester.select_option(selectName, option)
218
- end
219
-
220
- def new_popup_window(options)
221
- @web_tester.new_popup_window(options)
222
- end
223
-
224
-
225
- # Wait for specific seconds for an Ajax update finish.
226
- # Trick: In your Rails application,
227
- # :loading => "Element.show('search_indicator');
228
- # :complete => "Element.hide('search_indicator');
229
- #
230
- # <%= image_tag("indicator.gif", :id => 'search_indicator', :style => 'display:none') %>
231
- #
232
- # Typical usage:
233
- # ajax_wait_for_element("search_indicator", 30)
234
- # ajax_wait_for_element("search_indicator", 30, "show")
235
- # ajax_wait_for_element("search_indicator", 30, "hide")
236
- # ajax_wait_for_element("search_indicator", 30, "show", 5) # check every 5 seconds
237
- #
238
- # Warning: this method has not been fully tested, if you are not using Rails, change your parameter accordingly.
239
- #
240
- def ajax_wait_for_element(element_id, seconds, status='show', check_interval=2)
241
- count = 0
242
- check_interval = 2 if check_interval < 1 or check_interval > seconds
243
- while count < (seconds / check_interval) do
244
- search_indicator = @web_tester.element_by_id(element_id)
245
- search_indicator_outer_html = search_indicator.outerHtml if search_indicator
246
- if status == 'hide'
247
- return true if search_indicator_outer_html and !search_indicator_outer_html.include?('style="DISPLAY: none"')
248
- else
249
- return true if search_indicator_outer_html and search_indicator_outer_html.include?('style="DISPLAY: none"')
250
- end
251
- sleep check_interval if check_interval > 0 and check_interval < 5 * 60 # wait max 5 minutes
252
- count += 1
253
- end
254
- return false
255
- end
256
-
257
- def wait_for_element(element_id, timeout = 30, interval = 0.5)
258
- start_time = Time.now
259
- until @web_tester.element_by_id(element_id) do
260
- sleep(interval)
261
- if (Time.now - start_time) > timeout
262
- raise RuntimeError, "failed to find element: #{element_id} for max #{timeout}"
263
- end
264
- end
265
- end
266
-
267
- def element_text(elem_id)
268
- @web_tester.element_value(elem_id)
269
- end
270
-
271
- # fail the test if user can perform the operation
272
- def shall_not_allow
273
- operation_performed_ok = false
274
- begin
275
- yield
276
- operation_performed_ok = true
277
- rescue
278
- end
279
-
280
- raise "Operation shall not be allowed" if operation_performed_ok
281
- end
282
- alias do_not_allow shall_not_allow
283
-
284
- # ---
285
- # For debugging
286
- # ---
287
- def dump_response(stream = nil)
288
- @web_tester.dump_response(stream)
289
- end
290
-
291
- def click_popup_window(button, waitTime= 9, user_input=nil )
292
- @web_tester.start_clicker(button, waitTime, user_input)
293
- end
294
-
295
- end
296
- end
1
+ # The Mixin is normally included in the spec/tests and pages, provide
2
+ # convenient methods to drive the browser.
3
+ #
4
+ # Instead of
5
+ # browser.click_button("submit")
6
+ # You can just use
7
+ # click_button("submit")
8
+ #
9
+
10
+ module RWebUnit
11
+ module Driver
12
+
13
+ # Verify the next page following an operation.
14
+ #
15
+ # Typical usage:
16
+ # login_page.click_login
17
+ # expect_page HomePage
18
+ def expect_page(page_clazz)
19
+ page_clazz.new(@web_tester)
20
+ end
21
+
22
+ # Using Ruby block syntax to create interesting domain specific language,
23
+ # may be appeal to someone.
24
+
25
+ # Example:
26
+ # on @page do |i|
27
+ # i.enter_text('btn1')
28
+ # i.click_button('btn1')
29
+ # end
30
+ def on(page, &block)
31
+ yield page
32
+ end
33
+
34
+ def test_context
35
+ @web_tester.test_context
36
+ end
37
+
38
+ def begin_at(url)
39
+ @web_tester.begin_at(url)
40
+ end
41
+
42
+ def ie;
43
+ @web_tester.ie;
44
+ end
45
+
46
+ def close_browser
47
+ @web_tester.close_browser unless ENV['ITEST_LEAVE_BROWSER_OPEN_AFTER_RUN'] == "true"
48
+ end
49
+ alias close_ie close_browser
50
+
51
+ # browser navigation
52
+ def go_back;
53
+ @web_tester.go_back;
54
+ end
55
+ def go_forward;
56
+ @web_tester.go_forward;
57
+ end
58
+
59
+ def goto_page(page)
60
+ operation_delay
61
+ @web_tester.goto_page(page);
62
+ end
63
+ def refresh;
64
+ @web_tester.refresh;
65
+ end
66
+ alias refresh_page refresh
67
+
68
+ def attach_browser(how, what)
69
+ WebTester.attach_browser(how, what)
70
+ end
71
+
72
+ ##
73
+ # Delegate to WebTester
74
+ #
75
+
76
+ # Depends on which object type, you can use following attribute
77
+ # More details: http://wiki.openqa.org/display/WTR/Methods+supported+by+Element
78
+ #
79
+ # :id Used to find an element that has an "id=" attribute. Since each id should be unique, according to the XHTML specification, this is recommended as the most reliable method to find an object. *
80
+ # :name Used to find an element that has a "name=" attribute. This is useful for older versions of HTML, but "name" is deprecated in XHTML. *
81
+ # :value Used to find a text field with a given default value, or a button with a given caption, or a text field
82
+ # :text Used for links, spans, divs and other element that contain text.
83
+ # :index Used to find the nth element of the specified type on a page. For example, button(:index, 2) finds the second button. Current versions of WATIR use 1-based indexing, but future versions will use 0-based indexing.
84
+ # :class Used for an element that has a "class=" attribute.
85
+ # :title Used for an element that has a "title=" attribute.
86
+ # :xpath Finds the item using xpath query.
87
+ # :method Used only for forms, the method attribute of a form is either GET or POST.
88
+ # :action Used only for form elements, specifies the URL where the form is to be submitted.
89
+ # :href Used to identify a link by its "href=" attribute.
90
+ # :src Used to identify an image by its URL.
91
+ #
92
+
93
+ # area <area> tags
94
+ # button <input> tags with type=button, submit, image or reset
95
+ # check_box <input> tags with type=checkbox
96
+ # div <div> tags
97
+ # form <form> tags
98
+ # frame frames, including both the <frame> elements and the corresponding pages
99
+ # h1 - h6 <h1>, <h2>, <h3>, <h4>, <h5>, <h6> tags
100
+ # hidden <input> tags with type=hidden
101
+ # image <img> tags
102
+ # label <label> tags (including "for" attribute)
103
+ # li <li> tags
104
+ # link <a> (anchor) tags
105
+ # map <map> tags
106
+ # radio <input> tags with the type=radio; known as radio buttons
107
+ # select_list <select> tags, known as drop-downs or drop-down lists
108
+ # span <span> tags
109
+ # table <table> tags, including row and cell methods for accessing nested elements
110
+ # text_field <input> tags with the type=text (single-line), type=textarea (multi-line), and type=password
111
+ # p <p> (paragraph) tags, because
112
+ def area(*args)
113
+ @web_tester.area(*args);
114
+ end
115
+ def button(*args)
116
+ @web_tester.button(*args);
117
+ end
118
+ def cell(*args)
119
+ @web_tester.cell(*args);
120
+ end
121
+ alias td cell
122
+
123
+ def checkbox(*args)
124
+ @web_tester.checkbox(*args);
125
+ end
126
+ alias check_box checkbox # seems watir doc is wrong, checkbox not check_box
127
+
128
+ def div(*args)
129
+ @web_tester.div(*args);
130
+ end
131
+ def form(*args)
132
+ @web_tester.form(*args);
133
+ end
134
+ def frame(*args)
135
+ @web_tester.frame(*args);
136
+ end
137
+ def h1(*args)
138
+ @web_tester.h1(*args);
139
+ end
140
+ def h2(*args)
141
+ @web_tester.h2(*args);
142
+ end
143
+ def h3(*args)
144
+ @web_tester.h3(*args);
145
+ end
146
+ def h4(*args)
147
+ @web_tester.h4(*args);
148
+ end
149
+ def h5(*args)
150
+ @web_tester.h5(*args);
151
+ end
152
+ def h6(*args)
153
+ @web_tester.h6(*args);
154
+ end
155
+ def hidden(*args)
156
+ @web_tester.hidden(*args);
157
+ end
158
+ def image(*args)
159
+ @web_tester.image(*args);
160
+ end
161
+ def li(*args)
162
+ @web_tester.li(*args);
163
+ end
164
+ def link(*args)
165
+ @web_tester.link(*args);
166
+ end
167
+ def map(*args)
168
+ @web_tester.map(*args);
169
+ end
170
+ def pre(*args)
171
+ @web_tester.pre(*args);
172
+ end
173
+ def row(*args)
174
+ @web_tester.row(*args);
175
+ end
176
+ alias tr row
177
+
178
+ def radio(*args)
179
+ @web_tester.radio(*args);
180
+ end
181
+ def select_list(*args)
182
+ @web_tester.select_list(*args);
183
+ end
184
+ def span(*args)
185
+ @web_tester.span(*args);
186
+ end
187
+ def table(*args)
188
+ @web_tester.table(*args);
189
+ end
190
+ def text_field(*args)
191
+ @web_tester.text_field(*args);
192
+ end
193
+
194
+ def paragraph(*args)
195
+ @web_tester.paragraph(*args);
196
+ end
197
+ def file_field(*args)
198
+ @web_tester.file_field(*args);
199
+ end
200
+ def label(*args)
201
+ @web_tester.label(*args);
202
+ end
203
+
204
+ def contains_text(text)
205
+ @web_tester.contains_text(text);
206
+ end
207
+
208
+
209
+ def images;
210
+ @web_tester.images;
211
+ end
212
+ def links;
213
+ @web_tester.links;
214
+ end
215
+ def buttons;
216
+ @web_tester.buttons;
217
+ end
218
+ def select_lists;
219
+ @web_tester.select_lists;
220
+ end
221
+ def checkboxes;
222
+ @web_tester.checkboxes;
223
+ end
224
+ def radios;
225
+ @web_tester.radios;
226
+ end
227
+ def text_fields;
228
+ @web_tester.text_fields;
229
+ end
230
+
231
+
232
+ # enter text into a text field
233
+ def enter_text(elementName, elementValue)
234
+ operation_delay
235
+ @web_tester.set_form_element(elementName, elementValue)
236
+ end
237
+ alias set_form_element enter_text
238
+
239
+
240
+ #links
241
+ def click_link_with_text(link_text)
242
+ operation_delay
243
+ @web_tester.click_link_with_text(link_text)
244
+ end
245
+ alias click_link click_link_with_text
246
+
247
+ def click_link_with_id(link_id)
248
+ operation_delay
249
+ @web_tester.click_link_with_id(link_id)
250
+ end
251
+
252
+ ##
253
+ # buttons
254
+
255
+ # submit the form using the first (index) submit button
256
+ def submit()
257
+ operation_delay
258
+ @web_tester.submit()
259
+ end
260
+
261
+ # click a form submit button with specified button id
262
+ def submit(button_id)
263
+ operation_delay
264
+ @web_tester.submit(button_id)
265
+ end
266
+
267
+ def click_button_with_id(button_id)
268
+ operation_delay
269
+ @web_tester.click_button_with_id(button_id)
270
+ end
271
+
272
+ def click_button_with_caption(caption)
273
+ operation_delay
274
+ @web_tester.click_button_with_caption(caption)
275
+ end
276
+ alias click_button_with_text click_button_with_caption
277
+ alias click_button click_button_with_caption
278
+
279
+ def click_button_with_image_src_contains(image_filename)
280
+ operation_delay
281
+ found = nil
282
+ raise "no buttons in this page" if buttons.length <= 0
283
+ buttons.each { |btn|
284
+ if btn && btn.src && btn.src.include?(image_filename) then
285
+ found = btn
286
+ break
287
+ end
288
+ }
289
+ raise "not image button with src: #{image_filename} found" if found.nil?
290
+ found.click
291
+ end
292
+ alias click_button_with_image click_button_with_image_src_contains
293
+
294
+ def click_button_with_value(value)
295
+ operation_delay
296
+ @web_tester.click_button_with_value(value)
297
+ end
298
+
299
+ # Radios
300
+ def click_radio_option(name, value)
301
+ operation_delay
302
+ @web_tester.click_radio_option(name, value)
303
+ end
304
+ alias click_radio_button click_radio_option
305
+
306
+ def clear_radio_option(name, value)
307
+ operation_delay
308
+ @web_tester.clear_radio_option(name, value)
309
+ end
310
+ alias clear_radio_button clear_radio_option
311
+
312
+ # Filefield
313
+ def select_file_for_upload(file_field, file_path)
314
+ operation_delay
315
+ @web_tester.select_file_for_upload(file_field, file_path)
316
+ end
317
+
318
+ # Check one or more checkboxes with same name, can accept a string or an array of string as values checkbox, pass array as values will try to set mulitple checkboxes.
319
+ #
320
+ # page.check_checkbox('bad_ones', 'Chicken Little')
321
+ # page.check_checkbox('good_ones', ['Cars', 'Toy Story'])
322
+ def check_checkbox(name, value=nil)
323
+ operation_delay
324
+ @web_tester.check_checkbox(name, value)
325
+ end
326
+
327
+ # Uncheck one or more checkboxes with same name
328
+ def uncheck_checkbox(name, value=nil)
329
+ operation_delay
330
+ @web_tester.uncheck_checkbox(name, value)
331
+ end
332
+
333
+ # combo box
334
+ def select_option(selectName, option)
335
+ operation_delay
336
+ @web_tester.select_option(selectName, option)
337
+ end
338
+
339
+ def new_popup_window(options)
340
+ @web_tester.new_popup_window(options)
341
+ end
342
+
343
+ # Wait for specific seconds for an Ajax update finish.
344
+ # Trick: In your Rails application,
345
+ # :loading => "Element.show('search_indicator');
346
+ # :complete => "Element.hide('search_indicator');
347
+ #
348
+ # <%= image_tag("indicator.gif", :id => 'search_indicator', :style => 'display:none') %>
349
+ #
350
+ # Typical usage:
351
+ # ajax_wait_for_element("search_indicator", 30)
352
+ # ajax_wait_for_element("search_indicator", 30, "show")
353
+ # ajax_wait_for_element("search_indicator", 30, "hide")
354
+ # ajax_wait_for_element("search_indicator", 30, "show", 5) # check every 5 seconds
355
+ #
356
+ # Warning: this method has not been fully tested, if you are not using Rails, change your parameter accordingly.
357
+ #
358
+ def ajax_wait_for_element(element_id, seconds, status='show', check_interval=2)
359
+ count = 0
360
+ check_interval = 2 if check_interval < 1 or check_interval > seconds
361
+ while count < (seconds / check_interval) do
362
+ search_indicator = @web_tester.element_by_id(element_id)
363
+ search_indicator_outer_html = search_indicator.outerHtml if search_indicator
364
+ if status == 'hide'
365
+ return true if search_indicator_outer_html and !search_indicator_outer_html.include?('style="DISPLAY: none"')
366
+ else
367
+ return true if search_indicator_outer_html and search_indicator_outer_html.include?('style="DISPLAY: none"')
368
+ end
369
+ sleep check_interval if check_interval > 0 and check_interval < 5 * 60 # wait max 5 minutes
370
+ count += 1
371
+ end
372
+ return false
373
+ end
374
+
375
+ def wait_for_element(element_id, timeout = 30, interval = 0.5)
376
+ start_time = Time.now
377
+ until @web_tester.element_by_id(element_id) do
378
+ sleep(interval)
379
+ if (Time.now - start_time) > timeout
380
+ raise RuntimeError, "failed to find element: #{element_id} for max #{timeout}"
381
+ end
382
+ end
383
+ end
384
+
385
+ def element_text(elem_id)
386
+ @web_tester.element_value(elem_id)
387
+ end
388
+
389
+ # fail the test if user can perform the operation
390
+ def shall_not_allow
391
+ operation_performed_ok = false
392
+ begin
393
+ yield
394
+ operation_performed_ok = true
395
+ rescue
396
+ end
397
+
398
+ raise "Operation shall not be allowed" if operation_performed_ok
399
+ end
400
+ alias do_not_allow shall_not_allow
401
+
402
+ # ---
403
+ # For debugging
404
+ # ---
405
+ def dump_response(stream = nil)
406
+ @web_tester.dump_response(stream)
407
+ end
408
+
409
+ def click_popup_window(button, waitTime= 9, user_input=nil )
410
+ @web_tester.start_clicker(button, waitTime, user_input)
411
+ end
412
+
413
+ def operation_delay
414
+ begin
415
+ if ENV['ITEST_OPERATION_DELAY'] && ENV['ITEST_OPERATION_DELAY'].to_i > 0 && ENV['ITEST_OPERATION_DELAY'].to_f < 30000 then # max 30 seconds
416
+ sleep(ENV['ITEST_OPERATION_DELAY'].to_f / 1000)
417
+ end
418
+ rescue => e
419
+ # ignore
420
+ end
421
+ end
422
+
423
+ end
424
+ end