awetestlib 0.1.2 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/README.md +55 -0
  2. data/awetestlib.windows.gemspec +1 -1
  3. data/awetestlib_osx.gemspec +1 -0
  4. data/bin/AutoItX3.dll +0 -0
  5. data/bin/awetestlib +23 -3
  6. data/bin/awetestlib-helpers.rb +39 -0
  7. data/bin/awetestlib-netbeans-setup.rb +39 -0
  8. data/bin/awetestlib-regression-setup.rb +16 -0
  9. data/bin/awetestlib-rubymine-setup.rb +33 -0
  10. data/images/logo.png +0 -0
  11. data/lib/awetestlib.rb +4 -4
  12. data/lib/awetestlib/html_report.rb +171 -0
  13. data/lib/{regression → awetestlib}/logging.rb +13 -46
  14. data/lib/awetestlib/regression/browser.rb +1233 -0
  15. data/lib/awetestlib/regression/drag_and_drop.rb +379 -0
  16. data/lib/awetestlib/regression/find.rb +431 -0
  17. data/lib/awetestlib/regression/legacy.rb +45 -0
  18. data/lib/awetestlib/regression/page_data.rb +190 -0
  19. data/lib/awetestlib/regression/runner.rb +307 -0
  20. data/lib/awetestlib/regression/tables.rb +491 -0
  21. data/lib/awetestlib/regression/user_input.rb +1256 -0
  22. data/lib/awetestlib/regression/utilities.rb +895 -0
  23. data/lib/awetestlib/regression/validations.rb +1184 -0
  24. data/lib/awetestlib/regression/waits.rb +391 -0
  25. data/lib/awetestlib/runner.rb +16 -0
  26. data/lib/version.rb +2 -2
  27. data/setup_samples/sample_netbeans/demo.rb +86 -0
  28. data/setup_samples/sample_netbeans/nbproject/configs/Demo.properties +2 -0
  29. data/setup_samples/sample_netbeans/nbproject/private/config.properties +1 -0
  30. data/setup_samples/sample_netbeans/nbproject/private/configs/Demo.properties +1 -0
  31. data/setup_samples/sample_netbeans/nbproject/private/private.properties +2 -0
  32. data/setup_samples/sample_netbeans/nbproject/project.properties +5 -0
  33. data/setup_samples/sample_netbeans/nbproject/project.xml +13 -0
  34. data/setup_samples/sample_rubymine/.idea/.name +1 -0
  35. data/setup_samples/sample_rubymine/.idea/encodings.xml +5 -0
  36. data/setup_samples/sample_rubymine/.idea/misc.xml +5 -0
  37. data/setup_samples/sample_rubymine/.idea/modules.xml +9 -0
  38. data/setup_samples/sample_rubymine/.idea/sample_rubymine.iml +9 -0
  39. data/setup_samples/sample_rubymine/.idea/scopes/scope_settings.xml +5 -0
  40. data/setup_samples/sample_rubymine/.idea/vcs.xml +7 -0
  41. data/setup_samples/sample_rubymine/.idea/workspace.xml +213 -0
  42. data/setup_samples/sample_rubymine/demo.rb +86 -0
  43. metadata +64 -17
  44. data/lib/regression/browser.rb +0 -1259
  45. data/lib/regression/drag_and_drop.rb +0 -374
  46. data/lib/regression/find.rb +0 -426
  47. data/lib/regression/legacy.rb +0 -40
  48. data/lib/regression/page_data.rb +0 -185
  49. data/lib/regression/runner.rb +0 -278
  50. data/lib/regression/tables.rb +0 -486
  51. data/lib/regression/user_input.rb +0 -1255
  52. data/lib/regression/utilities.rb +0 -891
  53. data/lib/regression/validations.rb +0 -1179
  54. data/lib/regression/waits.rb +0 -387
@@ -1,891 +0,0 @@
1
- module Utilities
2
-
3
- # Place holder to prevent method not found error in scripts
4
- def set_script_variables
5
- # TODO: replace with method_missing?
6
- end
7
-
8
- def setup
9
- # if @os_sysname =~ /Windows.+Server\s+2003/
10
- ## 'Microsoft(R) Windows(R) Server 2003, Enterprise Edition'
11
- # @vertical_hack_ie = 110
12
- # @vertical_hack_ff = 138
13
- # @horizontal_hack_ie = 5
14
- # @horizontal_hack_ff = 4
15
- # elsif @os_sysname =~ /Windows XP Professional/
16
- # 'Microsoft Windows XP Professional'
17
- @vertical_hack_ie = 118
18
- @vertical_hack_ff = 144
19
- @horizontal_hack_ie = 5
20
- @horizontal_hack_ff = 4
21
- #end
22
-
23
- @settings_display_ids = Hash[
24
- "Currency" => "row-currencyName",
25
- "Description" => "row-description",
26
- "Tx Date" => "row-fmtDate",
27
- "Total" => "row-amount",
28
- "[currencyCode]" => "row-currencyCode",
29
- "Date in Millis" => "row-dateInMilliseconds",
30
- ]
31
- @column_data_display_ids = Hash[
32
- "Currency" => "yui-dt0-th-currencyName",
33
- "Description" => "yui-dt0-th-description",
34
- "Tx Date" => "yui-dt0-th-fmtDate",
35
- "Total" => "yui-dt0-th-fmtDate",
36
- "[currencyCode]" => "yui-dt0-th-currencyCode",
37
- "Date in Millis" => "yui-dt0-th-dateInMilliseconds",
38
- ]
39
- @settings_panel_index = 0
40
- @x_tolerance = 4
41
- @y_tolerance = 4
42
- end
43
-
44
- def get_trace(lnbr)
45
- callertrace = "\nCaller trace: (#{lnbr})\n"
46
- Kernel.caller.each_index do |x|
47
- callertrace << ' >> ' + Kernel.caller[x].to_s + "\n"
48
- end
49
- callertrace
50
- end
51
-
52
- alias dump_caller get_trace
53
-
54
- def get_mdyy(t = Time.now)
55
- "#{t.month}/#{t.day}/#{t.year}"
56
- end
57
-
58
- def get_prefix(strg, offset)
59
- a_slice = strg.slice(0, offset)
60
- a_slice.downcase
61
- end
62
-
63
- def get_timestamp(format = 'long', offset = nil, offset_unit = :years)
64
- t = DateTime.now
65
- if offset
66
- t = t.advance(offset_unit => offset)
67
- end
68
- case format
69
- when 'dateonly'
70
- t.strftime("%m/%d/%Y")
71
- when 'condensed'
72
- t.strftime("%Y%m%d%H%M")
73
- when 'condensed_seconds'
74
- t.strftime("%Y%m%d%H%M%S")
75
- when 'long'
76
- t.strftime("%m/%d/%Y %I:%M %p")
77
- when 'mdyy'
78
- get_mdyy(t)
79
- when 'm/d/y'
80
- get_mdyy(t)
81
- else
82
- Time.now.strftime("%m/%d/%Y %H:%M:%S")
83
- end
84
- end
85
-
86
- def calc_index(index, every = 1)
87
- (index / every) + (every - 1)
88
- end
89
-
90
- def get_variables(file, login = :role, dbg = true)
91
- debug_to_log("#{__method__}: file = #{file}")
92
- debug_to_log("#{__method__}: role = #{login}")
93
-
94
- @var = Hash.new
95
- workbook = Excel.new(file)
96
- data_index = find_sheet_with_name(workbook, 'Data')
97
- workbook.default_sheet = workbook.sheets[data_index]
98
- var_col = 0
99
-
100
- 2.upto(workbook.last_column) do |col|
101
- scriptName = workbook.cell(1, col)
102
- if scriptName == @myName
103
- var_col = col
104
- break
105
- end
106
- end
107
-
108
- 2.upto(workbook.last_row) do |line|
109
- name = workbook.cell(line, 'A')
110
- value = workbook.cell(line, var_col).to_s.strip
111
- @var[name] = value
112
- end
113
-
114
- @var.keys.sort.each do |name|
115
- message_tolog("@var #{name}: '#{@var[name]}'")
116
- end if dbg
117
-
118
- @login = Hash.new
119
- login_col = 0
120
- role_col = 0
121
- userid_col = 0
122
- password_col = 0
123
- url_col = 0
124
- name_col = 0
125
- role_index = find_sheet_with_name(workbook, 'Login')
126
- if role_index >= 0
127
- workbook.default_sheet = workbook.sheets[role_index]
128
-
129
- 1.upto(workbook.last_column) do |col|
130
- a_cell = workbook.cell(1, col)
131
- case a_cell
132
- when @myName
133
- login_col = col
134
- break
135
- when 'role'
136
- role_col = col
137
- when 'userid'
138
- userid_col = col
139
- when 'password'
140
- password_col = col
141
- when 'url'
142
- url_col = col
143
- when 'name'
144
- name_col = col
145
- end
146
- end
147
-
148
- 2.upto(workbook.last_row) do |line|
149
- role = workbook.cell(line, role_col)
150
- userid = workbook.cell(line, userid_col)
151
- password = workbook.cell(line, password_col)
152
- url = workbook.cell(line, url_col)
153
- username = workbook.cell(line, name_col)
154
- enabled = workbook.cell(line, login_col).to_s
155
-
156
- case login
157
- when :id
158
- key = userid
159
- when :role
160
- key = role
161
- else
162
- key = role
163
- end
164
-
165
- @login[key] = Hash.new
166
- @login[key]['role'] = role
167
- @login[key]['userid'] = userid
168
- @login[key]['password'] = password
169
- @login[key]['url'] = url
170
- @login[key]['name'] = username
171
- @login[key]['enabled'] = enabled
172
-
173
- end
174
-
175
- @login.keys.sort.each do |key|
176
- message_tolog("@login (by #{login}): #{key}=>'#{@login[key].to_yaml}'")
177
- end if dbg
178
- end
179
-
180
- rescue
181
- fatal_to_log("#{__method__}: '#{$!}'")
182
- end
183
-
184
- def translate_var_list(key)
185
- if @var[key] and @var[key].length > 0
186
- list = @var[key].dup
187
- unless list =~ /^\[.+\]$/
188
- list = "[#{list}]"
189
- end
190
- eval(list)
191
- end
192
- rescue
193
- failed_to_log("#{__method__}: '#{$!}'")
194
- end
195
-
196
- def grab_window_list(strg)
197
- @ai.AutoItSetOption("WinTitleMatchMode", 2)
198
- list = @ai.WinList(strg)
199
- stuff = ''
200
- names = list[0]
201
- handles = list[1]
202
- max = names.length - 1
203
- rng = Range.new(0, max)
204
- rng.each do |idx|
205
- window_handle = "[HANDLE:#{handles[idx]}]"
206
- full_text = @ai.WinGetText(window_handle)
207
- stuff << "[#{handles[idx]}]=>#{names[idx]}=>'#{full_text}'\n"
208
- end
209
- debug_to_log("\n#{stuff}")
210
- @ai.AutoItSetOption("WinTitleMatchMode", 1)
211
- stuff
212
- end
213
-
214
- def debug_call_list(msg)
215
- call_array = get_call_array
216
- debug_to_log("#{msg}\n#{dump_array(call_array)}")
217
- end
218
-
219
- def sec2hms(s)
220
- Time.at(s.to_i).gmtime.strftime('%H:%M:%S')
221
- end
222
-
223
- def close_log(scriptName, lnbr = '')
224
- cmplTS = Time.now.to_f.to_s
225
- puts ("#{scriptName} finished. Closing log. #{lnbr.to_s}")
226
- passed_to_log("#{scriptName} run complete [#{cmplTS}]")
227
- @myLog.close()
228
- sleep(2)
229
- end
230
-
231
- protected :close_log
232
-
233
- def find_sheet_with_name(workbook, sheet_name)
234
- sheets = workbook.sheets
235
- idx = 0
236
- found = false
237
- sheets.each do |s|
238
- if s == sheet_name
239
- found = true
240
- break
241
- end
242
- idx += 1
243
- end
244
- if found
245
- idx
246
- else
247
- -1
248
- end
249
- end
250
-
251
- def nice_array(arr, space_to_underscore = false)
252
- new_arr = Array.new
253
- if space_to_underscore
254
- arr.each do |nty|
255
- new_arr << nty.gsub(/\s/, '_')
256
- end
257
- else
258
- new_arr = arr
259
- end
260
- "['#{new_arr.join("','")}']"
261
- end
262
-
263
- def string_count_in_string(strg, substrg)
264
- count = strg.scan(substrg).length
265
- count
266
- end
267
-
268
- def rescue_me(e, me = nil, what = nil, where = nil, who = nil)
269
- #TODO: these are rescues from exceptions raised in Watir/Firewatir
270
- debug_to_log("#{__method__}: Begin rescue")
271
- ok = false
272
- begin
273
- gaak = who.inspect
274
- located = gaak =~ /located=true/i
275
- rescue
276
- debug_to_log("#{__method__}: gaak: '#{gaak}'")
277
- end
278
- msg = e.message
279
- debug_to_log("#{__method__}: msg = #{msg}")
280
- if msg =~ /undefined method\s+.join.\s+for/i # firewatir to_s implementation error
281
- ok = true
282
- elsif msg =~ /undefined method\s+.match.\s+for.+WIN32OLERuntimeError/i # watir and firewatir
283
- ok = true
284
- elsif msg =~ /undefined method\s+.match.\s+for.+UnknownObjectException/i # watir
285
- ok = true
286
- elsif msg =~ /window\.getBrowser is not a function/i # firewatir
287
- ok = true
288
- elsif msg =~ /WIN32OLERuntimeError/i # watir
289
- ok = true
290
- elsif msg =~ /undefined method\s+.match.\s+for/i # watir
291
- ok = true
292
- elsif msg =~ /wrong number of arguments \(1 for 0\)/i
293
- ok = true
294
- elsif (msg =~ /unable to locate element/i)
295
- if located
296
- ok = true
297
- elsif where == 'Watir::Div'
298
- ok = true
299
- end
300
- elsif (msg =~ /HRESULT error code:0x80070005/)
301
- ok = true
302
- #elsif msg =~ /missing\s+\;\s+before statement/
303
- # ok = true
304
- end
305
- if ok
306
- debug_to_log("#{__method__}: RESCUED: \n#{who.to_yaml}=> #{what} in #{me}()\n=> '#{$!}'")
307
- debug_to_log("#{__method__}: #{who.inspect}") if who
308
- debug_to_log("#{__method__}: #{where.inspect}")
309
- debug_to_log("#{__method__}: #{get_callers(6, true)}")
310
- else
311
- debug_to_log("#{__method__}: NO RESCUE: #{e.message}")
312
- debug_to_log("#{__method__}: NO RESCUE: \n#{get_callers(6, true)}")
313
- end
314
- debug_to_log("#{__method__}: Exit")
315
- ok
316
- end
317
-
318
- def get_caller_line
319
- last_caller = get_callers[0]
320
- line = last_caller.split(':', 3)[1]
321
- line
322
- end
323
-
324
- def get_call_list(depth = 9, dbg = false)
325
- myList = []
326
- call_list = Kernel.caller
327
- puts call_list if dbg
328
- call_list.each_index do |x|
329
- myCaller = call_list[x].to_s
330
- break if x > depth or myCaller =~ /:in .run.$/
331
- myCaller =~ /([\(\)\w_\_\-\.]+\:\d+\:?.*?)$/
332
- myList << "[#{$1.gsub(/eval/, @myName)}] "
333
- end
334
- myList
335
- end
336
-
337
- alias get_callers get_call_list
338
-
339
- def get_call_list_new(depth = 9, dbg = false)
340
- myList = []
341
- call_list = Kernel.caller
342
- puts call_list if dbg
343
- call_list.each_index do |x|
344
- myCaller = call_list[x].to_s
345
- break if x > depth or myCaller =~ /:in .run.$/
346
- if myCaller.include? @myName
347
- myCaller =~ /([\(\)\w_\_\-\.]+\:\d+\:?.*?)$/
348
- myList << "[#{$1.gsub(/eval/, @myName)}] "
349
- break
350
- end
351
- end
352
- if @projName
353
- call_list.each_index do |x|
354
- myCaller = call_list[x].to_s
355
- break if x > depth or myCaller =~ /:in .run.$/
356
- if myCaller.include? @projName
357
- myCaller =~ /([\(\)\w_\_\-\.]+\:\d+\:?.*?)$/
358
- myList << "[#{$1.gsub(/eval/, @projName)}] "
359
- break
360
- end
361
- end
362
- end
363
- myList
364
- end
365
-
366
- def get_call_array(depth = 9)
367
- arr = []
368
- call_list = Kernel.caller
369
- call_list.each_index do |x|
370
- myCaller = call_list[x].to_s
371
- break if x > depth or myCaller =~ /:in .run.$/
372
- myCaller =~ /([\(\)\w_\_\-\.]+\:\d+\:?.*?)$/
373
- arr << $1.gsub(/eval/, @myName)
374
- end
375
- arr
376
- end
377
-
378
- def get_debug_list(dbg = false)
379
- calls = get_call_array(10)
380
- puts "#{calls.to_yaml}" if dbg
381
- arr = []
382
- calls.each_index do |ix|
383
- if ix > 1 # skip this method and the logging method
384
- arr << calls[ix]
385
- end
386
- end
387
- puts "#{arr.to_yaml}" if dbg
388
- if arr.length > 0
389
- list = 'TRACE:'
390
- arr.reverse.each { |l| list << "=>#{l}" }
391
- " [[#{list}]]"
392
- else
393
- nil
394
- end
395
- end
396
-
397
- def dump_array(arr, space_to_underscore = false)
398
- dump = " #{arr.inspect}\n"
399
- arr.each_index do |x|
400
- value = arr[x].to_s
401
- value.gsub!(/\s/, '_') if space_to_underscore
402
- dump << " #{x.to_s.rjust(5)}>> '#{arr[x].to_s}'\n"
403
- end
404
- dump
405
- end
406
-
407
- def dump_ole_methods(ole)
408
- rtrn = ''
409
- ole.ole_methods.each do |m|
410
- prms = ''
411
- m.params.each do |p|
412
- prms << "#{p}, "
413
- end
414
- rtrn << "#{m.name}(#{prms.chop.chop})\n"
415
- end
416
- rtrn
417
- end
418
-
419
- def dump_ole_get_methods(ole)
420
- rtrn = ''
421
- ole.ole_get_methods.each do |m|
422
- prms = ''
423
- m.params.each do |p|
424
- prms << "#{p}, "
425
- end
426
- rtrn << "#{m.name}(#{prms.chop.chop})\n"
427
- end
428
- rtrn
429
- end
430
-
431
- def dump_ole_help(ole)
432
- rtrn = ''
433
- ole.ole_obj_help.each do |m|
434
- prms = ''
435
- m.params.each do |p|
436
- prms << "#{p}, "
437
- end
438
- rtrn << "#{m.name}(#{prms.chop.chop})\n"
439
- end
440
- rtrn
441
- end
442
-
443
- def dump_select_list_options(element)
444
- msg = "#{element.inspect}"
445
- options = element.options
446
- cnt = 1
447
- options.each do |o|
448
- msg << "\n\t#{cnt}:\t'#{o}"
449
- cnt += 1
450
- end
451
- debug_to_log(msg)
452
- end
453
-
454
- def dump_all_tables(browser, to_report = false)
455
- tables = browser.tables
456
- msg = ''
457
- tbl_cnt = 0
458
- tables.each do |tbl|
459
- tbl_cnt += 1
460
- row_cnt = 0
461
- msg <<"\n=================\ntable: #{tbl_cnt}\n=================\n#{tbl}\ntext:\n#{tbl.text}"
462
- tbl.rows.each do |row|
463
- row_cnt += 1
464
- cell_cnt = 0
465
- msg <<"\n=================\ntable: #{tbl_cnt} row: #{row_cnt}\n#{row.inspect}\n#{row}\ntext:'#{row.text}'"
466
- row.each do |cell|
467
- cell_cnt += 1
468
- msg <<"\ncell: #{cell_cnt}\n#{cell.inspect}\n#{row}\ntext: '#{cell.text}'"
469
- end
470
- end
471
- end
472
- if to_report
473
- debug_to_report(msg)
474
- else
475
- debug_to_log(msg)
476
- end
477
- end
478
-
479
- def dump_table_and_rows(table, to_report = false)
480
- msg = "\n=================\ntable\n=================\nn#{table}\n#{table.to_yaml}\nrows:"
481
- cnt = 0
482
- table.rows.each do |r|
483
- cnt += 1
484
- msg << "\n#{cnt}: #{r.text}"
485
- end
486
- msg << "\n=================\n================="
487
- if to_report
488
- debug_to_report(msg)
489
- else
490
- debug_to_log(msg)
491
- end
492
- end
493
-
494
- def dump_table_rows_and_cells(tbl)
495
- msg = ''
496
- row_cnt = 0
497
- msg <<"\n=================\ntable: #{tbl.inspect}\n=================\n#{tbl}\ntext:\n#{tbl.text}"
498
- tbl.rows.each do |row|
499
- row_cnt += 1
500
- cell_cnt = 0
501
- msg <<"\n=================\nrow: #{row_cnt}\n#{row.inspect}\n#{row}\ntext:'#{row.text}'"
502
- row.each do |cell|
503
- cell_cnt += 1
504
- msg <<"\ncell: #{cell_cnt}\n#{cell.inspect}\n#{row}\ntext: '#{cell.text}'"
505
- end
506
- end
507
- debug_to_log(msg)
508
- end
509
-
510
- alias dump_table_rows dump_table_rows_and_cells
511
-
512
- def dump_row_cells(row)
513
- msg = ''
514
- cell_cnt = 0
515
- msg <<"\n=================\nrow: #{row.inspect}\n#{row}\ntext:'#{row.text}'"
516
- row.each do |cell|
517
- cell_cnt += 1
518
- msg <<"\ncell: #{cell_cnt}\n#{cell.inspect}\n#{row}\ntext: '#{cell.text}'"
519
- end
520
- debug_to_log(msg)
521
- end
522
-
523
- def parse_cookies(browser)
524
- cookies = Hash.new
525
- strg = browser.document.cookie
526
- ary = strg.split(';')
527
- ary.each do |c|
528
- key, value = c.split('=')
529
- cookies[key.lstrip] = value
530
- end
531
- cookies
532
- end
533
-
534
- def capture_screen(browser, ts)
535
- browser.maximize
536
- browser.bring_to_front
537
- caller = get_caller
538
- caller.match(/:(\d+):/)
539
- lnbr = $1
540
- path = "#{@myRoot}/screenshot/"
541
- screenfile = "#{@myName}_#{@myRun.id}_#{lnbr.to_s}_#{ts.to_f.to_s}.scrsht.jpg"
542
- info_to_log("path:#{path} screenfile:#{screenfile}")
543
- screenSpec = '"' + path + screenfile + '"'
544
- screenSpec.gsub!('/', '\\')
545
- screen_capture(screenSpec)
546
- screenfile
547
- end
548
-
549
- def pdf_to_text(file, noblank = true)
550
- spec = file.sub(/\.pdf$/, '')
551
- `pdftotext #{spec}.pdf`
552
- file = File.new("#{spec}.txt")
553
- text = []
554
- file.readlines.each do |l|
555
- l.chomp! if noblank
556
- if l.length > 0
557
- text << l
558
- end
559
- end
560
- file.close
561
- text
562
- end
563
-
564
- def flash_id(browser, strg, count)
565
- msg = "Flash link id='#{strg}' #{count} times."
566
- msg << " #{desc}" if desc.length > 0
567
- browser.link(:id, strg).flash(count)
568
- if validate(browser, @myName, __LINE__)
569
- passed_to_log(msg)
570
- true
571
- end
572
- rescue
573
- failed_to_log("Unable to #{msg} '#{$!}'")
574
- end
575
-
576
- def flash(element, count = 4)
577
- element.flash(count)
578
- debug_to_log("'#{element.inspect}' flashed #{count} times.")
579
- true
580
- rescue
581
- debug_to_log("Flash '#{element.inspect}' failed: '#{$!}' (#{__LINE__})")
582
- end
583
-
584
- def get_save_file_path(root, filename)
585
- filespec = "#{root}/file/#{filename}"
586
- filespec.gsub!('/', '\\')
587
- end
588
-
589
- def save_file_orig(filepath, desc = '', wait = WAIT)
590
- # title = translate_popup_title(title)
591
- @ai.WinWait("File Download", "", wait)
592
- @ai.ControlFocus("File Download", "", "&Save")
593
- sleep 1
594
- @ai.ControlClick("File Download", "", "&Save", "left")
595
- @ai.WinWait("Save As", "", wait)
596
- sleep 1
597
- @ai.ControlSend("Save As", "", "Edit1", filepath)
598
- @ai.ControlClick("Save As", "", "&Save", "left")
599
- sleep 1
600
- @ai.WinWait("Download complete", "", wait)
601
- @ai.ControlClick("Download complete", "", "Close")
602
- end
603
-
604
- #TODO This and save_file2 have to be combined somehow.
605
- def save_file1(filepath, title = "File Download", desc = '', wait = WAIT)
606
- title = translate_popup_title(title)
607
- @ai.WinWait(title, '', wait)
608
- @ai.WinActivate(title, '')
609
- sleep 1
610
- @ai.ControlFocus(title, "", "&Save")
611
- sleep 3
612
- @ai.ControlClick(title, "", "&Save", "primary")
613
- sleep 2
614
- @ai.ControlClick(title, "", "Save", "primary")
615
-
616
- @ai.WinWait("Save As", "", wait)
617
- sleep 1
618
- @ai.ControlSend("Save As", "", "Edit1", filepath)
619
- @ai.ControlFocus("Save As", "", "&Save")
620
- @ai.ControlClick("Save As", "", "&Save", "primary")
621
- @ai.ControlClick("Save As", "", "Save", "primary")
622
-
623
- @ai.WinWait("Download complete", "", wait)
624
- passed_to_log("Save file '#{filepath}' succeeded. #{desc}")
625
- @ai.ControlClick("Download complete", "", "Close")
626
- rescue
627
- failed_to_log("Save file failed: #{desc} '#{$!}'. (#{__LINE__})")
628
- end
629
-
630
- def save_file2(filepath, title = "File Download - Security Warning", desc = '', wait = WAIT)
631
- title = translate_popup_title(title)
632
- sleep(1)
633
- @ai.WinWait(title, '', wait)
634
- dl_hndl = @ai.WinGetHandle(title, '')
635
- dl_sv_hndl = @ai.ControlGetHandle(title, '', "&Save")
636
- @ai.WinActivate(title, '')
637
- sleep 1
638
- @ai.ControlFocus(title, "", "&Save")
639
- sleep 1
640
- @ai.ControlFocus(title, "", "Save")
641
- sleep 1
642
- @ai.ControlClick(title, "", "&Save", "primary")
643
- sleep 1
644
- @ai.ControlClick(title, "", "Save", "primary")
645
- sleep 1
646
- w = WinClicker.new
647
- w.clickButtonWithHandle(dl_sv_hndl)
648
- sleep 1
649
- w.clickWindowsButton_hwnd(dl_hndl, "Save")
650
- sleep 1
651
- w.clickWindowsButton_hwnd(dl_hndl, "&Save")
652
-
653
- @ai.WinWait("Save As", "", wait)
654
- sleep 1
655
- @ai.ControlSend("Save As", "", "Edit1", filepath)
656
- @ai.ControlFocus("Save As", "", "&Save")
657
- @ai.ControlClick("Save As", "", "&Save", "primary")
658
-
659
- @ai.WinWait("Download complete", "", wait)
660
- passed_to_log("Save file '#{filepath}' succeeded. #{desc}")
661
- @ai.ControlClick("Download complete", "", "Close")
662
- rescue
663
- failed_to_log("Save file failed: #{desc} '#{$!}'. (#{__LINE__})")
664
- end
665
-
666
- #method for handling save dialog
667
- #use click_no_wait on the action that triggers the save dialog
668
- def save_file(filepath, download_title = "File Download - Security Warning")
669
- # TODO need version for Firefox
670
- # TODO need to handle first character underline, e.g. 'Cancel' and '&Cancel'
671
- download_title = translate_popup_title(download_title)
672
- download_text = ''
673
- download_control = "&Save"
674
- saveas_title = 'Save As'
675
- saveas_text = ''
676
- saveas_control = "Edit1"
677
- dnld_cmplt_title = "Download Complete"
678
- dnld_cmplt_title = translate_popup_title(dnld_cmplt_title)
679
- dnld_cmplt_text = ""
680
- # save_title = ""
681
- side = 'primary'
682
- msgdl = "Window '#{download_title}':"
683
- msgsa = "Window '#{saveas_title}':"
684
- msgdc = "Window '#{dnld_cmplt_title}':"
685
- begin
686
- if @ai.WinWait(download_title, download_text, WAIT)
687
- @ai.WinActivate(download_title, download_text)
688
- if @ai.WinActive(download_title, download_text)
689
- dl_title = @ai.WinGetTitle(download_title, download_text)
690
- # dl_hndl = @ai.WinGetHandle(download_title, download_text)
691
- # dl_text = @ai.WinGetText(download_title, download_text)
692
- # dl_sv_hndl = @ai.ControlGetHandle(dl_title, '', download_control)
693
- # dl_op_hndl = @ai.ControlGetHandle(dl_title, '', '&Open')
694
- # dl_cn_hndl = @ai.ControlGetHandle(dl_title, '', 'Cancel')
695
- debug_to_log("#{msgdl} activated. (#{__LINE__})")
696
-
697
- if @ai.ControlFocus(dl_title, download_text, download_control)
698
- debug_to_log("#{msgdl} focus gained. (#{__LINE__})")
699
-
700
- @ai.Send("S")
701
- # @ai.ControlSend(dl_Stitle, download_text, download_control, "{ENTER}")
702
- sleep_for 1
703
-
704
- if @ai.ControlClick(dl_title, download_text, download_control, side)
705
- debug_to_log("#{msgdl} click succeeded on '#{download_control}'. (#{__LINE__})")
706
-
707
- if @ai.WinWait(saveas_title, saveas_text, WAIT)
708
- debug_to_log("#{msgsa} appeared. (#{__LINE__})")
709
- sleep_for 1
710
- if @ai.ControlSend(saveas_title, saveas_text, saveas_control, filepath)
711
- debug_to_log("#{msgsa} controlsend of '#{saveas_control}' succeeded. (#{__LINE__})")
712
-
713
- @ai.Send("S")
714
- @ai.ControlSend(saveas_title, saveas_text, saveas_control, "{ENTER}")
715
- sleep_for 1
716
-
717
- if @ai.ControlClick(saveas_title, saveas_text, saveas_control, side)
718
- passed_to_log("#{msgsa} click succeeded on '#{saveas_control}'. (#{__LINE__})")
719
- if @ai.WinWait(dnld_cmplt_title, dnld_cmplt_text, WAIT)
720
- debug_to_log("#{msgdc} appeared. (#{__LINE__})")
721
- sleep_for 1
722
- if @ai.ControlClick(dnld_cmplt_title, dnld_cmplt_text, "Close", side)
723
- passed_to_log("Save file for #{filepath} succeeded.")
724
- else
725
- failed_to_log("#{msgdc} click failed on 'Close'. (#{__LINE__})")
726
- end
727
- else
728
- failed_to_log("#{msgdc} did not appear after #{WAIT} seconds. (#{__LINE__})")
729
- end
730
- else
731
- failed_to_log("#{msgsa} click failed on '#{saveas_control}'. (#{__LINE__})")
732
- end
733
- else
734
- failed_to_log("#{msgsa} controlsend of '#{saveas_control}' failed. (#{__LINE__})")
735
- end
736
- else
737
- failed_to_log("#{msgsa} did not appear after #{WAIT} seconds. (#{__LINE__})")
738
- end
739
- else
740
- failed_to_log("#{msgdl} click failed on '#{download_control}'. (#{__LINE__})")
741
- end
742
- else
743
- failed_to_log("#{msgdl} Unable to gain focus on control '#{dl_title}'. (#{__LINE__})")
744
- end
745
- else
746
- failed_to_log("#{msgdl} Unable to activate. (#{__LINE__})")
747
- end
748
- else
749
- failed_to_log("#{msgdl} did not appear after #{WAIT} seconds. (#{__LINE__})")
750
- end
751
- rescue
752
- failed_to_log("Save file failed: '#{$!}'. (#{__LINE__})")
753
- end
754
- end
755
-
756
- #method for cancelling Print window
757
- # TODO need to handle 'Cancel' and '&Cancel' (first character underlined)
758
- def close_print(title = 'Print', text = '', button = '&Cancel', side = 'left')
759
- msg = "Popup: title=#{title} button='#{button}' text='#{text}' side='#{side}':"
760
- if @ai.WinWait(title, text, WAIT)
761
- passed_to_log("#{msg} found.")
762
- @ai.WinActivate(title)
763
- if @ai.WinActive(title, text)
764
- passed_to_log("#{msg} activated.")
765
- if @ai.ControlFocus(title, text, button)
766
- passed_to_log("#{msg} focus attained.")
767
- if @ai.ControlClick(title, text, button, side)
768
- passed_to_log("#{msg} closed successfully.")
769
- else
770
- failed_to_log("#{msg} click failed on button (#{__LINE__})")
771
- end
772
- else
773
- failed_to_log("#{msg} Unable to gain focus on button (#{__LINE__})")
774
- end
775
- else
776
- failed_to_log("#{msg} Unable to activate (#{__LINE__})")
777
- end
778
- else
779
- failed_to_log("#{msg} did not appear after #{WAIT} seconds. (#{__LINE__})")
780
- end
781
- rescue
782
- failed_to_log("Close #{msg}: '#{$!}'. (#{__LINE__})")
783
- end
784
-
785
- #method for handling file download dialog
786
- #use click_no_wait on the action that triggers the save dialog
787
- # TODO need version for Firefox
788
- # TODO need to handle 'Cancel' and '&Cancel' (first character underlined)
789
- # TODO replace call to close_modal_ie with actual file download
790
- def file_download(browser = nil)
791
- title = 'File Download'
792
- title = translate_popup_title(title)
793
- text = ''
794
- button = 'Cancel'
795
- if @browserAbbrev == 'IE'
796
- close_popup(title, button, text)
797
- else
798
-
799
- end
800
- end
801
-
802
- #method for handling file upload dialog
803
- #use click_no_wait on the action that triggers the save dialog
804
- # TODO need version for Firefox
805
- def file_upload(filepath)
806
- title = 'Choose File'
807
- title = translate_popup_title(title)
808
- text = ''
809
- button = "&Open"
810
- control = "Edit1"
811
- side = 'primary'
812
- msg = "Window title=#{title} button='#{button}' text='#{text}' side='#{side}':"
813
- begin
814
- if @ai.WinWait(title, text, WAIT)
815
- passed_to_log("#{msg} found.")
816
- @ai.WinActivate(title, text)
817
- if @ai.WinActive(title, text)
818
- passed_to_log("#{msg} activated.")
819
- if @ai.ControlSend(title, text, control, filepath)
820
- passed_to_log("#{msg} #{control} command sent.")
821
- sleep_for 1
822
- if @ai.ControlClick(title, text, button, "primary")
823
- passed_to_log("#{msg} Upload of #{filepath} succeeded.")
824
- else
825
- failed_to_log("#{msg} Upload of #{filepath} failed. (#{__LINE__})")
826
- end
827
- else
828
- failed_to_log("#{msg} Unable to select #{filepath}. (#{__LINE__})")
829
- end
830
- else
831
- failed_to_log("#{msg} Unable to activate. (#{__LINE__})")
832
- end
833
- else
834
- failed_to_log("#{msg} did not appear after #{WAIT} seconds. (#{__LINE__})")
835
- end
836
- rescue
837
- failed_to_log("#{msg} Unable to upload: '#{$!}'. (#{__LINE__})")
838
- end
839
-
840
- end
841
-
842
- def upload_file(data_path)
843
- limit = 180 # .seconds
844
- Timeout::timeout(limit) {
845
- wait = 20
846
- @ai.WinWait("Choose File to Upload", "", wait)
847
- sleep 1
848
- @ai.ControlSend("Choose File to Upload", "", "Edit1", data_path)
849
- @ai.ControlClick("Choose File to Upload", "", "[CLASS:Button; INSTANCE:2]", "left")
850
- sleep 4
851
- #sleep 1
852
- }
853
- failed_to_log("Choose File to Upload not found after #{limit} '#{$!}'")
854
- rescue Timeout::Error
855
- failed_to_log("File Upload timeout after #{limit} '#{$!}'")
856
- end
857
-
858
- def focus_on_textfield_by_id(browser, strg, desc = '')
859
- msg = "Set focus on textfield name='#{strg}' "
860
- msg << " #{desc}" if desc.length > 0
861
- tf = browser.text_field(:id, strg)
862
- if validate(browser, @myName, __LINE__)
863
- tf.focus
864
- if validate(browser, @myName, __LINE__)
865
- passed_to_log(msg)
866
- true
867
- end
868
- end
869
- rescue
870
- failed_to_log("Unable to #{msg} '#{$!}'")
871
- end
872
-
873
- def flash_text(browser, strg, count, desc = '')
874
- msg = "Flash link text='#{strg}' #{count} times."
875
- msg << " #{desc}" if desc.length > 0
876
- strgCnt = string_count_in_string(browser.text, strg)
877
- if strgCnt > 0
878
- browser.link(:text, strg).flash(count)
879
- if validate(browser, @myName, __LINE__)
880
- passed_to_log(msg)
881
- true
882
- end
883
- else
884
- failed_to_log("#{msg} Link not found.")
885
- end
886
- rescue
887
- failed_to_log("Unable to #{msg} '#{$!}'")
888
- end
889
-
890
-
891
- end