rwebspec-webdriver 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +11 -12
- data/lib/rwebspec-webdriver/assert.rb +445 -0
- data/lib/{rwebspec → rwebspec-webdriver}/clickJSDialog.rb +0 -0
- data/lib/{rwebspec → rwebspec-webdriver}/context.rb +13 -11
- data/lib/rwebspec-webdriver/database_checker.rb +76 -0
- data/lib/rwebspec-webdriver/driver.rb +1011 -0
- data/lib/rwebspec-webdriver/element_locator.rb +89 -0
- data/lib/rwebspec-webdriver/load_test_helper.rb +174 -0
- data/lib/{rwebspec → rwebspec-webdriver}/matchers/contains_text.rb +0 -0
- data/lib/rwebspec-webdriver/popup.rb +149 -0
- data/lib/rwebspec-webdriver/rspec_helper.rb +101 -0
- data/lib/rwebspec-webdriver/test_script.rb +10 -0
- data/lib/rwebspec-webdriver/test_utils.rb +219 -0
- data/lib/rwebspec-webdriver/testwise_plugin.rb +85 -0
- data/lib/rwebspec-webdriver/using_pages.rb +51 -0
- data/lib/rwebspec-webdriver/web_browser.rb +744 -0
- data/lib/rwebspec-webdriver/web_page.rb +110 -0
- data/lib/rwebspec-webdriver/web_testcase.rb +40 -0
- data/lib/rwebspec-webdriver.rb +12 -12
- metadata +22 -22
- data/lib/rwebspec/assert.rb +0 -443
- data/lib/rwebspec/database_checker.rb +0 -74
- data/lib/rwebspec/driver.rb +0 -1009
- data/lib/rwebspec/element_locator.rb +0 -87
- data/lib/rwebspec/load_test_helper.rb +0 -172
- data/lib/rwebspec/popup.rb +0 -147
- data/lib/rwebspec/rspec_helper.rb +0 -99
- data/lib/rwebspec/test_script.rb +0 -8
- data/lib/rwebspec/test_utils.rb +0 -217
- data/lib/rwebspec/testwise_plugin.rb +0 -83
- data/lib/rwebspec/using_pages.rb +0 -49
- data/lib/rwebspec/web_browser.rb +0 -742
- data/lib/rwebspec/web_page.rb +0 -108
- data/lib/rwebspec/web_testcase.rb +0 -38
File without changes
|
@@ -4,21 +4,23 @@
|
|
4
4
|
#***********************************************************
|
5
5
|
|
6
6
|
module RWebSpec
|
7
|
+
module WebDriver
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
##
|
10
|
+
# Store test optionns
|
11
|
+
#
|
12
|
+
class Context
|
13
|
+
attr_accessor :base_url
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
def initialize(base_url)
|
16
|
+
set_base_url(base_url)
|
17
|
+
end
|
18
|
+
|
19
|
+
def set_base_url(baseUrl)
|
20
|
+
@base_url = baseUrl
|
21
|
+
end
|
17
22
|
|
18
|
-
def set_base_url(baseUrl)
|
19
|
-
@base_url = baseUrl
|
20
23
|
end
|
21
24
|
|
22
25
|
end
|
23
|
-
|
24
26
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'active_record' # change rwebspec/database
|
2
|
+
|
3
|
+
module RWebSpec
|
4
|
+
module WebDriver
|
5
|
+
module DatabaseChecker
|
6
|
+
|
7
|
+
# Example
|
8
|
+
# connect_to_database mysql_db(:host => "localhost", :database => "lavabuild_local", :user => "root", :password => ""), true
|
9
|
+
def mysql_db(settings)
|
10
|
+
options = {:adapter => "mysql"}
|
11
|
+
options.merge!(settings)
|
12
|
+
end
|
13
|
+
|
14
|
+
# connect_to_database sqlite3_db(:database => File.join(File.dirname(__FILE__), "testdata", "sample.sqlite3")), true
|
15
|
+
def sqlite3_db(settings)
|
16
|
+
options = {:adapter => "sqlite3"}
|
17
|
+
options.merge!(settings)
|
18
|
+
end
|
19
|
+
|
20
|
+
def sqlserver_db(settings)
|
21
|
+
options = {:adapter => "sqlserver"}
|
22
|
+
options[:username] ||= settings[:user]
|
23
|
+
options.merge!(settings)
|
24
|
+
end
|
25
|
+
|
26
|
+
def sqlserver_db_dbi(options)
|
27
|
+
options[:user] ||= options[:username]
|
28
|
+
options[:username] ||= options[:user]
|
29
|
+
conn_str = "DBI:ADO:Provider=SQLOLEDB;Data Source=#{options[:host]};Initial Catalog=#{options[:database]};User ID=\"#{options[:user]}\";password=\"#{options[:password]}\" "
|
30
|
+
dbh = DBI.connect(conn_str)
|
31
|
+
end
|
32
|
+
|
33
|
+
def clear_database_connection
|
34
|
+
begin
|
35
|
+
ActiveRecord::Base.remove_connection
|
36
|
+
rescue => e
|
37
|
+
puts "failed o clear database connection: #{e}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Connect to databse, example
|
42
|
+
# mysql_db(:host => "localhost", :database => "lavabuild_local", :user => "root", :password => "")
|
43
|
+
def connect_to_database(db_settings, force = false)
|
44
|
+
# only setup database connection once
|
45
|
+
if force
|
46
|
+
ActiveRecord::Base.establish_connection(db_settings)
|
47
|
+
else
|
48
|
+
begin
|
49
|
+
ActiveRecord::Base.connection
|
50
|
+
rescue => e
|
51
|
+
require 'pp'
|
52
|
+
pp db_settings
|
53
|
+
puts "failed to connect: #{e}"
|
54
|
+
ActiveRecord::Base.establish_connection(db_settings)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def load_table(table_name)
|
60
|
+
begin
|
61
|
+
ActiveRecord::Base.connection
|
62
|
+
rescue =>e
|
63
|
+
raise "No database connection setup yet, use connect_to_database() method"
|
64
|
+
end
|
65
|
+
class_name = table_name.classify
|
66
|
+
# define the class, so can use ActiveRecord in
|
67
|
+
# such as
|
68
|
+
# Perosn.count.should == 2
|
69
|
+
def_class = "class ::#{class_name} < ActiveRecord::Base; end"
|
70
|
+
eval def_class
|
71
|
+
return def_class
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,1011 @@
|
|
1
|
+
# convenient methods to drive the browser.
|
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
|
+
require File.join(File.dirname(__FILE__), 'testwise_plugin')
|
10
|
+
require File.join(File.dirname(__FILE__), 'popup')
|
11
|
+
require File.join(File.dirname(__FILE__), 'matchers', "contains_text.rb")
|
12
|
+
|
13
|
+
require 'timeout'
|
14
|
+
require 'uri'
|
15
|
+
|
16
|
+
module RWebSpec
|
17
|
+
module WebDriver
|
18
|
+
module Driver
|
19
|
+
include RWebSpec::WebDriver::TestWisePlugin
|
20
|
+
include RWebSpec::WebDriver::Popup
|
21
|
+
|
22
|
+
@@default_polling_interval = 1 # second
|
23
|
+
@@default_timeout = 30 # seconds
|
24
|
+
|
25
|
+
# open a browser, and set base_url via hash, but does not acually
|
26
|
+
#
|
27
|
+
# example:
|
28
|
+
# open_browser :base_url => http://localhost:8080
|
29
|
+
#
|
30
|
+
# There are 3 ways to set base url
|
31
|
+
# 1. pass as first argument
|
32
|
+
# 2. If running using TestWise, used as confiured
|
33
|
+
# 3. Use default value set
|
34
|
+
#
|
35
|
+
#
|
36
|
+
# New Options:
|
37
|
+
# :browser => :ie | :firefox | :chrome
|
38
|
+
def open_browser(base_url = nil, options = {})
|
39
|
+
puts "[DEBUG] [SeleniumDriver] Callling open_browser #{base_url}"
|
40
|
+
begin
|
41
|
+
support_unicode
|
42
|
+
rescue => e
|
43
|
+
puts "Unicode may not work in IE, #{e}"
|
44
|
+
end
|
45
|
+
|
46
|
+
base_url ||= $ITEST2_PROJECT_BASE_URL
|
47
|
+
base_url ||= $BASE_URL
|
48
|
+
raise "base_url must be set" if base_url.nil?
|
49
|
+
|
50
|
+
default_options = {:speed => "fast",
|
51
|
+
:visible => true,
|
52
|
+
:highlight_colour => 'yellow',
|
53
|
+
:close_others => true,
|
54
|
+
:start_new => true, # start a new browser always
|
55
|
+
:go => true}
|
56
|
+
|
57
|
+
options = default_options.merge options
|
58
|
+
|
59
|
+
if $ITEST2_BROWSER
|
60
|
+
options[:browser] = $ITEST2_BROWSER.downcase
|
61
|
+
end
|
62
|
+
if options[:firefox] && options[:browser].nil? then
|
63
|
+
options[:browser] = "firefox" # legacy
|
64
|
+
end
|
65
|
+
|
66
|
+
if base_url =~ /^file:/
|
67
|
+
uri_base = base_url
|
68
|
+
else
|
69
|
+
uri = URI.parse(base_url)
|
70
|
+
uri_base = "#{uri.scheme}://#{uri.host}:#{uri.port}"
|
71
|
+
end
|
72
|
+
|
73
|
+
if options[:start_new] || $celerity_loaded
|
74
|
+
puts "[DEBUG] [SeleniumBrowser] creating a new browser"
|
75
|
+
@web_browser = WebBrowser.new(uri_base, nil, options)
|
76
|
+
puts "[DEBUG] [SeleniumBrowser] browser: #{@web_browser.inspect}"
|
77
|
+
else
|
78
|
+
@web_browser = WebBrowser.reuse(uri_base, options) # Reuse existing browser
|
79
|
+
end
|
80
|
+
|
81
|
+
if base_url =~ /^file:/
|
82
|
+
goto_url(base_url) # for files, no base url
|
83
|
+
else
|
84
|
+
(uri.path.length == 0) ? begin_at(base_url) : begin_at(uri.path) if options[:go]
|
85
|
+
end
|
86
|
+
|
87
|
+
return @web_browser
|
88
|
+
end
|
89
|
+
|
90
|
+
alias open_browser_with open_browser
|
91
|
+
|
92
|
+
# return the underlying RWebSpec::WebDriver::Browser object
|
93
|
+
def browser
|
94
|
+
@web_browser
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
def quit
|
99
|
+
@web_browser.quit
|
100
|
+
end
|
101
|
+
|
102
|
+
def find_element(how, what)
|
103
|
+
@web_browser.find_element(how, what)
|
104
|
+
end
|
105
|
+
|
106
|
+
def find_elements(how, what)
|
107
|
+
@web_browser.find_elements(how, what)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Close the current browser window (started by the script). If no browser started, then close
|
111
|
+
# all browser windows.
|
112
|
+
#
|
113
|
+
def close_browser
|
114
|
+
if @web_browser
|
115
|
+
# Old TestWise version
|
116
|
+
# @web_browser.close_browser unless $ITEST2_LEAVE_BROWSER_OPEN_AFTER_RUN
|
117
|
+
@web_browser.close_browser
|
118
|
+
else
|
119
|
+
WebBrowser.close_all_browsers
|
120
|
+
end
|
121
|
+
end
|
122
|
+
alias close_ie close_browser
|
123
|
+
|
124
|
+
|
125
|
+
# Close all opening browser windows
|
126
|
+
#
|
127
|
+
def close_all_browsers
|
128
|
+
#TODO
|
129
|
+
end
|
130
|
+
|
131
|
+
# Verify the next page following an operation.
|
132
|
+
#
|
133
|
+
# Typical usage:
|
134
|
+
# login_page.click_login
|
135
|
+
# expect_page HomePage
|
136
|
+
def expect_page(page_clazz, argument = nil)
|
137
|
+
if argument
|
138
|
+
@web_browser.expect_page(page_clazz, argument)
|
139
|
+
else
|
140
|
+
@web_browser.expect_page(page_clazz)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def context
|
145
|
+
@web_browser.context
|
146
|
+
end
|
147
|
+
|
148
|
+
# Starting browser with a URL
|
149
|
+
#
|
150
|
+
# Example:
|
151
|
+
# begin_at("http://www.itest2.com")
|
152
|
+
def begin_at(url)
|
153
|
+
puts "[DEBUG] [SeleniumBrowser] begin_at #{url}"
|
154
|
+
dump_caller_stack
|
155
|
+
@web_browser.begin_at(url)
|
156
|
+
end
|
157
|
+
|
158
|
+
# Return the Watir::IE instance
|
159
|
+
#
|
160
|
+
def ie
|
161
|
+
@web_browser.ie
|
162
|
+
end
|
163
|
+
|
164
|
+
# Return the FireWatir::Firefox instance
|
165
|
+
#
|
166
|
+
def firefox
|
167
|
+
@web_browser.firefox
|
168
|
+
end
|
169
|
+
|
170
|
+
def is_firefox?
|
171
|
+
@web_browser.is_firefox? if @web_browser
|
172
|
+
end
|
173
|
+
|
174
|
+
def is_ie?
|
175
|
+
@web_browser.is_ie? if @web_browser
|
176
|
+
end
|
177
|
+
|
178
|
+
def is_htmlunit?
|
179
|
+
RUBY_PLATFORM =~ /java/ && @web_browser
|
180
|
+
end
|
181
|
+
|
182
|
+
# Go to another page on the testing site.
|
183
|
+
#
|
184
|
+
# open_browser("http://www.itest2.com")
|
185
|
+
# goto_page("/demo") # visit page http://www.itest2.com/demo
|
186
|
+
#
|
187
|
+
def goto_page(page)
|
188
|
+
perform_operation {
|
189
|
+
@web_browser.goto_page(page) if @web_browser
|
190
|
+
}
|
191
|
+
end
|
192
|
+
alias visit goto_page
|
193
|
+
|
194
|
+
# Go to another web site, normally different site being tested on
|
195
|
+
#
|
196
|
+
# open_browser("http://www.itest2.com")
|
197
|
+
# goto_url("http://myorganized.info")
|
198
|
+
def goto_url(url)
|
199
|
+
puts "Calling web_browser goto: #{@web_browser.inspect}"
|
200
|
+
@web_browser.goto_url url
|
201
|
+
end
|
202
|
+
|
203
|
+
# Attach to existinb browser window
|
204
|
+
#
|
205
|
+
# attach_browser(:title, )
|
206
|
+
def attach_browser(how, what, options = {})
|
207
|
+
#TODO
|
208
|
+
options.merge!(:browser => is_firefox? ? "Firefox" : "IE") unless options[:browser]
|
209
|
+
begin
|
210
|
+
options.merge!(:base_url => browser.context.base_url)
|
211
|
+
rescue => e
|
212
|
+
puts "failed to set base_url, ignore : #{e}"
|
213
|
+
end
|
214
|
+
WebBrowser.attach_browser(how, what, options)
|
215
|
+
end
|
216
|
+
|
217
|
+
# Reuse current an opened browser window instead of opening a new one
|
218
|
+
# example:
|
219
|
+
# use_current_browser(:title, /.*/) # use what ever browser window
|
220
|
+
# use_current_browser(:title, "TestWise") # use browser window with title "TestWise"
|
221
|
+
def use_current_browser(how = :title, what = /.*/)
|
222
|
+
@web_browser = WebBrowser.attach_browser(how, what)
|
223
|
+
end
|
224
|
+
|
225
|
+
[:back, :forward, :refresh].each do |method|
|
226
|
+
define_method(method) do
|
227
|
+
perform_operation { @web_browser.send(method) if @web_browser }
|
228
|
+
end
|
229
|
+
end
|
230
|
+
alias refresh_page refresh
|
231
|
+
alias go_back back
|
232
|
+
alias go_forward forward
|
233
|
+
|
234
|
+
##
|
235
|
+
# Delegate to WebTester
|
236
|
+
#
|
237
|
+
# Note:
|
238
|
+
# label(:id, "abc") # OK
|
239
|
+
# label(:id, :abc) # Error
|
240
|
+
#
|
241
|
+
# Depends on which object type, you can use following attribute
|
242
|
+
# More details: http://wiki.openqa.org/display/WTR/Methods+supported+by+Element
|
243
|
+
#
|
244
|
+
# :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. *
|
245
|
+
# :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. *
|
246
|
+
# :value Used to find a text field with a given default value, or a button with a given caption, or a text field
|
247
|
+
# :text Used for links, spans, divs and other element that contain text.
|
248
|
+
# :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.
|
249
|
+
# :class Used for an element that has a "class=" attribute.
|
250
|
+
# :title Used for an element that has a "title=" attribute.
|
251
|
+
# :xpath Finds the item using xpath query.
|
252
|
+
# :method Used only for forms, the method attribute of a form is either GET or POST.
|
253
|
+
# :action Used only for form elements, specifies the URL where the form is to be submitted.
|
254
|
+
# :href Used to identify a link by its "href=" attribute.
|
255
|
+
# :src Used to identify an image by its URL.
|
256
|
+
#
|
257
|
+
|
258
|
+
# area <area> tags
|
259
|
+
# button <input> tags with type=button, submit, image or reset
|
260
|
+
# check_box <input> tags with type=checkbox
|
261
|
+
# div <div> tags
|
262
|
+
# form <form> tags
|
263
|
+
# frame frames, including both the <frame> elements and the corresponding pages
|
264
|
+
# h1 - h6 <h1>, <h2>, <h3>, <h4>, <h5>, <h6> tags
|
265
|
+
# hidden <input> tags with type=hidden
|
266
|
+
# image <img> tags
|
267
|
+
# label <label> tags (including "for" attribute)
|
268
|
+
# li <li> tags
|
269
|
+
# link <a> (anchor) tags
|
270
|
+
# map <map> tags
|
271
|
+
# radio <input> tags with the type=radio; known as radio buttons
|
272
|
+
# select_list <select> tags, known as drop-downs or drop-down lists
|
273
|
+
# span <span> tags
|
274
|
+
# table <table> tags, including row and cell methods for accessing nested elements
|
275
|
+
# text_field <input> tags with the type=text (single-line), type=textarea (multi-line), and type=password
|
276
|
+
# p <p> (paragraph) tags, because
|
277
|
+
[:area, :button, :cell, :checkbox, :div, :form, :frame, :h1, :h2, :h3, :h4, :h5, :h6, :hidden, :image, :li, :link, :map, :pre, :row, :radio, :select_list, :span, :table, :text_field, :paragraph, :file_field, :label].each do |method|
|
278
|
+
define_method method do |* args|
|
279
|
+
perform_operation { @web_browser.send(method, * args) if @web_browser }
|
280
|
+
end
|
281
|
+
end
|
282
|
+
alias td cell
|
283
|
+
alias check_box checkbox # seems watir doc is wrong, checkbox not check_box
|
284
|
+
alias tr row
|
285
|
+
|
286
|
+
|
287
|
+
[:images, :links, :buttons, :select_lists, :checkboxes, :radios, :text_fields].each do |method|
|
288
|
+
define_method method do
|
289
|
+
perform_operation { @web_browser.send(method) if @web_browser }
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
# 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.
|
294
|
+
#
|
295
|
+
# page.check_checkbox('bad_ones', 'Chicken Little')
|
296
|
+
# page.check_checkbox('good_ones', ['Cars', 'Toy Story'])
|
297
|
+
#
|
298
|
+
[:set_form_element, :click_link_with_text, :click_link_with_id, :submit, :click_button_with_id, :click_button_with_name, :click_button_with_caption, :click_button_with_value, :click_radio_option, :clear_radio_option, :check_checkbox, :uncheck_checkbox, :select_option].each do |method|
|
299
|
+
define_method method do |* args|
|
300
|
+
perform_operation { @web_browser.send(method, * args) if @web_browser }
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
alias enter_text set_form_element
|
305
|
+
alias set_hidden_field set_form_element
|
306
|
+
alias click_link click_link_with_text
|
307
|
+
alias click_button_with_text click_button_with_caption
|
308
|
+
alias click_button click_button_with_caption
|
309
|
+
alias click_radio_button click_radio_option
|
310
|
+
alias clear_radio_button clear_radio_option
|
311
|
+
|
312
|
+
# for text field can be easier to be identified by attribute "id" instead of "name", not recommended though
|
313
|
+
def enter_text_with_id(textfield_id, value)
|
314
|
+
perform_operation {
|
315
|
+
elements = find_elements(:id, textfield_id)
|
316
|
+
if elements.size == 1 then
|
317
|
+
elements[0].send_keys(value)
|
318
|
+
else
|
319
|
+
smaller_set = elements.select {|x| x.tag_name == "textarea" || (x.tag_name == "input" && x.attribute("text")) }
|
320
|
+
smaller_set[0].send_keys(value)
|
321
|
+
end
|
322
|
+
}
|
323
|
+
end
|
324
|
+
|
325
|
+
def perform_operation(& block)
|
326
|
+
begin
|
327
|
+
dump_caller_stack
|
328
|
+
operation_delay
|
329
|
+
yield
|
330
|
+
rescue RuntimeError => re
|
331
|
+
puts "[DEBUG] operation error: #{re}"
|
332
|
+
raise re
|
333
|
+
# ensure
|
334
|
+
# puts "[DEBUG] ensure #{perform_ok}" unless perform_ok
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
def contains_text(text)
|
339
|
+
@web_browser.contains_text(text)
|
340
|
+
end
|
341
|
+
|
342
|
+
# In pages, can't use include, text.should include("abc") won't work
|
343
|
+
# Instead,
|
344
|
+
# text.should contains("abc"
|
345
|
+
def contains(str)
|
346
|
+
ContainsText.new(str)
|
347
|
+
end
|
348
|
+
|
349
|
+
alias contain contains
|
350
|
+
|
351
|
+
# Click image buttion with image source name
|
352
|
+
#
|
353
|
+
# For an image submit button <input name="submit" type="image" src="/images/search_button.gif">
|
354
|
+
# click_button_with_image("search_button.gif")
|
355
|
+
def click_button_with_image_src_contains(image_filename)
|
356
|
+
perform_operation {
|
357
|
+
@web_browser.click_button_with_image_src_contains(image_filename)
|
358
|
+
}
|
359
|
+
end
|
360
|
+
|
361
|
+
alias click_button_with_image click_button_with_image_src_contains
|
362
|
+
|
363
|
+
def new_popup_window(options)
|
364
|
+
@web_browser.new_popup_window(options)
|
365
|
+
end
|
366
|
+
|
367
|
+
|
368
|
+
# Warning: this does not work well with Firefox yet.
|
369
|
+
def element_text(elem_id)
|
370
|
+
@web_browser.element_value(elem_id)
|
371
|
+
end
|
372
|
+
|
373
|
+
# Identify DOM element by ID
|
374
|
+
# Warning: it is only supported on IE
|
375
|
+
def element_by_id(elem_id)
|
376
|
+
@web_browser.element_by_id(elem_id)
|
377
|
+
end
|
378
|
+
|
379
|
+
# ---
|
380
|
+
# For debugging
|
381
|
+
# ---
|
382
|
+
def dump_response(stream = nil)
|
383
|
+
@web_browser.dump_response(stream)
|
384
|
+
end
|
385
|
+
|
386
|
+
def default_dump_dir
|
387
|
+
if $ITEST2_RUNNING_SPEC_ID && $ITEST2_WORKING_DIR
|
388
|
+
|
389
|
+
$ITEST2_DUMP_DIR = File.join($ITEST2_WORKING_DIR, "dump")
|
390
|
+
FileUtils.mkdir($ITEST2_DUMP_DIR) unless File.exists?($ITEST2_DUMP_DIR)
|
391
|
+
|
392
|
+
spec_run_id = $ITEST2_RUNNING_SPEC_ID
|
393
|
+
spec_run_dir_name = spec_run_id.to_s.rjust(4, "0") unless spec_run_id == "unknown"
|
394
|
+
to_dir = File.join($ITEST2_DUMP_DIR, spec_run_dir_name)
|
395
|
+
else
|
396
|
+
to_dir = ENV['TEMP_DIR'] || (is_windows? ? "C:\\temp" : "/tmp")
|
397
|
+
end
|
398
|
+
end
|
399
|
+
|
400
|
+
# For current page souce to a file in specified folder for inspection
|
401
|
+
#
|
402
|
+
# save_current_page(:dir => "C:\\mysite", filename => "abc", :replacement => true)
|
403
|
+
def save_current_page(options = {})
|
404
|
+
default_options = {:replacement => true}
|
405
|
+
options = default_options.merge(options)
|
406
|
+
to_dir = options[:dir] || default_dump_dir
|
407
|
+
|
408
|
+
if options[:filename]
|
409
|
+
file_name = options[:filename]
|
410
|
+
else
|
411
|
+
file_name = Time.now.strftime("%m%d%H%M%S") + ".html"
|
412
|
+
end
|
413
|
+
|
414
|
+
Dir.mkdir(to_dir) unless File.exists?(to_dir)
|
415
|
+
file = File.join(to_dir, file_name)
|
416
|
+
|
417
|
+
content = page_source
|
418
|
+
base_url = @web_browser.context.base_url
|
419
|
+
current_url = @web_browser.url
|
420
|
+
current_url =~ /(.*\/).*$/
|
421
|
+
current_url_parent = $1
|
422
|
+
if options[:replacement] && base_url =~ /^http:/
|
423
|
+
File.new(file, "w").puts absolutize_page_hpricot(content, base_url, current_url_parent)
|
424
|
+
else
|
425
|
+
File.new(file, "w").puts content
|
426
|
+
end
|
427
|
+
|
428
|
+
end
|
429
|
+
|
430
|
+
|
431
|
+
# <link rel="stylesheet" type="text/css" href="/stylesheets/default.css" />
|
432
|
+
# '<script type="text/javascript" src="http://www.jeroenwijering.com/embed/swfobject.js"></script>'
|
433
|
+
# <script type="text/javascript" src="/javascripts/prototype.js"></script>
|
434
|
+
# <script type="text/javascript" src="/javascripts/scriptaculous.js?load=effects,builder"></script>
|
435
|
+
# <script type="text/javascript" src="/javascripts/extensions/gallery/lightbox.js"></script>
|
436
|
+
# <link href="/stylesheets/extensions/gallery/lightbox.css" rel="stylesheet" type="text/css" />
|
437
|
+
# <img src="images/mission_48.png" />
|
438
|
+
def absolutize_page(content, base_url, current_url_parent)
|
439
|
+
modified_content = ""
|
440
|
+
content.each_line do |line|
|
441
|
+
if line =~ /<script\s+.*src=["'']?(.*)["'].*/i then
|
442
|
+
script_src = $1
|
443
|
+
substitute_relative_path_in_src_line(line, script_src, base_url, current_url_parent)
|
444
|
+
elsif line =~ /<link\s+.*href=["'']?(.*)["'].*/i then
|
445
|
+
link_href = $1
|
446
|
+
substitute_relative_path_in_src_line(line, link_href, base_url, current_url_parent)
|
447
|
+
elsif line =~ /<img\s+.*src=["'']?(.*)["'].*/i then
|
448
|
+
img_src = $1
|
449
|
+
substitute_relative_path_in_src_line(line, img_src, base_url, current_url_parent)
|
450
|
+
end
|
451
|
+
|
452
|
+
modified_content += line
|
453
|
+
end
|
454
|
+
return modified_content
|
455
|
+
end
|
456
|
+
|
457
|
+
# absolutize_page referencs using hpricot
|
458
|
+
#
|
459
|
+
def absolutize_page_hpricot(content, base_url, parent_url)
|
460
|
+
return absolutize_page(content, base_url, parent_url) if RUBY_PLATFORM == 'java'
|
461
|
+
begin
|
462
|
+
require 'nokogiri'
|
463
|
+
doc = Nokogiri::HTML(content)
|
464
|
+
base_url.slice!(-1) if ends_with?(base_url, "/")
|
465
|
+
(doc/'link').each { |e| e['href'] = absolutify_url(e['href'], base_url, parent_url) || "" }
|
466
|
+
(doc/'img').each { |e| e['src'] = absolutify_url(e['src'], base_url, parent_url) || "" }
|
467
|
+
(doc/'script').each { |e| e['src'] = absolutify_url(e['src'], base_url, parent_url) || "" }
|
468
|
+
return doc.to_html
|
469
|
+
rescue => e
|
470
|
+
absolutize_page(content, base_url, parent_url)
|
471
|
+
end
|
472
|
+
end
|
473
|
+
|
474
|
+
##
|
475
|
+
# change
|
476
|
+
# <script type="text/javascript" src="/javascripts/prototype.js"></script>
|
477
|
+
# to
|
478
|
+
# <script type="text/javascript" src="http://itest2.com/javascripts/prototype.js"></script>
|
479
|
+
def absolutify_url(src, base_url, parent_url)
|
480
|
+
if src.nil? || src.empty? || src == "//:" || src =~ /\s*http:\/\//i
|
481
|
+
return src
|
482
|
+
end
|
483
|
+
|
484
|
+
return "#{base_url}#{src}" if src =~ /^\s*\//
|
485
|
+
return "#{parent_url}#{src}" if parent_url
|
486
|
+
return src
|
487
|
+
end
|
488
|
+
|
489
|
+
# substut
|
490
|
+
def substitute_relative_path_in_src_line(line, script_src, host_url, page_parent_url)
|
491
|
+
unless script_src =~ /^["']?http:/
|
492
|
+
host_url.slice!(-1) if ends_with?(host_url, "/")
|
493
|
+
if script_src =~ /^\s*\// # absolute_path
|
494
|
+
line.gsub!(script_src, "#{host_url}#{script_src}")
|
495
|
+
else #relative_path
|
496
|
+
line.gsub!(script_src, "#{page_parent_url}#{script_src}")
|
497
|
+
end
|
498
|
+
end
|
499
|
+
end
|
500
|
+
|
501
|
+
def ends_with?(str, suffix)
|
502
|
+
suffix = suffix.to_s
|
503
|
+
str[-suffix.length, suffix.length] == suffix
|
504
|
+
end
|
505
|
+
|
506
|
+
# current web page title
|
507
|
+
def page_title
|
508
|
+
@web_browser.page_title
|
509
|
+
end
|
510
|
+
|
511
|
+
# current page source (in HTML)
|
512
|
+
def page_source
|
513
|
+
@web_browser.page_source
|
514
|
+
end
|
515
|
+
|
516
|
+
# return plain text view of page
|
517
|
+
def page_text
|
518
|
+
@web_browser.text
|
519
|
+
end
|
520
|
+
|
521
|
+
# return the text of specific (identified by attribute "id") label tag
|
522
|
+
# For page containing
|
523
|
+
# <label id="preferred_ide">TestWise</label>
|
524
|
+
# label_with_id("preferred_ids") # => TestWise
|
525
|
+
# label_with_id("preferred_ids", :index => 2) # => TestWise
|
526
|
+
def label_with_id(label_id, options = {})
|
527
|
+
if options && options[:index] then
|
528
|
+
elements = find_elements(:id, label_id.to_s)
|
529
|
+
elements[options[:index].to_i - 1].text
|
530
|
+
# label(:id => label_id.to_s, :index => options[:index]).text
|
531
|
+
else
|
532
|
+
find_element(:id, label_id.to_s).text
|
533
|
+
end
|
534
|
+
end
|
535
|
+
|
536
|
+
# return the text of specific (identified by attribute "id") span tag
|
537
|
+
# For page containing
|
538
|
+
# <span id="preferred_recorder">iTest2/Watir Recorder</span>
|
539
|
+
# span_with_id("preferred_recorder") # => iTest2/Watir Recorder
|
540
|
+
def span_with_id(span_id, options = {})
|
541
|
+
if options && options[:index] then
|
542
|
+
elements = find_elements(:id, span_id.to_s)
|
543
|
+
elements[options[:index].to_i - 1].text
|
544
|
+
else
|
545
|
+
find_element(:id, span_id.to_s).text
|
546
|
+
end
|
547
|
+
end
|
548
|
+
|
549
|
+
# return the text of specific (identified by attribute "id") ta tag
|
550
|
+
# For page containing
|
551
|
+
# <td id="preferred_recorder">iTest2/Watir Recorder</span>
|
552
|
+
# td_with_id("preferred_recorder") # => iTest2/Watir Recorder
|
553
|
+
def cell_with_id(cell_id, options = {})
|
554
|
+
if options && options[:index] then
|
555
|
+
elements = find_elements(:id, cell_id.to_s)
|
556
|
+
elements[options[:index].to_i - 1].text
|
557
|
+
else
|
558
|
+
find_element(:id, cell_id.to_s).text
|
559
|
+
end
|
560
|
+
end
|
561
|
+
alias table_data_with_id cell_with_id
|
562
|
+
|
563
|
+
|
564
|
+
def is_mac?
|
565
|
+
RUBY_PLATFORM.downcase.include?("darwin")
|
566
|
+
end
|
567
|
+
|
568
|
+
def is_windows?
|
569
|
+
RUBY_PLATFORM.downcase.include?("mswin") or RUBY_PLATFORM.downcase.include?("mingw")
|
570
|
+
end
|
571
|
+
|
572
|
+
def is_linux?
|
573
|
+
RUBY_PLATFORM.downcase.include?("linux")
|
574
|
+
end
|
575
|
+
|
576
|
+
# Support browser (IE) operations using unicode
|
577
|
+
# Example:
|
578
|
+
# click_button("Google 搜索")
|
579
|
+
# Reference: http://jira.openqa.org/browse/WTR-219
|
580
|
+
def support_utf8
|
581
|
+
if is_windows?
|
582
|
+
require 'win32ole'
|
583
|
+
WIN32OLE.codepage = WIN32OLE::CP_UTF8
|
584
|
+
end
|
585
|
+
end
|
586
|
+
|
587
|
+
alias support_unicode support_utf8
|
588
|
+
|
589
|
+
#= Convenient functions
|
590
|
+
#
|
591
|
+
|
592
|
+
# Using Ruby block syntax to create interesting domain specific language,
|
593
|
+
# may be appeal to someone.
|
594
|
+
|
595
|
+
# Example:
|
596
|
+
# on @page do |i|
|
597
|
+
# i.enter_text('btn1')
|
598
|
+
# i.click_button('btn1')
|
599
|
+
# end
|
600
|
+
def on(page, & block)
|
601
|
+
yield page
|
602
|
+
end
|
603
|
+
|
604
|
+
# fail the test if user can perform the operation
|
605
|
+
#
|
606
|
+
# Example:
|
607
|
+
# shall_not_allow { 1/0 }
|
608
|
+
def shall_not_allow(& block)
|
609
|
+
operation_performed_ok = false
|
610
|
+
begin
|
611
|
+
yield
|
612
|
+
operation_performed_ok = true
|
613
|
+
rescue
|
614
|
+
end
|
615
|
+
raise "Operation shall not be allowed" if operation_performed_ok
|
616
|
+
end
|
617
|
+
|
618
|
+
alias do_not_allow shall_not_allow
|
619
|
+
|
620
|
+
# Does not provide real function, other than make enhancing test syntax
|
621
|
+
#
|
622
|
+
# Example:
|
623
|
+
# allow { click_button('Register') }
|
624
|
+
def allow(& block)
|
625
|
+
yield
|
626
|
+
end
|
627
|
+
|
628
|
+
alias shall_allow allow
|
629
|
+
alias allowing allow
|
630
|
+
|
631
|
+
# try operation, ignore if errors occur
|
632
|
+
#
|
633
|
+
# Example:
|
634
|
+
# failsafe { click_link("Logout") } # try logout, but it still OK if not being able to (already logout))
|
635
|
+
def failsafe(& block)
|
636
|
+
begin
|
637
|
+
yield
|
638
|
+
rescue =>e
|
639
|
+
end
|
640
|
+
end
|
641
|
+
|
642
|
+
alias fail_safe failsafe
|
643
|
+
|
644
|
+
|
645
|
+
# Execute the provided block until either (1) it returns true, or
|
646
|
+
# (2) the timeout (in seconds) has been reached. If the timeout is reached,
|
647
|
+
# a TimeOutException will be raised. The block will always
|
648
|
+
# execute at least once.
|
649
|
+
#
|
650
|
+
# This does not handle error, if the given block raise error, the statement finish with error
|
651
|
+
# Examples:
|
652
|
+
# wait_until {puts 'hello'}
|
653
|
+
# wait_until { div(:id, :receipt_date).exists? }
|
654
|
+
#
|
655
|
+
def wait_until(timeout = @@default_timeout || 30, polling_interval = @@default_polling_interval || 1, & block)
|
656
|
+
end_time = ::Time.now + timeout
|
657
|
+
|
658
|
+
until ::Time.now > end_time
|
659
|
+
result = nil
|
660
|
+
begin
|
661
|
+
result = yield(self)
|
662
|
+
return result if result
|
663
|
+
rescue => e
|
664
|
+
end
|
665
|
+
sleep polling_interval
|
666
|
+
end
|
667
|
+
|
668
|
+
raise TimeoutError, "timed out after #{timeout} seconds"
|
669
|
+
end
|
670
|
+
|
671
|
+
# Wait for specific seconds for an Ajax update finish.
|
672
|
+
# Trick: In your Rails application,
|
673
|
+
# :loading => "Element.show('search_indicator');
|
674
|
+
# :complete => "Element.hide('search_indicator');
|
675
|
+
#
|
676
|
+
# <%= image_tag("indicator.gif", :id => 'search_indicator', :style => 'display:none') %>
|
677
|
+
#
|
678
|
+
# Typical usage:
|
679
|
+
# ajax_wait_for_element("search_indicator", 30)
|
680
|
+
# ajax_wait_for_element("search_indicator", 30, "show")
|
681
|
+
# ajax_wait_for_element("search_indicator", 30, "hide")
|
682
|
+
# ajax_wait_for_element("search_indicator", 30, "show", 5) # check every 5 seconds
|
683
|
+
#
|
684
|
+
# Warning: this method has not been fully tested, if you are not using Rails, change your parameter accordingly.
|
685
|
+
#
|
686
|
+
def ajax_wait_for_element(element_id, seconds, status='show', check_interval = @@default_polling_interval)
|
687
|
+
count = 0
|
688
|
+
check_interval = 1 if check_interval < 1 or check_interval > seconds
|
689
|
+
while count < (seconds / check_interval) do
|
690
|
+
search_indicator = @web_browser.element_by_id(element_id)
|
691
|
+
search_indicator_outer_html = search_indicator.outerHtml if search_indicator
|
692
|
+
if status == 'hide'
|
693
|
+
return true if search_indicator_outer_html and !search_indicator_outer_html.include?('style="DISPLAY: none"')
|
694
|
+
else
|
695
|
+
return true if search_indicator_outer_html and search_indicator_outer_html.include?('style="DISPLAY: none"')
|
696
|
+
end
|
697
|
+
sleep check_interval if check_interval > 0 and check_interval < 5 * 60 # wait max 5 minutes
|
698
|
+
count += 1
|
699
|
+
end
|
700
|
+
return false
|
701
|
+
end
|
702
|
+
|
703
|
+
#Wait the element with given id to be present in web page
|
704
|
+
#
|
705
|
+
# Warning: this not working in Firefox, try use wait_util or try instead
|
706
|
+
def wait_for_element(element_id, timeout = @@default_timeout, interval = @@default_polling_interval)
|
707
|
+
start_time = Time.now
|
708
|
+
#TODO might not work with Firefox
|
709
|
+
until @web_browser.element_by_id(element_id) do
|
710
|
+
sleep(interval)
|
711
|
+
if (Time.now - start_time) > timeout
|
712
|
+
raise RuntimeError, "failed to find element: #{element_id} for max #{timeout}"
|
713
|
+
end
|
714
|
+
end
|
715
|
+
end
|
716
|
+
|
717
|
+
=begin
|
718
|
+
|
719
|
+
# TODO: Firewatir does not suport retrieving style or outerHtml
|
720
|
+
# http://jira.openqa.org/browse/WTR-260
|
721
|
+
# http://code.google.com/p/firewatir/issues/detail?id=76
|
722
|
+
#
|
723
|
+
# Max timeout value is 10 minutes
|
724
|
+
#
|
725
|
+
def ajax_call_complete_after_element_hidden(elem_id, check_start = 0.5, timeout = 5, interval = 0.5, &block)
|
726
|
+
yield
|
727
|
+
sleep check_start # the time allowed to perform the coomplete
|
728
|
+
timeout = 10 * 60 if timeout > 10 * 600 or timeout <= 0
|
729
|
+
begin
|
730
|
+
Timeout::timeout(timeout) {
|
731
|
+
begin
|
732
|
+
elem = element_by_id(elem_id)
|
733
|
+
while elem do
|
734
|
+
puts "outer=>#{elem.outerHtml}|"
|
735
|
+
puts "style =>#{elem.attribute_value('style')}|"
|
736
|
+
sleep interval
|
737
|
+
elem = element_by_id(elem_id)
|
738
|
+
end
|
739
|
+
rescue => e
|
740
|
+
puts e
|
741
|
+
end
|
742
|
+
}
|
743
|
+
rescue Timeout::Error
|
744
|
+
# Too slow!!
|
745
|
+
raise "Too slow, wait max #{timeout} seconds, the element #{elem_id} still there"
|
746
|
+
end
|
747
|
+
end
|
748
|
+
|
749
|
+
=end
|
750
|
+
|
751
|
+
# Try the operation up to specified times, and sleep given interval (in seconds)
|
752
|
+
# Error will be ignored until timeout
|
753
|
+
# Example
|
754
|
+
# repeat_try(3, 2) { click_button('Search' } # 3 times, 6 seconds in total
|
755
|
+
# repeat_try { click_button('Search' } # using default 5 tries, 2 second interval
|
756
|
+
def repeat_try(num_tries = @@default_timeout || 30, interval = @@default_polling_interval || 1, & block)
|
757
|
+
num_tries ||= 1
|
758
|
+
(num_tries - 1).times do |num|
|
759
|
+
begin
|
760
|
+
yield
|
761
|
+
return
|
762
|
+
rescue => e
|
763
|
+
# puts "debug: #{num} failed: #{e}"
|
764
|
+
sleep interval
|
765
|
+
end
|
766
|
+
end
|
767
|
+
|
768
|
+
# last try, throw error if still fails
|
769
|
+
begin
|
770
|
+
yield
|
771
|
+
rescue => e
|
772
|
+
raise e.to_s + " after trying #{num_tries} times every #{interval} seconds"
|
773
|
+
end
|
774
|
+
yield
|
775
|
+
end
|
776
|
+
|
777
|
+
# TODO: syntax
|
778
|
+
|
779
|
+
# Try the operation up to specified timeout (in seconds), and sleep given interval (in seconds).
|
780
|
+
# Error will be ignored until timeout
|
781
|
+
# Example
|
782
|
+
# try { click_link('waiting')}
|
783
|
+
# try(10, 2) { click_button('Search' } # try to click the 'Search' button upto 10 seconds, try every 2 seconds
|
784
|
+
# try { click_button('Search' }
|
785
|
+
def try(timeout = @@default_timeout, polling_interval = @@default_polling_interval || 1, & block)
|
786
|
+
start_time = Time.now
|
787
|
+
|
788
|
+
last_error = nil
|
789
|
+
until (duration = Time.now - start_time) > timeout
|
790
|
+
begin
|
791
|
+
return if yield
|
792
|
+
last_error = nil
|
793
|
+
rescue => e
|
794
|
+
last_error = e
|
795
|
+
end
|
796
|
+
sleep polling_interval
|
797
|
+
end
|
798
|
+
|
799
|
+
raise "Timeout after #{duration.to_i} seconds with error: #{last_error}." if last_error
|
800
|
+
raise "Timeout after #{duration.to_i} seconds."
|
801
|
+
end
|
802
|
+
|
803
|
+
alias try_upto try
|
804
|
+
|
805
|
+
##
|
806
|
+
# Convert :first to 1, :second to 2, and so on...
|
807
|
+
def symbol_to_sequence(symb)
|
808
|
+
value = {:zero => 0,
|
809
|
+
:first => 1,
|
810
|
+
:second => 2,
|
811
|
+
:third => 3,
|
812
|
+
:fourth => 4,
|
813
|
+
:fifth => 5,
|
814
|
+
:sixth => 6,
|
815
|
+
:seventh => 7,
|
816
|
+
:eighth => 8,
|
817
|
+
:ninth => 9,
|
818
|
+
:tenth => 10}[symb]
|
819
|
+
return value || symb.to_i
|
820
|
+
end
|
821
|
+
|
822
|
+
# Clear popup windows such as 'Security Alert' or 'Security Information' popup window,
|
823
|
+
#
|
824
|
+
# Screenshot see http://kb2.adobe.com/cps/165/tn_16588.html
|
825
|
+
#
|
826
|
+
# You can also by pass security alerts by change IE setting, http://kb.iu.edu/data/amuj.html
|
827
|
+
#
|
828
|
+
# Example
|
829
|
+
# clear_popup("Security Information", 5, true) # check for Security Information for 5 seconds, click Yes
|
830
|
+
def clear_popup(popup_win_title, seconds = 10, yes = true)
|
831
|
+
# commonly "Security Alert", "Security Information"
|
832
|
+
if is_windows?
|
833
|
+
sleep 1
|
834
|
+
autoit = WIN32OLE.new('AutoItX3.Control')
|
835
|
+
# Look for window with given title. Give up after 1 second.
|
836
|
+
ret = autoit.WinWait(popup_win_title, '', seconds)
|
837
|
+
#
|
838
|
+
# If window found, send appropriate keystroke (e.g. {enter}, {Y}, {N}).
|
839
|
+
if ret == 1 then
|
840
|
+
puts "about to send click Yes" if debugging?
|
841
|
+
button_id = yes ? "Button1" : "Button2" # Yes or No
|
842
|
+
autoit.ControlClick(popup_win_title, '', button_id)
|
843
|
+
end
|
844
|
+
sleep(0.5)
|
845
|
+
else
|
846
|
+
raise "Currently supported only on Windows"
|
847
|
+
end
|
848
|
+
end
|
849
|
+
|
850
|
+
def select_file_for_upload(file_field_name, file_path)
|
851
|
+
=begin
|
852
|
+
if is_windows?
|
853
|
+
normalized_file_path = file_path.gsub("/", "\\")
|
854
|
+
if $support_ie8 && check_ie_version && @ie_version >= 8
|
855
|
+
# puts "IE8"
|
856
|
+
file_field(:name, file_field).set(normalized_file_path)
|
857
|
+
# choose_file_dialog(normalized_file_path)
|
858
|
+
else
|
859
|
+
file_field(:name, file_field).set(normalized_file_path)
|
860
|
+
end
|
861
|
+
else
|
862
|
+
# for firefox, just call file_field, it may fail
|
863
|
+
file_field(:name, file_field).set(normalized_file_path)
|
864
|
+
end
|
865
|
+
=end
|
866
|
+
elem = find_element(:name, file_field_name)
|
867
|
+
elem.send_keys(file_path)
|
868
|
+
end
|
869
|
+
|
870
|
+
def choose_file_dialog(file_path)
|
871
|
+
Watir.autoit.WinWaitActive("Choose File to Upload", '', 10)
|
872
|
+
Watir.autoit.ControlSetText("Choose File to Upload", "", 1148, file_path)
|
873
|
+
Watir.autoit.ControlClick("Choose File to Upload", "", "&Open")
|
874
|
+
end
|
875
|
+
|
876
|
+
def check_ie_version
|
877
|
+
if is_windows? && @ie_version.nil?
|
878
|
+
begin
|
879
|
+
cmd = 'reg query "HKLM\SOFTWARE\Microsoft\Internet Explorer" /v Version';
|
880
|
+
result = `#{cmd}`
|
881
|
+
version_line = nil
|
882
|
+
result.each do |line|
|
883
|
+
if (line =~ /Version\s+REG_SZ\s+([\d\.]+)/)
|
884
|
+
version_line = $1
|
885
|
+
end
|
886
|
+
end
|
887
|
+
|
888
|
+
if version_line =~ /^\s*(\d+)\./
|
889
|
+
@ie_version = $1.to_i
|
890
|
+
end
|
891
|
+
rescue => e
|
892
|
+
end
|
893
|
+
end
|
894
|
+
end
|
895
|
+
|
896
|
+
# Use AutoIT3 to send password
|
897
|
+
# title starts with "Connect to ..."
|
898
|
+
def basic_authentication_ie(title, username, password, options = {})
|
899
|
+
default_options = {:textctrl_username => "Edit2",
|
900
|
+
:textctrl_password => "Edit3",
|
901
|
+
:button_ok => 'Button1'
|
902
|
+
}
|
903
|
+
|
904
|
+
options = default_options.merge(options)
|
905
|
+
|
906
|
+
title ||= ""
|
907
|
+
if title =~ /^Connect\sto/
|
908
|
+
full_title = title
|
909
|
+
else
|
910
|
+
full_title = "Connect to #{title}"
|
911
|
+
end
|
912
|
+
require 'rformspec'
|
913
|
+
login_win = RFormSpec::Window.new(full_title)
|
914
|
+
login_win.send_control_text(options[:textctrl_username], username)
|
915
|
+
login_win.send_control_text(options[:textctrl_password], password)
|
916
|
+
login_win.click_button("OK")
|
917
|
+
end
|
918
|
+
|
919
|
+
# Use JSSH to pass authentication
|
920
|
+
# Window title "Authentication required"
|
921
|
+
def basic_authentication_firefox(username, password, wait = 3)
|
922
|
+
jssh_command = "
|
923
|
+
var length = getWindows().length;
|
924
|
+
var win;
|
925
|
+
var found = false;
|
926
|
+
for (var i = 0; i < length; i++) {
|
927
|
+
win = getWindows()[i];
|
928
|
+
if(win.document.title == \"Authentication Required\") {
|
929
|
+
found = true;
|
930
|
+
break;
|
931
|
+
}
|
932
|
+
}
|
933
|
+
if (found) {
|
934
|
+
var jsdocument = win.document;
|
935
|
+
var dialog = jsdocument.getElementsByTagName(\"dialog\")[0];
|
936
|
+
jsdocument.getElementsByTagName(\"textbox\")[0].value = \"#{username}\";
|
937
|
+
jsdocument.getElementsByTagName(\"textbox\")[1].value = \"#{password}\";
|
938
|
+
dialog.getButton(\"accept\").click();
|
939
|
+
}
|
940
|
+
\n"
|
941
|
+
sleep(wait)
|
942
|
+
$jssh_socket.send(jssh_command, 0)
|
943
|
+
# read_socket()
|
944
|
+
end
|
945
|
+
|
946
|
+
def basic_authentication_celerity(username, password)
|
947
|
+
@web_browser.celerity.credentials = "#{username}:#{password}"
|
948
|
+
end
|
949
|
+
|
950
|
+
def basic_authentication(username, password, options = {})
|
951
|
+
if is_celerity?
|
952
|
+
basic_authentication_celerity(username, password)
|
953
|
+
elsif is_firefox?
|
954
|
+
basic_authentication_firefox(username, password)
|
955
|
+
else
|
956
|
+
basic_authentication_ie(options[:title], username, password, options)
|
957
|
+
end
|
958
|
+
end
|
959
|
+
|
960
|
+
# take_screenshot to save the current active window
|
961
|
+
# TODO can't move mouse
|
962
|
+
def take_screenshot_old
|
963
|
+
if is_windows? && $ITEST2_DUMP_PAGE
|
964
|
+
begin
|
965
|
+
puts "[DEBUG] Capturing screenshots..."
|
966
|
+
screenshot_image_filename = "rwebspec_" + Time.now.strftime("%m%d%H%M%S") + ".jpg"
|
967
|
+
the_dump_dir = default_dump_dir
|
968
|
+
FileUtils.mkdir_p(the_dump_dir) unless File.exists?(the_dump_dir)
|
969
|
+
screenshot_image_filepath = File.join(the_dump_dir, screenshot_image_filename)
|
970
|
+
|
971
|
+
screenshot_image_filepath.gsub!("/", "\\") if is_windows?
|
972
|
+
screen_capture(screenshot_image_filepath, true)
|
973
|
+
|
974
|
+
notify_screenshot_location(screenshot_image_filepath)
|
975
|
+
rescue
|
976
|
+
puts "error: #{Failed to capture screen}"
|
977
|
+
end
|
978
|
+
end
|
979
|
+
end
|
980
|
+
|
981
|
+
|
982
|
+
# use win32screenshot library to save curernt active window, which shall be IE
|
983
|
+
#
|
984
|
+
def take_screenshot
|
985
|
+
if $testwise_screenshot_supported && is_windows?
|
986
|
+
begin
|
987
|
+
screenshot_image_filename = "screenshot_" + Time.now.strftime("%m%d%H%M%S") + ".jpg"
|
988
|
+
the_dump_dir = default_dump_dir
|
989
|
+
FileUtils.mkdir_p(the_dump_dir) unless File.exists?(the_dump_dir)
|
990
|
+
screenshot_image_filepath = File.join(the_dump_dir, screenshot_image_filename)
|
991
|
+
screenshot_image_filepath.gsub!("/", "\\") if is_windows?
|
992
|
+
|
993
|
+
FileUtils.rm_f(screenshot_image_filepath) if File.exist?(screenshot_image_filepath)
|
994
|
+
|
995
|
+
case @web_browser.underlying_browser.browser
|
996
|
+
when :internet_explorer
|
997
|
+
Win32::Screenshot::Take.of(:window, :title => /internet\sexplorer/i).write(screenshot_image_filepath)
|
998
|
+
else
|
999
|
+
Win32::Screenshot::Take.of(:foreground).write(screenshot_image_filepath)
|
1000
|
+
end
|
1001
|
+
notify_screenshot_location(screenshot_image_filepath)
|
1002
|
+
rescue => e
|
1003
|
+
puts "error on taking screenshot: #{e}"
|
1004
|
+
end
|
1005
|
+
end
|
1006
|
+
end
|
1007
|
+
|
1008
|
+
end
|
1009
|
+
|
1010
|
+
end
|
1011
|
+
end
|