awetestlib 0.1.29pre3 → 0.1.29pre4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. data/README.md +16 -8
  2. data/awetestlib.windows.gemspec +42 -41
  3. data/awetestlib_osx.gemspec +41 -47
  4. data/bin/awetestlib-android-setup.rb +2 -1
  5. data/bin/awetestlib-cucumber-setup.rb +2 -1
  6. data/bin/awetestlib-driver-setup.rb +1 -0
  7. data/bin/awetestlib-helpers.rb +2 -2
  8. data/bin/awetestlib-mobile-app-setup.rb +1 -0
  9. data/bin/awetestlib-netbeans-setup.rb +2 -1
  10. data/bin/awetestlib-regression-setup.rb +26 -12
  11. data/bin/awetestlib-rubymine-setup.rb +9 -4
  12. data/images/netbeans1.jpg +0 -0
  13. data/images/netbeans2.jpg +0 -0
  14. data/images/netbeans3.jpg +0 -0
  15. data/images/netbeans4.jpg +0 -0
  16. data/images/netbeans5.jpg +0 -0
  17. data/images/rubymine1.jpg +0 -0
  18. data/images/rubymine2.jpg +0 -0
  19. data/images/rubymine3.jpg +0 -0
  20. data/images/rubymine4.jpg +0 -0
  21. data/images/scripting1.png +0 -0
  22. data/images/scripting2.png +0 -0
  23. data/images/scripting3.png +0 -0
  24. data/images/scripting4.png +0 -0
  25. data/lib/awetestlib/logging.rb +6 -6
  26. data/lib/awetestlib/regression/browser.rb +15 -12
  27. data/lib/awetestlib/regression/drag_and_drop.rb +421 -421
  28. data/lib/awetestlib/regression/runner.rb +311 -307
  29. data/lib/awetestlib/regression/tables.rb +627 -627
  30. data/lib/awetestlib/regression/user_input.rb +576 -576
  31. data/lib/awetestlib/regression/utilities.rb +1056 -1046
  32. data/lib/awetestlib/regression/validations.rb +2 -1
  33. data/lib/version.rb +2 -2
  34. data/netbeans_setup.md +30 -30
  35. data/rubymine_setup.md +24 -24
  36. data/setup_samples/sample_cucumber/features/step_definitions/predefined_steps.rb +303 -25
  37. metadata +160 -34
  38. checksums.yaml +0 -7
@@ -1,1046 +1,1056 @@
1
- module Awetestlib
2
- module Regression
3
- # Miscellaneous helper methods.
4
- # Includes file save/upload as well as debug methods.
5
- # Rdoc work in progress.
6
- module Utilities
7
-
8
-
9
- # Group by associated DOM object or scripting function?
10
-
11
-
12
- # Place holder to prevent method not found error in scripts
13
- def set_script_variables
14
- # TODO: replace with method_missing?
15
- end
16
-
17
- def setup
18
- # if @os_sysname =~ /Windows.+Server\s+2003/
19
- ## 'Microsoft(R) Windows(R) Server 2003, Enterprise Edition'
20
- # @vertical_hack_ie = 110
21
- # @vertical_hack_ff = 138
22
- # @horizontal_hack_ie = 5
23
- # @horizontal_hack_ff = 4
24
- # elsif @os_sysname =~ /Windows XP Professional/
25
- # 'Microsoft Windows XP Professional'
26
- @vertical_hack_ie = 118
27
- @vertical_hack_ff = 144
28
- @horizontal_hack_ie = 5
29
- @horizontal_hack_ff = 4
30
- #end
31
-
32
- @settings_display_ids = Hash[
33
- "Currency" => "row-currencyName",
34
- "Description" => "row-description",
35
- "Tx Date" => "row-fmtDate",
36
- "Total" => "row-amount",
37
- "[currencyCode]" => "row-currencyCode",
38
- "Date in Millis" => "row-dateInMilliseconds",
39
- ]
40
- @column_data_display_ids = Hash[
41
- "Currency" => "yui-dt0-th-currencyName",
42
- "Description" => "yui-dt0-th-description",
43
- "Tx Date" => "yui-dt0-th-fmtDate",
44
- "Total" => "yui-dt0-th-fmtDate",
45
- "[currencyCode]" => "yui-dt0-th-currencyCode",
46
- "Date in Millis" => "yui-dt0-th-dateInMilliseconds",
47
- ]
48
- @settings_panel_index = 0
49
- @x_tolerance = 4
50
- @y_tolerance = 4
51
- end
52
-
53
- def build_message(strg1, desc = '', strg2 = '', strg3 = '', strg4 = '')
54
- msg = "#{strg1}"
55
- msg << " #{desc}" if desc and desc.length > 0
56
- msg << " #{strg2}" if strg2 and strg2.length > 0
57
- msg << " #{strg3}" if strg3 and strg3.length > 0
58
- msg << " #{strg4}" if strg4 and strg4.length > 0
59
- msg
60
- end
61
-
62
- def get_date_names(date = Date.today)
63
- this_month = date.month
64
- if this_month == 12
65
- next_month = 1
66
- else
67
- next_month = this_month + 1
68
- end
69
- if this_month == 1
70
- prev_month = 12
71
- else
72
- prev_month = this_month - 1
73
- end
74
-
75
- month_arr = ['', 'January', 'February', 'March', 'April', 'May', 'June',
76
- 'July', 'August', 'September', 'October', 'November', 'December']
77
-
78
- this_month_name = month_arr[this_month]
79
- next_month_name = month_arr[next_month]
80
- prev_month_name = month_arr[prev_month]
81
-
82
- arr = [date.year, date.day, this_month_name, next_month_name, prev_month_name]
83
- debug_to_log("#{__method__} #{nice_array(arr)}")
84
- arr
85
- end
86
-
87
- def get_trace(lnbr)
88
- callertrace = "\nCaller trace: (#{lnbr})\n"
89
- Kernel.caller.each_index do |x|
90
- callertrace << ' >> ' + Kernel.caller[x].to_s + "\n"
91
- end
92
- callertrace
93
- end
94
-
95
- alias dump_caller get_trace
96
-
97
- def get_mdyy(t = Time.now)
98
- "#{t.month}/#{t.day}/#{t.year}"
99
- end
100
-
101
- def get_prefix(strg, offset)
102
- a_slice = strg.slice(0, offset)
103
- a_slice.downcase
104
- end
105
-
106
- def get_timestamp(format = 'long', offset = nil, offset_unit = :years)
107
- t = DateTime.now
108
- if offset
109
- t = t.advance(offset_unit => offset)
110
- end
111
- case format
112
- when 'dateonly'
113
- t.strftime("%m/%d/%Y")
114
- when 'condensed'
115
- t.strftime("%Y%m%d%H%M")
116
- when 'condensed_seconds'
117
- t.strftime("%Y%m%d%H%M%S")
118
- when 'long'
119
- t.strftime("%m/%d/%Y %I:%M %p")
120
- when 'mdyy'
121
- get_mdyy(t)
122
- when 'm/d/y'
123
- get_mdyy(t)
124
- else
125
- Time.now.strftime("%m/%d/%Y %H:%M:%S")
126
- end
127
- end
128
-
129
- def calc_index(index, every = 1)
130
- (index / every) + (every - 1)
131
- end
132
-
133
- def get_variables(file, key_type = :role, dbg = true)
134
- #TODO refactor this
135
- debug_to_log("#{__method__}: file = #{file}")
136
- debug_to_log("#{__method__}: key = #{key_type}")
137
-
138
- script_found_in_login = false
139
- script_found_in_data = false
140
-
141
- @var = Hash.new
142
- workbook = Excel.new(file)
143
- data_index = find_sheet_with_name(workbook, 'Data')
144
- workbook.default_sheet = workbook.sheets[data_index]
145
- var_col = 0
146
-
147
- 2.upto(workbook.last_column) do |col|
148
- scriptName = workbook.cell(1, col)
149
- if scriptName == @myName
150
- var_col = col
151
- script_found_in_data = true
152
- break
153
- end
154
- end
155
-
156
- 2.upto(workbook.last_row) do |line|
157
- name = workbook.cell(line, 'A')
158
- value = workbook.cell(line, var_col).to_s.strip
159
- @var[name] = value
160
- end
161
-
162
- @var.keys.sort.each do |name|
163
- message_tolog("@var #{name}: '#{@var[name]}'")
164
- end if dbg
165
-
166
- @login = Hash.new
167
- login_col = 0
168
- role_col = 0
169
- userid_col = 0
170
- password_col = 0
171
- url_col = 0
172
- name_col = 0
173
- login_index = find_sheet_with_name(workbook, 'Login')
174
- if login_index and login_index >= 0
175
- workbook.default_sheet = workbook.sheets[login_index]
176
-
177
- 1.upto(workbook.last_column) do |col|
178
- a_cell = workbook.cell(1, col)
179
- case a_cell
180
- when @myName
181
- login_col = col
182
- script_found_in_login = true
183
- break
184
- when 'role'
185
- role_col = col
186
- when 'userid'
187
- userid_col = col
188
- when 'password'
189
- password_col = col
190
- when 'url'
191
- url_col = col
192
- when 'name'
193
- name_col = col
194
- end
195
- end
196
-
197
- 2.upto(workbook.last_row) do |line|
198
- role = workbook.cell(line, role_col)
199
- userid = workbook.cell(line, userid_col)
200
- password = workbook.cell(line, password_col)
201
- url = workbook.cell(line, url_col)
202
- username = workbook.cell(line, name_col)
203
- enabled = workbook.cell(line, login_col).to_s
204
-
205
- case key_type
206
- when :id, :userid
207
- key = userid
208
- when :role
209
- key = role
210
- else
211
- key = userid
212
- end
213
-
214
- @login[key] = Hash.new
215
- @login[key]['role'] = role
216
- @login[key]['userid'] = userid
217
- @login[key]['password'] = password
218
- @login[key]['url'] = url
219
- @login[key]['name'] = username
220
- @login[key]['enabled'] = enabled
221
-
222
- end
223
-
224
- @login.keys.sort.each do |key|
225
- message_tolog("@login (by #{key_type}): #{key}=>'#{@login[key].to_yaml}'")
226
- end if dbg
227
- end
228
-
229
- if script_found_in_login and script_found_in_data
230
- true
231
- else
232
- failed_to_log("Script found: in Login = #{script_found_in_login}; in Data = #{script_found_in_data}")
233
- end
234
- rescue
235
- failed_to_log("#{__method__}: '#{$!}'")
236
- end
237
-
238
- def translate_var_list(key)
239
- if @var[key] and @var[key].length > 0
240
- list = @var[key].dup
241
- unless list =~ /^\[.+\]$/
242
- list = "[#{list}]"
243
- end
244
- eval(list)
245
- end
246
- rescue
247
- failed_to_log("#{__method__}: '#{$!}'")
248
- end
249
-
250
- def grab_window_list(strg)
251
- @ai.AutoItSetOption("WinTitleMatchMode", 2)
252
- list = @ai.WinList(strg)
253
- stuff = ''
254
- names = list[0]
255
- handles = list[1]
256
- max = names.length - 1
257
- rng = Range.new(0, max)
258
- rng.each do |idx|
259
- window_handle = "[HANDLE:#{handles[idx]}]"
260
- full_text = @ai.WinGetText(window_handle)
261
- stuff << "[#{handles[idx]}]=>#{names[idx]}=>'#{full_text}'\n"
262
- end
263
- debug_to_log("\n#{stuff}")
264
- @ai.AutoItSetOption("WinTitleMatchMode", 1)
265
- stuff
266
- end
267
-
268
- def debug_call_list(msg)
269
- call_array = get_call_array
270
- debug_to_log("#{msg}\n#{dump_array(call_array)}")
271
- end
272
-
273
- def sec2hms(s)
274
- Time.at(s.to_i).gmtime.strftime('%H:%M:%S')
275
- end
276
-
277
- def close_log(scriptName, lnbr = '')
278
- cmplTS = Time.now.to_f.to_s
279
- puts ("#{scriptName} finished. Closing log. #{lnbr.to_s}")
280
- passed_to_log("#{scriptName} run complete [#{cmplTS}]")
281
- @myLog.close()
282
- sleep(2)
283
- end
284
-
285
- protected :close_log
286
-
287
- def find_sheet_with_name(workbook, sheet_name)
288
- sheets = workbook.sheets
289
- idx = 0
290
- found = false
291
- sheets.each do |s|
292
- if s == sheet_name
293
- found = true
294
- break
295
- end
296
- idx += 1
297
- end
298
- if found
299
- idx
300
- else
301
- -1
302
- end
303
- end
304
-
305
- def nice_array(arr, space_to_underscore = false)
306
- new_arr = Array.new
307
- if space_to_underscore
308
- arr.each do |nty|
309
- new_arr << nty.gsub(/\s/, '_')
310
- end
311
- else
312
- new_arr = arr
313
- end
314
- "['#{new_arr.join("', '")}']"
315
- end
316
-
317
- def nice_number(number, decimals = 0, dollars = false)
318
- number.to_s.gsub!(/[,\$]/, '')
319
- ptrn = "%0.#{decimals}f"
320
- ptrn = '$' + ptrn if dollars
321
- sprintf(ptrn, number).gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1,")
322
- end
323
-
324
- def pad_date(dt)
325
- if dt and dt.length > 0
326
- a, d1, b, d2, c = dt.split(/([\/\.-])/)
327
- a = a.rjust(2, '0') unless a and a.length > 1
328
- b = b.rjust(2, '0') unless b and b.length > 1
329
- c = c.rjust(2, '0') unless c and c.length > 1
330
- a + d1 + b + d2 + c
331
- else
332
- ''
333
- end
334
- end
335
-
336
- def string_count_in_string(strg, substrg)
337
- count = strg.scan(substrg).length
338
- count
339
- end
340
-
341
- def strip_regex_mix(strg)
342
- rslt = strg.dup
343
- while match = rslt.match(/(\(\?-mix:(.+)\))/)
344
- rslt.sub!(match[1], "/#{match[2]}/")
345
- end
346
- rslt
347
- end
348
-
349
- def rescue_me(e, me = nil, what = nil, where = nil, who = nil)
350
- #TODO: these are rescues from exceptions raised in Watir/Firewatir
351
- debug_to_log("#{__method__}: Begin rescue")
352
- ok = false
353
- begin
354
- gaak = who.inspect
355
- located = gaak =~ /located=true/i
356
- rescue
357
- debug_to_log("#{__method__}: gaak: '#{gaak}'")
358
- end
359
- msg = e.message
360
- debug_to_log("#{__method__}: msg = #{msg}")
361
- if msg =~ /undefined method\s+.join.\s+for/i # firewatir to_s implementation error
362
- ok = true
363
- elsif msg =~ /undefined method\s+.match.\s+for.+WIN32OLERuntimeError/i # watir and firewatir
364
- ok = true
365
- elsif msg =~ /undefined method\s+.match.\s+for.+UnknownObjectException/i # watir
366
- ok = true
367
- elsif msg =~ /window\.getBrowser is not a function/i # firewatir
368
- ok = true
369
- elsif msg =~ /WIN32OLERuntimeError/i # watir
370
- ok = true
371
- elsif msg =~ /undefined method\s+.match.\s+for/i # watir
372
- ok = true
373
- elsif msg =~ /wrong number of arguments \(1 for 0\)/i
374
- ok = true
375
- elsif (msg =~ /unable to locate element/i)
376
- if located
377
- ok = true
378
- elsif where == 'Watir::Div'
379
- ok = true
380
- end
381
- elsif (msg =~ /HRESULT error code:0x80070005/)
382
- ok = true
383
- #elsif msg =~ /missing\s+\;\s+before statement/
384
- # ok = true
385
- end
386
- if ok
387
- debug_to_log("#{__method__}: RESCUED: \n#{who.to_yaml}=> #{what} in #{me}()\n=> '#{$!}'")
388
- debug_to_log("#{__method__}: #{who.inspect}") if who
389
- debug_to_log("#{__method__}: #{where.inspect}")
390
- debug_to_log("#{__method__}: #{get_callers(6, true)}")
391
- else
392
- debug_to_log("#{__method__}: NO RESCUE: #{e.message}")
393
- debug_to_log("#{__method__}: NO RESCUE: \n#{get_callers(6, true)}")
394
- end
395
- debug_to_log("#{__method__}: Exit")
396
- ok
397
- end
398
-
399
- def get_caller_line
400
- last_caller = get_call_list[0]
401
- line = last_caller.split(':', 3)[1]
402
- line
403
- end
404
-
405
- def get_call_list(depth = 9, dbg = false)
406
- myList = []
407
- call_list = Kernel.caller
408
- puts call_list if dbg
409
- call_list.each_index do |x|
410
- myCaller = call_list[x].to_s
411
- myCaller =~ /([\(\)\w_\_\-\.]+\:\d+\:?.*?)$/
412
- myList << "[#{$1.gsub(/eval/, @myName)}] "
413
- break if x > depth or myCaller =~ /:in .run.$/
414
- end
415
- myList
416
- end
417
-
418
- alias get_callers get_call_list
419
-
420
- def get_call_list_new(depth = 9, dbg = false)
421
- myList = []
422
- call_list = Kernel.caller
423
- puts call_list if dbg
424
- call_list.each_index do |x|
425
- myCaller = call_list[x].to_s
426
- if myCaller.include? @myName
427
- myCaller =~ /([\(\)\w_\_\-\.]+\:\d+\:?.*?)$/
428
- myList << "[#{$1.gsub(/eval/, @myName)}] "
429
- break
430
- end
431
- break if x > depth or myCaller =~ /:in .run.$/
432
- end
433
- if @projName
434
- call_list.each_index do |x|
435
- myCaller = call_list[x].to_s
436
- if myCaller.include? @projName
437
- myCaller =~ /([\(\)\w_\_\-\.]+\:\d+\:?.*?)$/
438
- myList << "[#{$1.gsub(/eval/, @projName)}] "
439
- break
440
- end
441
- end
442
- break if x > depth or myCaller =~ /:in .run.$/
443
- end
444
- myList
445
- end
446
-
447
- def get_call_array(depth = 9)
448
- arr = []
449
- call_list = Kernel.caller
450
- call_list.each_index do |x|
451
- myCaller = call_list[x].to_s
452
- myCaller =~ /([\(\)\w_\_\-\.]+\:\d+\:?.*?)$/
453
- arr << $1.gsub(/eval/, @myName)
454
- break if x > depth or myCaller =~ /:in .run.$/
455
- end
456
- arr
457
- end
458
-
459
- def get_debug_list(dbg = false)
460
- calls = get_call_array(10)
461
- puts "#{calls.to_yaml}" if dbg
462
- arr = []
463
- calls.each_index do |ix|
464
- if ix > 1 # skip this method and the logging method
465
- arr << calls[ix]
466
- end
467
- end
468
- puts "#{arr.to_yaml}" if dbg
469
- if arr.length > 0
470
- list = 'TRACE:'
471
- arr.reverse.each { |l| list << "=>#{l}" }
472
- " [[#{list}]]"
473
- else
474
- nil
475
- end
476
- end
477
-
478
- def dump_array(arr, space_to_underscore = false)
479
- dump = " #{arr.inspect}\n"
480
- arr.each_index do |x|
481
- value = arr[x].to_s
482
- value.gsub!(/\s/, '_') if space_to_underscore
483
- dump << " #{x.to_s.rjust(5)}>> '#{arr[x].to_s}'\n"
484
- end
485
- dump
486
- end
487
-
488
- def dump_ole_methods(ole)
489
- rtrn = ''
490
- ole.ole_methods.each do |m|
491
- prms = ''
492
- m.params.each do |p|
493
- prms << "#{p}, "
494
- end
495
- rtrn << "#{m.name}(#{prms.chop.chop})\n"
496
- end
497
- rtrn
498
- end
499
-
500
- def dump_ole_get_methods(ole)
501
- rtrn = ''
502
- ole.ole_get_methods.each do |m|
503
- prms = ''
504
- m.params.each do |p|
505
- prms << "#{p}, "
506
- end
507
- rtrn << "#{m.name}(#{prms.chop.chop})\n"
508
- end
509
- rtrn
510
- end
511
-
512
- def dump_ole_help(ole)
513
- rtrn = ''
514
- ole.ole_obj_help.each do |m|
515
- prms = ''
516
- m.params.each do |p|
517
- prms << "#{p}, "
518
- end
519
- rtrn << "#{m.name}(#{prms.chop.chop})\n"
520
- end
521
- rtrn
522
- end
523
-
524
- def dump_select_list_options(element, report = false)
525
- msg = "#{element.inspect}"
526
- options = element.options
527
- cnt = 1
528
- options.each do |o|
529
- msg << "\n\t#{cnt}:\t'#{o}"
530
- cnt += 1
531
- end
532
- if report
533
- debug_to_report(msg)
534
- else
535
- debug_to_log(msg)
536
- end
537
- end
538
-
539
- def dump_all_tables(browser, to_report = false)
540
- tables = browser.tables
541
- msg = ''
542
- tbl_cnt = 0
543
- tables.each do |tbl|
544
- tbl_cnt += 1
545
- row_cnt = 0
546
- msg <<"\n=================\ntable: #{tbl_cnt}\n=================\n#{tbl}\ntext:\n#{tbl.text}"
547
- tbl.rows.each do |row|
548
- row_cnt += 1
549
- cell_cnt = 0
550
- msg <<"\n=================\ntable: #{tbl_cnt} row: #{row_cnt}\n#{row.inspect}\n#{row}\ntext:'#{row.text}'"
551
- row.each do |cell|
552
- cell_cnt += 1
553
- msg <<"\ncell: #{cell_cnt}\n#{cell.inspect}\n#{row}\ntext: '#{cell.text}'"
554
- end
555
- end
556
- end
557
- if to_report
558
- debug_to_report(msg)
559
- else
560
- debug_to_log(msg)
561
- end
562
- end
563
-
564
- def dump_table_and_rows(table, to_report = false)
565
- msg = "\n=================\ntable\n=================\nn#{table}\n#{table.to_yaml}\nrows:"
566
- cnt = 0
567
- table.rows.each do |r|
568
- cnt += 1
569
- msg << "\n#{cnt}: #{r.text}"
570
- end
571
- msg << "\n=================\n================="
572
- if to_report
573
- debug_to_report(msg)
574
- else
575
- debug_to_log(msg)
576
- end
577
- end
578
-
579
- def dump_table_rows_and_cells(tbl)
580
- msg = ''
581
- row_cnt = 0
582
- msg <<"\n=================\ntable: #{tbl.inspect}\n=================\n#{tbl}\ntext:\n#{tbl.text}"
583
- tbl.rows.each do |row|
584
- row_cnt += 1
585
- cell_cnt = 0
586
- msg <<"\n=================\nrow: #{row_cnt}\n#{row.inspect}\n#{row}\ntext:'#{row.text}'"
587
- row.each do |cell|
588
- cell_cnt += 1
589
- msg <<"\ncell: #{cell_cnt}\n#{cell.inspect}\n#{row}\ntext: '#{cell.text}'"
590
- end
591
- end
592
- debug_to_log(msg)
593
- end
594
-
595
- alias dump_table_rows dump_table_rows_and_cells
596
-
597
- def dump_row_cells(row)
598
- msg = ''
599
- cell_cnt = 0
600
- msg <<"\n=================\nrow: #{row.inspect}\n#{row}\ntext:'#{row.text}'"
601
- row.each do |cell|
602
- cell_cnt += 1
603
- msg <<"\ncell: #{cell_cnt}\n#{cell.inspect}\n#{row}\ntext: '#{cell.text}'"
604
- end
605
- debug_to_log(msg)
606
- end
607
-
608
- def parse_cookies(browser)
609
- cookies = Hash.new
610
- strg = browser.document.cookie
611
- ary = strg.split(';')
612
- ary.each do |c|
613
- key, value = c.split('=')
614
- cookies[key.lstrip] = value
615
- end
616
- cookies
617
- end
618
-
619
- def capture_screen(browser, ts)
620
- browser.maximize
621
- browser.bring_to_front
622
- caller = get_caller
623
- caller.match(/:(\d+):/)
624
- lnbr = $1
625
- path = "#{@myRoot}/screenshot/"
626
- screenfile = "#{@myName}_#{@myRun.id}_#{lnbr.to_s}_#{ts.to_f.to_s}.scrsht.jpg"
627
- info_to_log("path:#{path} screenfile:#{screenfile}")
628
- screenSpec = '"' + path + screenfile + '"'
629
- screenSpec.gsub!('/', '\\')
630
- screen_capture(screenSpec)
631
- screenfile
632
- end
633
-
634
- def pdf_to_text(file, noblank = true)
635
- spec = file.sub(/\.pdf$/, '')
636
- `pdftotext #{spec}.pdf`
637
- file = File.new("#{spec}.txt")
638
- text = []
639
- file.readlines.each do |l|
640
- l.chomp! if noblank
641
- if l.length > 0
642
- text << l
643
- end
644
- end
645
- file.close
646
- text
647
- end
648
-
649
- # @deprecated
650
- def flash_id(browser, strg, count)
651
- msg = "Flash link id='#{strg}' #{count} times."
652
- msg << " #{desc}" if desc.length > 0
653
- browser.link(:id, strg).flash(count)
654
- passed_to_log(msg)
655
- true
656
- rescue
657
- failed_to_log("Unable to #{msg} '#{$!}'")
658
- end
659
-
660
- def flash(element, count = 4)
661
- element.flash(count)
662
- debug_to_log("'#{element.inspect}' flashed #{count} times.")
663
- true
664
- rescue
665
- debug_to_log("Flash '#{element.inspect}' failed: '#{$!}' (#{__LINE__})")
666
- end
667
-
668
- def get_save_file_path(root, filename)
669
- filespec = "#{root}/file/#{filename}"
670
- filespec.gsub!('/', '\\')
671
- end
672
-
673
- def save_file_orig(filepath, desc = '', wait = WAIT)
674
- # title = translate_popup_title(title)
675
- @ai.WinWait("File Download", "", wait)
676
- @ai.ControlFocus("File Download", "", "&Save")
677
- sleep 1
678
- @ai.ControlClick("File Download", "", "&Save", "left")
679
- @ai.WinWait("Save As", "", wait)
680
- sleep 1
681
- @ai.ControlSend("Save As", "", "Edit1", filepath)
682
- @ai.ControlClick("Save As", "", "&Save", "left")
683
- sleep 1
684
- @ai.WinWait("Download complete", "", wait)
685
- @ai.ControlClick("Download complete", "", "Close")
686
- end
687
-
688
- #TODO This and save_file2 have to be combined somehow.
689
- def save_file1(filepath, title = "File Download", desc = '', wait = WAIT)
690
- title = translate_popup_title(title)
691
- @ai.WinWait(title, '', wait)
692
- @ai.WinActivate(title, '')
693
- sleep 1
694
- @ai.ControlFocus(title, "", "&Save")
695
- sleep 3
696
- @ai.ControlClick(title, "", "&Save", "primary")
697
- sleep 2
698
- @ai.ControlClick(title, "", "Save", "primary")
699
-
700
- @ai.WinWait("Save As", "", wait)
701
- sleep 1
702
- @ai.ControlSend("Save As", "", "Edit1", filepath)
703
- @ai.ControlFocus("Save As", "", "&Save")
704
- @ai.ControlClick("Save As", "", "&Save", "primary")
705
- @ai.ControlClick("Save As", "", "Save", "primary")
706
-
707
- @ai.WinWait("Download complete", "", wait)
708
- passed_to_log("Save file '#{filepath}' succeeded. #{desc}")
709
- @ai.ControlClick("Download complete", "", "Close")
710
- rescue
711
- failed_to_log("Save file failed: #{desc} '#{$!}'. (#{__LINE__})")
712
- end
713
-
714
- def save_file2(filepath, title = "File Download - Security Warning", desc = '', wait = WAIT)
715
- title = translate_popup_title(title)
716
- sleep(1)
717
- @ai.WinWait(title, '', wait)
718
- dl_hndl = @ai.WinGetHandle(title, '')
719
- dl_sv_hndl = @ai.ControlGetHandle(title, '', "&Save")
720
- @ai.WinActivate(title, '')
721
- sleep 1
722
- @ai.ControlFocus(title, "", "&Save")
723
- sleep 1
724
- @ai.ControlFocus(title, "", "Save")
725
- sleep 1
726
- @ai.ControlClick(title, "", "&Save", "primary")
727
- sleep 1
728
- @ai.ControlClick(title, "", "Save", "primary")
729
- sleep 1
730
- w = WinClicker.new
731
- w.clickButtonWithHandle(dl_sv_hndl)
732
- sleep 1
733
- w.clickWindowsButton_hwnd(dl_hndl, "Save")
734
- sleep 1
735
- w.clickWindowsButton_hwnd(dl_hndl, "&Save")
736
-
737
- @ai.WinWait("Save As", "", wait)
738
- sleep 1
739
- @ai.ControlSend("Save As", "", "Edit1", filepath)
740
- @ai.ControlFocus("Save As", "", "&Save")
741
- @ai.ControlClick("Save As", "", "&Save", "primary")
742
-
743
- @ai.WinWait("Download complete", "", wait)
744
- passed_to_log("Save file '#{filepath}' succeeded. #{desc}")
745
- @ai.ControlClick("Download complete", "", "Close")
746
- rescue
747
- failed_to_log("Save file failed: #{desc} '#{$!}'. (#{__LINE__})")
748
- end
749
-
750
- #method for handling save dialog
751
- #use click_no_wait on the action that triggers the save dialog
752
- def save_file(filepath, download_title = "File Download - Security Warning")
753
- # TODO need version for Firefox
754
- # TODO need to handle first character underline, e.g. 'Cancel' and '&Cancel'
755
- download_title = translate_popup_title(download_title)
756
- download_text = ''
757
- download_control = "&Save"
758
- saveas_title = 'Save As'
759
- saveas_text = ''
760
- saveas_control = "Edit1"
761
- dnld_cmplt_title = "Download Complete"
762
- dnld_cmplt_title = translate_popup_title(dnld_cmplt_title)
763
- dnld_cmplt_text = ""
764
- # save_title = ""
765
- side = 'primary'
766
- msgdl = "Window '#{download_title}':"
767
- msgsa = "Window '#{saveas_title}':"
768
- msgdc = "Window '#{dnld_cmplt_title}':"
769
- begin
770
- if @ai.WinWait(download_title, download_text, WAIT)
771
- @ai.WinActivate(download_title, download_text)
772
- if @ai.WinActive(download_title, download_text)
773
- dl_title = @ai.WinGetTitle(download_title, download_text)
774
- # dl_hndl = @ai.WinGetHandle(download_title, download_text)
775
- # dl_text = @ai.WinGetText(download_title, download_text)
776
- # dl_sv_hndl = @ai.ControlGetHandle(dl_title, '', download_control)
777
- # dl_op_hndl = @ai.ControlGetHandle(dl_title, '', '&Open')
778
- # dl_cn_hndl = @ai.ControlGetHandle(dl_title, '', 'Cancel')
779
- debug_to_log("#{msgdl} activated. (#{__LINE__})")
780
-
781
- if @ai.ControlFocus(dl_title, download_text, download_control)
782
- debug_to_log("#{msgdl} focus gained. (#{__LINE__})")
783
-
784
- @ai.Send("S")
785
- # @ai.ControlSend(dl_Stitle, download_text, download_control, "{ENTER}")
786
- sleep_for 1
787
-
788
- if @ai.ControlClick(dl_title, download_text, download_control, side)
789
- debug_to_log("#{msgdl} click succeeded on '#{download_control}'. (#{__LINE__})")
790
-
791
- if @ai.WinWait(saveas_title, saveas_text, WAIT)
792
- debug_to_log("#{msgsa} appeared. (#{__LINE__})")
793
- sleep_for 1
794
- if @ai.ControlSend(saveas_title, saveas_text, saveas_control, filepath)
795
- debug_to_log("#{msgsa} controlsend of '#{saveas_control}' succeeded. (#{__LINE__})")
796
-
797
- @ai.Send("S")
798
- @ai.ControlSend(saveas_title, saveas_text, saveas_control, "{ENTER}")
799
- sleep_for 1
800
-
801
- if @ai.ControlClick(saveas_title, saveas_text, saveas_control, side)
802
- passed_to_log("#{msgsa} click succeeded on '#{saveas_control}'. (#{__LINE__})")
803
- if @ai.WinWait(dnld_cmplt_title, dnld_cmplt_text, WAIT)
804
- debug_to_log("#{msgdc} appeared. (#{__LINE__})")
805
- sleep_for 1
806
- if @ai.ControlClick(dnld_cmplt_title, dnld_cmplt_text, "Close", side)
807
- passed_to_log("Save file for #{filepath} succeeded.")
808
- else
809
- failed_to_log("#{msgdc} click failed on 'Close'. (#{__LINE__})")
810
- end
811
- else
812
- failed_to_log("#{msgdc} did not appear after #{WAIT} seconds. (#{__LINE__})")
813
- end
814
- else
815
- failed_to_log("#{msgsa} click failed on '#{saveas_control}'. (#{__LINE__})")
816
- end
817
- else
818
- failed_to_log("#{msgsa} controlsend of '#{saveas_control}' failed. (#{__LINE__})")
819
- end
820
- else
821
- failed_to_log("#{msgsa} did not appear after #{WAIT} seconds. (#{__LINE__})")
822
- end
823
- else
824
- failed_to_log("#{msgdl} click failed on '#{download_control}'. (#{__LINE__})")
825
- end
826
- else
827
- failed_to_log("#{msgdl} Unable to gain focus on control '#{dl_title}'. (#{__LINE__})")
828
- end
829
- else
830
- failed_to_log("#{msgdl} Unable to activate. (#{__LINE__})")
831
- end
832
- else
833
- failed_to_log("#{msgdl} did not appear after #{WAIT} seconds. (#{__LINE__})")
834
- end
835
- rescue
836
- failed_to_log("Save file failed: '#{$!}'. (#{__LINE__})")
837
- end
838
- end
839
-
840
- #method for cancelling Print window
841
- # TODO need to handle 'Cancel' and '&Cancel' (first character underlined)
842
- def close_print(title = 'Print', text = '', button = '&Cancel', side = 'left')
843
- msg = "Popup: title=#{title} button='#{button}' text='#{text}' side='#{side}':"
844
- if @ai.WinWait(title, text, WAIT)
845
- passed_to_log("#{msg} found.")
846
- @ai.WinActivate(title)
847
- if @ai.WinActive(title, text)
848
- passed_to_log("#{msg} activated.")
849
- if @ai.ControlFocus(title, text, button)
850
- passed_to_log("#{msg} focus attained.")
851
- if @ai.ControlClick(title, text, button, side)
852
- passed_to_log("#{msg} closed successfully.")
853
- else
854
- failed_to_log("#{msg} click failed on button (#{__LINE__})")
855
- end
856
- else
857
- failed_to_log("#{msg} Unable to gain focus on button (#{__LINE__})")
858
- end
859
- else
860
- failed_to_log("#{msg} Unable to activate (#{__LINE__})")
861
- end
862
- else
863
- failed_to_log("#{msg} did not appear after #{WAIT} seconds. (#{__LINE__})")
864
- end
865
- rescue
866
- failed_to_log("Close #{msg}: '#{$!}'. (#{__LINE__})")
867
- end
868
-
869
- #method for handling file download dialog
870
- #use click_no_wait on the action that triggers the save dialog
871
- # TODO need version for Firefox
872
- # TODO need to handle 'Cancel' and '&Cancel' (first character underlined)
873
- # TODO replace call to close_modal_ie with actual file download
874
- def file_download(browser = nil)
875
- title = 'File Download'
876
- title = translate_popup_title(title)
877
- text = ''
878
- button = 'Cancel'
879
- if @browserAbbrev == 'IE'
880
- close_popup(title, button, text)
881
- else
882
-
883
- end
884
- end
885
-
886
- #method for handling file upload dialog
887
- #use click_no_wait on the action that triggers the save dialog
888
- # TODO need version for Firefox
889
- def file_upload(filepath, title = 'Choose File', text = '', button = '&Open',
890
- control = 'Edit1', side = 'primary')
891
- title = translate_popup_title(title)
892
- msg = "Window title=#{title} button='#{button}' text='#{text}' side='#{side}':"
893
- begin
894
- if @ai.WinWait(title, text, WAIT)
895
- passed_to_log("#{msg} found.")
896
- @ai.WinActivate(title, text)
897
- if @ai.WinActive(title, text)
898
- passed_to_log("#{msg} activated.")
899
- if @ai.ControlSend(title, text, control, filepath)
900
- passed_to_log("#{msg} #{control} command sent.")
901
- sleep_for 1
902
- if @ai.ControlClick(title, text, button, "primary")
903
-
904
- passed_to_log("#{msg} Upload of #{filepath} succeeded.")
905
-
906
-
907
- else
908
- failed_to_log("#{msg} Upload of #{filepath} failed. (#{__LINE__})")
909
- end
910
- else
911
- failed_to_log("#{msg} Unable to select #{filepath}. (#{__LINE__})")
912
- end
913
- else
914
- failed_to_log("#{msg} Unable to activate. (#{__LINE__})")
915
- end
916
- else
917
- failed_to_log("#{msg} did not appear after #{WAIT} seconds. (#{__LINE__})")
918
- end
919
- rescue
920
- failed_to_log("#{msg} Unable to upload: '#{$!}'. (#{__LINE__})")
921
- end
922
-
923
- end
924
-
925
- def upload_file(data_path)
926
- limit = 180 # .seconds
927
- Timeout::timeout(limit) {
928
- wait = 20
929
- @ai.WinWait("Choose File to Upload", "", wait)
930
- sleep 1
931
- @ai.ControlSend("Choose File to Upload", "", "Edit1", data_path)
932
- @ai.ControlClick("Choose File to Upload", "", "[CLASS:Button; INSTANCE:2]", "left")
933
- sleep 4
934
- #sleep 1
935
- }
936
- failed_to_log("Choose File to Upload not found after #{limit} '#{$!}'")
937
- rescue Timeout::Error
938
- failed_to_log("File Upload timeout after #{limit} '#{$!}'")
939
- end
940
-
941
- def focus_on_textfield_by_id(browser, strg, desc = '')
942
- msg = "Set focus on textfield name='#{strg}' "
943
- msg << " #{desc}" if desc.length > 0
944
- tf = browser.text_field(:id, strg)
945
- tf.focus
946
- passed_to_log(msg)
947
- true
948
- rescue
949
- failed_to_log("Unable to #{msg} '#{$!}'")
950
- end
951
-
952
- # @deprecated
953
- def flash_text(browser, strg, count, desc = '')
954
- msg = "Flash link text='#{strg}' #{count} times."
955
- msg << " #{desc}" if desc.length > 0
956
- strgCnt = string_count_in_string(browser.text, strg)
957
- if strgCnt > 0
958
- browser.link(:text, strg).flash(count)
959
- passed_to_log(msg)
960
- true
961
- else
962
- failed_to_log("#{msg} Link not found.")
963
- end
964
- rescue
965
- failed_to_log("Unable to #{msg} '#{$!}'")
966
- end
967
-
968
- def do_taskkill(severity, pid)
969
- if pid and pid > 0 and pid < 538976288
970
- info_to_log("Executing taskkill for pid #{pid}")
971
- log_message(severity, %x[taskkill /t /f /pid #{pid}])
972
- end
973
- rescue
974
- error_to_log("#{$!} (#{__LINE__})")
975
- end
976
-
977
- def rescue_me_command(element, how, what, command = nil, param = nil, container = :browser)
978
- loc = "#{container}.#{element}(#{how}, #{what})"
979
- loc << ".#{command}" if command
980
- loc << "(#{param})" if param
981
- loc
982
- end
983
-
984
- def method_to_title(method, no_sub = false)
985
- title = method.to_s.titleize
986
- title.gsub!(/And/, '&') unless no_sub
987
- title
988
- rescue
989
- debug_to_log("#{__method__}: #{method} #{$!}")
990
- end
991
-
992
- def unable_to(message = '', no_dolbang = false, verify_that = false)
993
- call_arr = get_call_array()
994
- call_script, call_line, call_meth = parse_caller(call_arr[1])
995
- strg = "Unable to"
996
- strg << " verify" if verify_that
997
- strg << " #{call_meth.titleize}:"
998
- strg << " #{message}" if message.length > 0
999
- strg << " '#{$!}'" unless no_dolbang
1000
- strg
1001
- end
1002
-
1003
- def parse_caller(caller)
1004
- call_script, call_line, call_meth = caller.split(':')
1005
- call_script.gsub!(/\.rb/, '')
1006
- call_script = call_script.camelize
1007
- call_meth =~ /in .([\w\d_]+)./
1008
- call_meth = $1
1009
- [call_script, call_line, call_meth]
1010
- end
1011
-
1012
- def get_test_level
1013
- arr = []
1014
- each_line = 0
1015
- call_list = Kernel.caller
1016
- #debug_to_log("#{call_list.to_yaml}")
1017
- call_list.each_index do |x|
1018
- myCaller = call_list[x].to_s
1019
- myCaller =~ /([\(\)\w_\_\-\.]+\:\d+\:?.*?)$/
1020
- string = $1
1021
- unless string =~ /logging\.rb|mark_testlevel|mark_test_level|debug_to_report|debug_toreport/
1022
- if string.length > 0
1023
- if string =~ /each|each_key/
1024
- each_line = string.match(/\:(\d+)\:/)[1]
1025
- elsif string.match(/\:(\d+)\:/)[1] == each_line
1026
- next
1027
- else
1028
- arr << string.gsub(/eval/, @myName)
1029
- end
1030
- end
1031
- end
1032
- break if myCaller =~ /:in .run.$|runner\.rb/
1033
- end
1034
- #debug_to_log("#{arr.length} #{nice_array(arr)}")
1035
- [arr.length, arr]
1036
- end
1037
-
1038
- def awetestlib?
1039
- not Awetestlib::Runner.nil?
1040
- rescue
1041
- return false
1042
- end
1043
-
1044
- end
1045
- end
1046
- end
1
+ module Awetestlib
2
+ module Regression
3
+ # Miscellaneous helper methods.
4
+ # Includes file save/upload as well as debug methods.
5
+ # Rdoc work in progress.
6
+ module Utilities
7
+
8
+
9
+ # Group by associated DOM object or scripting function?
10
+
11
+
12
+ # Place holder to prevent method not found error in scripts
13
+ def set_script_variables
14
+ # TODO: replace with method_missing?
15
+ end
16
+
17
+ def setup
18
+ # if @os.name =~ /Windows.+Server\s+2003/
19
+ ## 'Microsoft(R) Windows(R) Server 2003, Enterprise Edition'
20
+ # @vertical_hack_ie = 110
21
+ # @vertical_hack_ff = 138
22
+ # @horizontal_hack_ie = 5
23
+ # @horizontal_hack_ff = 4
24
+ # elsif @os.name =~ /Windows XP Professional/
25
+ # 'Microsoft Windows XP Professional'
26
+ @vertical_hack_ie = 118
27
+ @vertical_hack_ff = 144
28
+ @horizontal_hack_ie = 5
29
+ @horizontal_hack_ff = 4
30
+ #end
31
+
32
+ @settings_display_ids = Hash[
33
+ "Currency" => "row-currencyName",
34
+ "Description" => "row-description",
35
+ "Tx Date" => "row-fmtDate",
36
+ "Total" => "row-amount",
37
+ "[currencyCode]" => "row-currencyCode",
38
+ "Date in Millis" => "row-dateInMilliseconds",
39
+ ]
40
+ @column_data_display_ids = Hash[
41
+ "Currency" => "yui-dt0-th-currencyName",
42
+ "Description" => "yui-dt0-th-description",
43
+ "Tx Date" => "yui-dt0-th-fmtDate",
44
+ "Total" => "yui-dt0-th-fmtDate",
45
+ "[currencyCode]" => "yui-dt0-th-currencyCode",
46
+ "Date in Millis" => "yui-dt0-th-dateInMilliseconds",
47
+ ]
48
+ @settings_panel_index = 0
49
+ @x_tolerance = 4
50
+ @y_tolerance = 4
51
+ end
52
+
53
+ def build_message(strg1, desc = '', strg2 = '', strg3 = '', strg4 = '')
54
+ msg = "#{strg1}"
55
+ msg << " #{desc}" if desc and desc.length > 0
56
+ msg << " #{strg2}" if strg2 and strg2.length > 0
57
+ msg << " #{strg3}" if strg3 and strg3.length > 0
58
+ msg << " #{strg4}" if strg4 and strg4.length > 0
59
+ msg
60
+ end
61
+
62
+ def get_date_names(date = Date.today)
63
+ this_month = date.month
64
+ if this_month == 12
65
+ next_month = 1
66
+ else
67
+ next_month = this_month + 1
68
+ end
69
+ if this_month == 1
70
+ prev_month = 12
71
+ else
72
+ prev_month = this_month - 1
73
+ end
74
+
75
+ month_arr = ['', 'January', 'February', 'March', 'April', 'May', 'June',
76
+ 'July', 'August', 'September', 'October', 'November', 'December']
77
+
78
+ this_month_name = month_arr[this_month]
79
+ next_month_name = month_arr[next_month]
80
+ prev_month_name = month_arr[prev_month]
81
+
82
+ arr = [date.year, date.day, this_month_name, next_month_name, prev_month_name]
83
+ debug_to_log("#{__method__} #{nice_array(arr)}")
84
+ arr
85
+ end
86
+
87
+ def get_trace(lnbr)
88
+ callertrace = "\nCaller trace: (#{lnbr})\n"
89
+ Kernel.caller.each_index do |x|
90
+ callertrace << ' >> ' + Kernel.caller[x].to_s + "\n"
91
+ end
92
+ callertrace
93
+ end
94
+
95
+ alias dump_caller get_trace
96
+
97
+ def get_mdyy(t = Time.now)
98
+ "#{t.month}/#{t.day}/#{t.year}"
99
+ end
100
+
101
+ def get_prefix(strg, offset)
102
+ a_slice = strg.slice(0, offset)
103
+ a_slice.downcase
104
+ end
105
+
106
+ def get_timestamp(format = 'long', offset = nil, offset_unit = :years)
107
+ t = DateTime.now
108
+ if offset
109
+ t = t.advance(offset_unit => offset)
110
+ end
111
+ case format
112
+ when 'dateonly'
113
+ t.strftime("%m/%d/%Y")
114
+ when 'condensed'
115
+ t.strftime("%Y%m%d%H%M")
116
+ when 'condensed_seconds'
117
+ t.strftime("%Y%m%d%H%M%S")
118
+ when 'long'
119
+ t.strftime("%m/%d/%Y %I:%M %p")
120
+ when 'mdyy'
121
+ get_mdyy(t)
122
+ when 'm/d/y'
123
+ get_mdyy(t)
124
+ else
125
+ Time.now.strftime("%m/%d/%Y %H:%M:%S")
126
+ end
127
+ end
128
+
129
+ def calc_index(index, every = 1)
130
+ (index / every) + (every - 1)
131
+ end
132
+
133
+ def get_variables(file, key_type = :role, dbg = true)
134
+ #TODO refactor this
135
+ debug_to_log("#{__method__}: file = #{file}")
136
+ debug_to_log("#{__method__}: key = #{key_type}")
137
+
138
+ script_found_in_login = false
139
+ script_found_in_data = false
140
+
141
+ @var = Hash.new
142
+ workbook = Excel.new(file)
143
+ data_index = find_sheet_with_name(workbook, 'Data')
144
+ workbook.default_sheet = workbook.sheets[data_index]
145
+ var_col = 0
146
+
147
+ 2.upto(workbook.last_column) do |col|
148
+ scriptName = workbook.cell(1, col)
149
+ if scriptName == @myName
150
+ var_col = col
151
+ script_found_in_data = true
152
+ break
153
+ end
154
+ end
155
+
156
+ 2.upto(workbook.last_row) do |line|
157
+ name = workbook.cell(line, 'A')
158
+ value = workbook.cell(line, var_col).to_s.strip
159
+ @var[name] = value
160
+ end
161
+
162
+ @var.keys.sort.each do |name|
163
+ message_tolog("@var #{name}: '#{@var[name]}'")
164
+ end if dbg
165
+
166
+ @login = Hash.new
167
+ login_col = 0
168
+ role_col = 0
169
+ userid_col = 0
170
+ password_col = 0
171
+ url_col = 0
172
+ name_col = 0
173
+ login_index = find_sheet_with_name(workbook, 'Login')
174
+ if login_index and login_index >= 0
175
+ workbook.default_sheet = workbook.sheets[login_index]
176
+
177
+ 1.upto(workbook.last_column) do |col|
178
+ a_cell = workbook.cell(1, col)
179
+ case a_cell
180
+ when @myName
181
+ login_col = col
182
+ script_found_in_login = true
183
+ break
184
+ when 'role'
185
+ role_col = col
186
+ when 'userid'
187
+ userid_col = col
188
+ when 'password'
189
+ password_col = col
190
+ when 'url'
191
+ url_col = col
192
+ when 'name'
193
+ name_col = col
194
+ end
195
+ end
196
+
197
+ 2.upto(workbook.last_row) do |line|
198
+ role = workbook.cell(line, role_col)
199
+ userid = workbook.cell(line, userid_col)
200
+ password = workbook.cell(line, password_col)
201
+ url = workbook.cell(line, url_col)
202
+ username = workbook.cell(line, name_col)
203
+ enabled = workbook.cell(line, login_col).to_s
204
+
205
+ case key_type
206
+ when :id, :userid
207
+ key = userid
208
+ when :role
209
+ key = role
210
+ else
211
+ key = userid
212
+ end
213
+
214
+ @login[key] = Hash.new
215
+ @login[key]['role'] = role
216
+ @login[key]['userid'] = userid
217
+ @login[key]['password'] = password
218
+ @login[key]['url'] = url
219
+ @login[key]['name'] = username
220
+ @login[key]['enabled'] = enabled
221
+
222
+ end
223
+
224
+ @login.keys.sort.each do |key|
225
+ message_tolog("@login (by #{key_type}): #{key}=>'#{@login[key].to_yaml}'")
226
+ end if dbg
227
+ end
228
+
229
+ if script_found_in_login and script_found_in_data
230
+ true
231
+ else
232
+ failed_to_log("Script found: in Login = #{script_found_in_login}; in Data = #{script_found_in_data}")
233
+ end
234
+ rescue
235
+ failed_to_log("#{__method__}: '#{$!}'")
236
+ end
237
+
238
+ def translate_var_list(key)
239
+ if @var[key] and @var[key].length > 0
240
+ list = @var[key].dup
241
+ unless list =~ /^\[.+\]$/
242
+ list = "[#{list}]"
243
+ end
244
+ eval(list)
245
+ end
246
+ rescue
247
+ failed_to_log("#{__method__}: '#{$!}'")
248
+ end
249
+
250
+ def grab_window_list(strg)
251
+ @ai.AutoItSetOption("WinTitleMatchMode", 2)
252
+ list = @ai.WinList(strg)
253
+ stuff = ''
254
+ names = list[0]
255
+ handles = list[1]
256
+ max = names.length - 1
257
+ rng = Range.new(0, max)
258
+ rng.each do |idx|
259
+ window_handle = "[HANDLE:#{handles[idx]}]"
260
+ full_text = @ai.WinGetText(window_handle)
261
+ stuff << "[#{handles[idx]}]=>#{names[idx]}=>'#{full_text}'\n"
262
+ end
263
+ debug_to_log("\n#{stuff}")
264
+ @ai.AutoItSetOption("WinTitleMatchMode", 1)
265
+ stuff
266
+ end
267
+
268
+ def debug_call_list(msg)
269
+ call_array = get_call_array
270
+ debug_to_log("#{msg}\n#{dump_array(call_array)}")
271
+ end
272
+
273
+ def sec2hms(s)
274
+ Time.at(s.to_i).gmtime.strftime('%H:%M:%S')
275
+ end
276
+
277
+ def close_log(scriptName, lnbr = '')
278
+ cmplTS = Time.now.to_f.to_s
279
+ puts ("#{scriptName} finished. Closing log. #{lnbr.to_s}")
280
+ passed_to_log("#{scriptName} run complete [#{cmplTS}]")
281
+ @myLog.close()
282
+ sleep(2)
283
+ end
284
+
285
+ protected :close_log
286
+
287
+ def find_sheet_with_name(workbook, sheet_name)
288
+ sheets = workbook.sheets
289
+ idx = 0
290
+ found = false
291
+ sheets.each do |s|
292
+ if s == sheet_name
293
+ found = true
294
+ break
295
+ end
296
+ idx += 1
297
+ end
298
+ if found
299
+ idx
300
+ else
301
+ -1
302
+ end
303
+ end
304
+
305
+ def nice_array(arr, space_to_underscore = false)
306
+ new_arr = Array.new
307
+ if space_to_underscore
308
+ arr.each do |nty|
309
+ new_arr << nty.gsub(/\s/, '_')
310
+ end
311
+ else
312
+ new_arr = arr
313
+ end
314
+ "['#{new_arr.join("', '")}']"
315
+ end
316
+
317
+ def nice_number(number, decimals = 0, dollars = false)
318
+ number.to_s.gsub!(/[,\$]/, '')
319
+ ptrn = "%0.#{decimals}f"
320
+ ptrn = '$' + ptrn if dollars
321
+ sprintf(ptrn, number).gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1,")
322
+ end
323
+
324
+ def pad_date(dt)
325
+ if dt and dt.length > 0
326
+ a, d1, b, d2, c = dt.split(/([\/\.-])/)
327
+ a = a.rjust(2, '0') unless a and a.length > 1
328
+ b = b.rjust(2, '0') unless b and b.length > 1
329
+ c = c.rjust(2, '0') unless c and c.length > 1
330
+ a + d1 + b + d2 + c
331
+ else
332
+ ''
333
+ end
334
+ end
335
+
336
+ def string_count_in_string(strg, substrg)
337
+ count = strg.scan(substrg).length
338
+ count
339
+ end
340
+
341
+ def strip_regex_mix(strg)
342
+ rslt = strg.dup
343
+ while match = rslt.match(/(\(\?-mix:(.+)\))/)
344
+ rslt.sub!(match[1], "/#{match[2]}/")
345
+ end
346
+ rslt
347
+ end
348
+
349
+ def rescue_me(e, me = nil, what = nil, where = nil, who = nil)
350
+ #TODO: these are rescues from exceptions raised in Watir/Firewatir
351
+ debug_to_log("#{__method__}: Begin rescue")
352
+ ok = false
353
+ begin
354
+ gaak = who.inspect
355
+ located = gaak =~ /located=true/i
356
+ rescue
357
+ debug_to_log("#{__method__}: gaak: '#{gaak}'")
358
+ end
359
+ msg = e.message
360
+ debug_to_log("#{__method__}: msg = #{msg}")
361
+ if msg =~ /undefined method\s+.join.\s+for/i # firewatir to_s implementation error
362
+ ok = true
363
+ elsif msg =~ /undefined method\s+.match.\s+for.+WIN32OLERuntimeError/i # watir and firewatir
364
+ ok = true
365
+ elsif msg =~ /undefined method\s+.match.\s+for.+UnknownObjectException/i # watir
366
+ ok = true
367
+ elsif msg =~ /window\.getBrowser is not a function/i # firewatir
368
+ ok = true
369
+ elsif msg =~ /WIN32OLERuntimeError/i # watir
370
+ ok = true
371
+ elsif msg =~ /undefined method\s+.match.\s+for/i # watir
372
+ ok = true
373
+ elsif msg =~ /wrong number of arguments \(1 for 0\)/i
374
+ ok = true
375
+ elsif (msg =~ /unable to locate element/i)
376
+ if located
377
+ ok = true
378
+ elsif where == 'Watir::Div'
379
+ ok = true
380
+ end
381
+ elsif (msg =~ /HRESULT error code:0x80070005/)
382
+ ok = true
383
+ #elsif msg =~ /missing\s+\;\s+before statement/
384
+ # ok = true
385
+ end
386
+ if ok
387
+ debug_to_log("#{__method__}: RESCUED: \n#{who.to_yaml}=> #{what} in #{me}()\n=> '#{$!}'")
388
+ debug_to_log("#{__method__}: #{who.inspect}") if who
389
+ debug_to_log("#{__method__}: #{where.inspect}")
390
+ debug_to_log("#{__method__}: #{get_callers(6, true)}")
391
+ else
392
+ debug_to_log("#{__method__}: NO RESCUE: #{e.message}")
393
+ debug_to_log("#{__method__}: NO RESCUE: \n#{get_callers(6, true)}")
394
+ end
395
+ debug_to_log("#{__method__}: Exit")
396
+ ok
397
+ end
398
+
399
+ def get_caller_line
400
+ last_caller = get_call_list[0]
401
+ line = last_caller.split(':', 3)[1]
402
+ line
403
+ end
404
+
405
+ def get_call_list(depth = 9, dbg = false)
406
+ myList = []
407
+ call_list = Kernel.caller
408
+ puts call_list if dbg
409
+ call_list.each_index do |x|
410
+ myCaller = call_list[x].to_s
411
+ myCaller =~ /([\(\)\w_\_\-\.]+\:\d+\:?.*?)$/
412
+ myList << "[#{$1.gsub(/eval/, @myName)}] "
413
+ break if x > depth or myCaller =~ /:in .run.$/
414
+ end
415
+ myList
416
+ end
417
+
418
+ alias get_callers get_call_list
419
+
420
+ def get_call_list_new(depth = 9, dbg = false)
421
+ myList = []
422
+ call_list = Kernel.caller
423
+ puts call_list if dbg
424
+ call_list.each_index do |x|
425
+ myCaller = call_list[x].to_s
426
+ if myCaller.include? @myName
427
+ myCaller =~ /([\(\)\w_\_\-\.]+\:\d+\:?.*?)$/
428
+ myList << "[#{$1.gsub(/eval/, @myName)}] "
429
+ break
430
+ end
431
+ break if x > depth or myCaller =~ /:in .run.$/ # this break causes error in Ruby 1.9.x
432
+ end
433
+ if @projName
434
+ call_list.each_index do |x|
435
+ myCaller = call_list[x].to_s
436
+ if myCaller.include? @projName
437
+ myCaller =~ /([\(\)\w_\_\-\.]+\:\d+\:?.*?)$/
438
+ myList << "[#{$1.gsub(/eval/, @projName)}] "
439
+ break
440
+ end
441
+ end
442
+ break if x > depth or myCaller =~ /:in .run.$/ # this break causes error in Ruby 1.9.
443
+ end
444
+ myList
445
+ end
446
+
447
+ def get_call_array(depth = 9)
448
+ arr = []
449
+ call_list = Kernel.caller
450
+ call_list.each_index do |x|
451
+ myCaller = call_list[x].to_s
452
+ myCaller =~ /([\(\)\w_\_\-\.]+\:\d+\:?.*?)$/
453
+ arr << $1.gsub(/eval/, @myName)
454
+ break if x > depth or myCaller =~ /:in .run.$/
455
+ end
456
+ arr
457
+ end
458
+
459
+ def get_debug_list(dbg = false)
460
+ calls = get_call_array(10)
461
+ puts "#{calls.to_yaml}" if dbg
462
+ arr = []
463
+ calls.each_index do |ix|
464
+ if ix > 1 # skip this method and the logging method
465
+ arr << calls[ix]
466
+ end
467
+ end
468
+ puts "#{arr.to_yaml}" if dbg
469
+ if arr.length > 0
470
+ list = 'TRACE:'
471
+ arr.reverse.each { |l| list << "=>#{l}" }
472
+ " [[#{list}]]"
473
+ else
474
+ nil
475
+ end
476
+ end
477
+
478
+ def dump_array(arr, space_to_underscore = false)
479
+ dump = " #{arr.inspect}\n"
480
+ arr.each_index do |x|
481
+ value = arr[x].to_s
482
+ value.gsub!(/\s/, '_') if space_to_underscore
483
+ dump << " #{x.to_s.rjust(5)}>> '#{arr[x].to_s}'\n"
484
+ end
485
+ dump
486
+ end
487
+
488
+ def dump_ole_methods(ole)
489
+ rtrn = ''
490
+ ole.ole_methods.each do |m|
491
+ prms = ''
492
+ m.params.each do |p|
493
+ prms << "#{p}, "
494
+ end
495
+ rtrn << "#{m.name}(#{prms.chop.chop})\n"
496
+ end
497
+ rtrn
498
+ end
499
+
500
+ def dump_ole_get_methods(ole)
501
+ rtrn = ''
502
+ ole.ole_get_methods.each do |m|
503
+ prms = ''
504
+ m.params.each do |p|
505
+ prms << "#{p}, "
506
+ end
507
+ rtrn << "#{m.name}(#{prms.chop.chop})\n"
508
+ end
509
+ rtrn
510
+ end
511
+
512
+ def dump_ole_help(ole)
513
+ rtrn = ''
514
+ ole.ole_obj_help.each do |m|
515
+ prms = ''
516
+ m.params.each do |p|
517
+ prms << "#{p}, "
518
+ end
519
+ rtrn << "#{m.name}(#{prms.chop.chop})\n"
520
+ end
521
+ rtrn
522
+ end
523
+
524
+ def dump_select_list_options(element, report = false)
525
+ msg = "#{element.inspect}"
526
+ options = element.options
527
+ cnt = 1
528
+ options.each do |o|
529
+ msg << "\n\t#{cnt}:\t'#{o}"
530
+ cnt += 1
531
+ end
532
+ if report
533
+ debug_to_report(msg)
534
+ else
535
+ debug_to_log(msg)
536
+ end
537
+ end
538
+
539
+ def dump_all_tables(browser, to_report = false)
540
+ tables = browser.tables
541
+ msg = ''
542
+ tbl_cnt = 0
543
+ tables.each do |tbl|
544
+ tbl_cnt += 1
545
+ row_cnt = 0
546
+ msg <<"\n=================\ntable: #{tbl_cnt}\n=================\n#{tbl}\ntext:\n#{tbl.text}"
547
+ tbl.rows.each do |row|
548
+ row_cnt += 1
549
+ cell_cnt = 0
550
+ msg <<"\n=================\ntable: #{tbl_cnt} row: #{row_cnt}\n#{row.inspect}\n#{row}\ntext:'#{row.text}'"
551
+ row.each do |cell|
552
+ cell_cnt += 1
553
+ msg <<"\ncell: #{cell_cnt}\n#{cell.inspect}\n#{row}\ntext: '#{cell.text}'"
554
+ end
555
+ end
556
+ end
557
+ if to_report
558
+ debug_to_report(msg)
559
+ else
560
+ debug_to_log(msg)
561
+ end
562
+ end
563
+
564
+ def dump_table_and_rows(table, to_report = false)
565
+ msg = "\n=================\ntable\n=================\nn#{table}\n#{table.to_yaml}\nrows:"
566
+ cnt = 0
567
+ table.rows.each do |r|
568
+ cnt += 1
569
+ msg << "\n#{cnt}: #{r.text}"
570
+ end
571
+ msg << "\n=================\n================="
572
+ if to_report
573
+ debug_to_report(msg)
574
+ else
575
+ debug_to_log(msg)
576
+ end
577
+ end
578
+
579
+ def dump_table_rows_and_cells(tbl)
580
+ msg = ''
581
+ row_cnt = 0
582
+ msg <<"\n=================\ntable: #{tbl.inspect}\n=================\n#{tbl}\ntext:\n#{tbl.text}"
583
+ tbl.rows.each do |row|
584
+ row_cnt += 1
585
+ cell_cnt = 0
586
+ msg <<"\n=================\nrow: #{row_cnt}\n#{row.inspect}\n#{row}\ntext:'#{row.text}'"
587
+ row.each do |cell|
588
+ cell_cnt += 1
589
+ msg <<"\ncell: #{cell_cnt}\n#{cell.inspect}\n#{row}\ntext: '#{cell.text}'"
590
+ end
591
+ end
592
+ debug_to_log(msg)
593
+ end
594
+
595
+ alias dump_table_rows dump_table_rows_and_cells
596
+
597
+ def dump_row_cells(row)
598
+ msg = ''
599
+ cell_cnt = 0
600
+ msg <<"\n=================\nrow: #{row.inspect}\n#{row}\ntext:'#{row.text}'"
601
+ row.each do |cell|
602
+ cell_cnt += 1
603
+ msg <<"\ncell: #{cell_cnt}\n#{cell.inspect}\n#{row}\ntext: '#{cell.text}'"
604
+ end
605
+ debug_to_log(msg)
606
+ end
607
+
608
+ def parse_cookies(browser)
609
+ cookies = Hash.new
610
+ strg = browser.document.cookie
611
+ ary = strg.split(';')
612
+ ary.each do |c|
613
+ key, value = c.split('=')
614
+ cookies[key.lstrip] = value
615
+ end
616
+ cookies
617
+ end
618
+
619
+ def capture_screen(browser, ts)
620
+ browser.maximize
621
+ browser.bring_to_front
622
+ caller = get_caller
623
+ caller.match(/:(\d+):/)
624
+ lnbr = $1
625
+ path = "#{@myRoot}/screenshot/"
626
+ screenfile = "#{@myName}_#{@myRun.id}_#{lnbr.to_s}_#{ts.to_f.to_s}.scrsht.jpg"
627
+ info_to_log("path:#{path} screenfile:#{screenfile}")
628
+ screenSpec = '"' + path + screenfile + '"'
629
+ screenSpec.gsub!('/', '\\')
630
+ screen_capture(screenSpec)
631
+ screenfile
632
+ end
633
+
634
+ def pdf_to_text(file, noblank = true)
635
+ spec = file.sub(/\.pdf$/, '')
636
+ `pdftotext #{spec}.pdf`
637
+ file = File.new("#{spec}.txt")
638
+ text = []
639
+ file.readlines.each do |l|
640
+ l.chomp! if noblank
641
+ if l.length > 0
642
+ text << l
643
+ end
644
+ end
645
+ file.close
646
+ text
647
+ end
648
+
649
+ # @deprecated
650
+ def flash_id(browser, strg, count)
651
+ msg = "Flash link id='#{strg}' #{count} times."
652
+ msg << " #{desc}" if desc.length > 0
653
+ browser.link(:id, strg).flash(count)
654
+ passed_to_log(msg)
655
+ true
656
+ rescue
657
+ failed_to_log("Unable to #{msg} '#{$!}'")
658
+ end
659
+
660
+ def flash(element, count = 4)
661
+ element.flash(count)
662
+ debug_to_log("'#{element.inspect}' flashed #{count} times.")
663
+ true
664
+ rescue
665
+ debug_to_log("Flash '#{element.inspect}' failed: '#{$!}' (#{__LINE__})")
666
+ end
667
+
668
+ def get_save_file_path(root, filename)
669
+ filespec = "#{root}/file/#{filename}"
670
+ filespec.gsub!('/', '\\')
671
+ end
672
+
673
+ def save_file_orig(filepath, desc = '', wait = WAIT)
674
+ # title = translate_popup_title(title)
675
+ @ai.WinWait("File Download", "", wait)
676
+ @ai.ControlFocus("File Download", "", "&Save")
677
+ sleep 1
678
+ @ai.ControlClick("File Download", "", "&Save", "left")
679
+ @ai.WinWait("Save As", "", wait)
680
+ sleep 1
681
+ @ai.ControlSend("Save As", "", "Edit1", filepath)
682
+ @ai.ControlClick("Save As", "", "&Save", "left")
683
+ sleep 1
684
+ @ai.WinWait("Download complete", "", wait)
685
+ @ai.ControlClick("Download complete", "", "Close")
686
+ end
687
+
688
+ #TODO This and save_file2 have to be combined somehow.
689
+ def save_file1(filepath, title = "File Download", desc = '', wait = WAIT)
690
+ title = translate_popup_title(title)
691
+ @ai.WinWait(title, '', wait)
692
+ @ai.WinActivate(title, '')
693
+ sleep 1
694
+ @ai.ControlFocus(title, "", "&Save")
695
+ sleep 3
696
+ @ai.ControlClick(title, "", "&Save", "primary")
697
+ sleep 2
698
+ @ai.ControlClick(title, "", "Save", "primary")
699
+
700
+ @ai.WinWait("Save As", "", wait)
701
+ sleep 1
702
+ @ai.ControlSend("Save As", "", "Edit1", filepath)
703
+ @ai.ControlFocus("Save As", "", "&Save")
704
+ @ai.ControlClick("Save As", "", "&Save", "primary")
705
+ @ai.ControlClick("Save As", "", "Save", "primary")
706
+
707
+ @ai.WinWait("Download complete", "", wait)
708
+ passed_to_log("Save file '#{filepath}' succeeded. #{desc}")
709
+ @ai.ControlClick("Download complete", "", "Close")
710
+ rescue
711
+ failed_to_log("Save file failed: #{desc} '#{$!}'. (#{__LINE__})")
712
+ end
713
+
714
+ def save_file2(filepath, title = "File Download - Security Warning", desc = '', wait = WAIT)
715
+ title = translate_popup_title(title)
716
+ sleep(1)
717
+ @ai.WinWait(title, '', wait)
718
+ dl_hndl = @ai.WinGetHandle(title, '')
719
+ dl_sv_hndl = @ai.ControlGetHandle(title, '', "&Save")
720
+ @ai.WinActivate(title, '')
721
+ sleep 1
722
+ @ai.ControlFocus(title, "", "&Save")
723
+ sleep 1
724
+ @ai.ControlFocus(title, "", "Save")
725
+ sleep 1
726
+ @ai.ControlClick(title, "", "&Save", "primary")
727
+ sleep 1
728
+ @ai.ControlClick(title, "", "Save", "primary")
729
+ sleep 1
730
+ w = WinClicker.new
731
+ w.clickButtonWithHandle(dl_sv_hndl)
732
+ sleep 1
733
+ w.clickWindowsButton_hwnd(dl_hndl, "Save")
734
+ sleep 1
735
+ w.clickWindowsButton_hwnd(dl_hndl, "&Save")
736
+
737
+ @ai.WinWait("Save As", "", wait)
738
+ sleep 1
739
+ @ai.ControlSend("Save As", "", "Edit1", filepath)
740
+ @ai.ControlFocus("Save As", "", "&Save")
741
+ @ai.ControlClick("Save As", "", "&Save", "primary")
742
+
743
+ @ai.WinWait("Download complete", "", wait)
744
+ passed_to_log("Save file '#{filepath}' succeeded. #{desc}")
745
+ @ai.ControlClick("Download complete", "", "Close")
746
+ rescue
747
+ failed_to_log("Save file failed: #{desc} '#{$!}'. (#{__LINE__})")
748
+ end
749
+
750
+ #method for handling save dialog
751
+ #use click_no_wait on the action that triggers the save dialog
752
+ def save_file(filepath, download_title = "File Download - Security Warning")
753
+ # TODO need version for Firefox
754
+ # TODO need to handle first character underline, e.g. 'Cancel' and '&Cancel'
755
+ download_title = translate_popup_title(download_title)
756
+ download_text = ''
757
+ download_control = "&Save"
758
+ saveas_title = 'Save As'
759
+ saveas_text = ''
760
+ saveas_control = "Edit1"
761
+ dnld_cmplt_title = "Download Complete"
762
+ dnld_cmplt_title = translate_popup_title(dnld_cmplt_title)
763
+ dnld_cmplt_text = ""
764
+ # save_title = ""
765
+ side = 'primary'
766
+ msgdl = "Window '#{download_title}':"
767
+ msgsa = "Window '#{saveas_title}':"
768
+ msgdc = "Window '#{dnld_cmplt_title}':"
769
+ begin
770
+ if @ai.WinWait(download_title, download_text, WAIT)
771
+ @ai.WinActivate(download_title, download_text)
772
+ if @ai.WinActive(download_title, download_text)
773
+ dl_title = @ai.WinGetTitle(download_title, download_text)
774
+ # dl_hndl = @ai.WinGetHandle(download_title, download_text)
775
+ # dl_text = @ai.WinGetText(download_title, download_text)
776
+ # dl_sv_hndl = @ai.ControlGetHandle(dl_title, '', download_control)
777
+ # dl_op_hndl = @ai.ControlGetHandle(dl_title, '', '&Open')
778
+ # dl_cn_hndl = @ai.ControlGetHandle(dl_title, '', 'Cancel')
779
+ debug_to_log("#{msgdl} activated. (#{__LINE__})")
780
+
781
+ if @ai.ControlFocus(dl_title, download_text, download_control)
782
+ debug_to_log("#{msgdl} focus gained. (#{__LINE__})")
783
+
784
+ @ai.Send("S")
785
+ # @ai.ControlSend(dl_Stitle, download_text, download_control, "{ENTER}")
786
+ sleep_for 1
787
+
788
+ if @ai.ControlClick(dl_title, download_text, download_control, side)
789
+ debug_to_log("#{msgdl} click succeeded on '#{download_control}'. (#{__LINE__})")
790
+
791
+ if @ai.WinWait(saveas_title, saveas_text, WAIT)
792
+ debug_to_log("#{msgsa} appeared. (#{__LINE__})")
793
+ sleep_for 1
794
+ if @ai.ControlSend(saveas_title, saveas_text, saveas_control, filepath)
795
+ debug_to_log("#{msgsa} controlsend of '#{saveas_control}' succeeded. (#{__LINE__})")
796
+
797
+ @ai.Send("S")
798
+ @ai.ControlSend(saveas_title, saveas_text, saveas_control, "{ENTER}")
799
+ sleep_for 1
800
+
801
+ if @ai.ControlClick(saveas_title, saveas_text, saveas_control, side)
802
+ passed_to_log("#{msgsa} click succeeded on '#{saveas_control}'. (#{__LINE__})")
803
+ if @ai.WinWait(dnld_cmplt_title, dnld_cmplt_text, WAIT)
804
+ debug_to_log("#{msgdc} appeared. (#{__LINE__})")
805
+ sleep_for 1
806
+ if @ai.ControlClick(dnld_cmplt_title, dnld_cmplt_text, "Close", side)
807
+ passed_to_log("Save file for #{filepath} succeeded.")
808
+ else
809
+ failed_to_log("#{msgdc} click failed on 'Close'. (#{__LINE__})")
810
+ end
811
+ else
812
+ failed_to_log("#{msgdc} did not appear after #{WAIT} seconds. (#{__LINE__})")
813
+ end
814
+ else
815
+ failed_to_log("#{msgsa} click failed on '#{saveas_control}'. (#{__LINE__})")
816
+ end
817
+ else
818
+ failed_to_log("#{msgsa} controlsend of '#{saveas_control}' failed. (#{__LINE__})")
819
+ end
820
+ else
821
+ failed_to_log("#{msgsa} did not appear after #{WAIT} seconds. (#{__LINE__})")
822
+ end
823
+ else
824
+ failed_to_log("#{msgdl} click failed on '#{download_control}'. (#{__LINE__})")
825
+ end
826
+ else
827
+ failed_to_log("#{msgdl} Unable to gain focus on control '#{dl_title}'. (#{__LINE__})")
828
+ end
829
+ else
830
+ failed_to_log("#{msgdl} Unable to activate. (#{__LINE__})")
831
+ end
832
+ else
833
+ failed_to_log("#{msgdl} did not appear after #{WAIT} seconds. (#{__LINE__})")
834
+ end
835
+ rescue
836
+ failed_to_log("Save file failed: '#{$!}'. (#{__LINE__})")
837
+ end
838
+ end
839
+
840
+ #method for cancelling Print window
841
+ # TODO need to handle 'Cancel' and '&Cancel' (first character underlined)
842
+ def close_print(title = 'Print', text = '', button = '&Cancel', side = 'left')
843
+ msg = "Popup: title=#{title} button='#{button}' text='#{text}' side='#{side}':"
844
+ if @ai.WinWait(title, text, WAIT)
845
+ passed_to_log("#{msg} found.")
846
+ @ai.WinActivate(title)
847
+ if @ai.WinActive(title, text)
848
+ passed_to_log("#{msg} activated.")
849
+ if @ai.ControlFocus(title, text, button)
850
+ passed_to_log("#{msg} focus attained.")
851
+ if @ai.ControlClick(title, text, button, side)
852
+ passed_to_log("#{msg} closed successfully.")
853
+ else
854
+ failed_to_log("#{msg} click failed on button (#{__LINE__})")
855
+ end
856
+ else
857
+ failed_to_log("#{msg} Unable to gain focus on button (#{__LINE__})")
858
+ end
859
+ else
860
+ failed_to_log("#{msg} Unable to activate (#{__LINE__})")
861
+ end
862
+ else
863
+ failed_to_log("#{msg} did not appear after #{WAIT} seconds. (#{__LINE__})")
864
+ end
865
+ rescue
866
+ failed_to_log("Close #{msg}: '#{$!}'. (#{__LINE__})")
867
+ end
868
+
869
+ #method for handling file download dialog
870
+ #use click_no_wait on the action that triggers the save dialog
871
+ # TODO need version for Firefox
872
+ # TODO need to handle 'Cancel' and '&Cancel' (first character underlined)
873
+ # TODO replace call to close_modal_ie with actual file download
874
+ def file_download(browser = nil)
875
+ title = 'File Download'
876
+ title = translate_popup_title(title)
877
+ text = ''
878
+ button = 'Cancel'
879
+ if @browserAbbrev == 'IE'
880
+ close_popup(title, button, text)
881
+ else
882
+
883
+ end
884
+ end
885
+
886
+ #method for handling file upload dialog
887
+ #use click_no_wait on the action that triggers the save dialog
888
+ # TODO need version for Firefox
889
+ def file_upload(filepath, title = 'Choose File', text = '', button = '&Open',
890
+ control = 'Edit1', side = 'primary')
891
+ title = translate_popup_title(title)
892
+ msg = "Window title=#{title} button='#{button}' text='#{text}' side='#{side}':"
893
+ begin
894
+ if @ai.WinWait(title, text, WAIT)
895
+ passed_to_log("#{msg} found.")
896
+ @ai.WinActivate(title, text)
897
+ if @ai.WinActive(title, text)
898
+ passed_to_log("#{msg} activated.")
899
+ if @ai.ControlSend(title, text, control, filepath)
900
+ passed_to_log("#{msg} #{control} command sent.")
901
+ sleep_for 1
902
+ if @ai.ControlClick(title, text, button, "primary")
903
+
904
+ passed_to_log("#{msg} Upload of #{filepath} succeeded.")
905
+
906
+
907
+ else
908
+ failed_to_log("#{msg} Upload of #{filepath} failed. (#{__LINE__})")
909
+ end
910
+ else
911
+ failed_to_log("#{msg} Unable to select #{filepath}. (#{__LINE__})")
912
+ end
913
+ else
914
+ failed_to_log("#{msg} Unable to activate. (#{__LINE__})")
915
+ end
916
+ else
917
+ failed_to_log("#{msg} did not appear after #{WAIT} seconds. (#{__LINE__})")
918
+ end
919
+ rescue
920
+ failed_to_log("#{msg} Unable to upload: '#{$!}'. (#{__LINE__})")
921
+ end
922
+
923
+ end
924
+
925
+ def upload_file(data_path)
926
+ limit = 180 # .seconds
927
+ Timeout::timeout(limit) {
928
+ wait = 20
929
+ @ai.WinWait("Choose File to Upload", "", wait)
930
+ sleep 1
931
+ @ai.ControlSend("Choose File to Upload", "", "Edit1", data_path)
932
+ @ai.ControlClick("Choose File to Upload", "", "[CLASS:Button; INSTANCE:2]", "left")
933
+ sleep 4
934
+ #sleep 1
935
+ }
936
+ failed_to_log("Choose File to Upload not found after #{limit} '#{$!}'")
937
+ rescue Timeout::Error
938
+ failed_to_log("File Upload timeout after #{limit} '#{$!}'")
939
+ end
940
+
941
+ def focus_on_textfield_by_id(browser, strg, desc = '')
942
+ msg = "Set focus on textfield name='#{strg}' "
943
+ msg << " #{desc}" if desc.length > 0
944
+ tf = browser.text_field(:id, strg)
945
+ tf.focus
946
+ passed_to_log(msg)
947
+ true
948
+ rescue
949
+ failed_to_log("Unable to #{msg} '#{$!}'")
950
+ end
951
+
952
+ # @deprecated
953
+ def flash_text(browser, strg, count, desc = '')
954
+ msg = "Flash link text='#{strg}' #{count} times."
955
+ msg << " #{desc}" if desc.length > 0
956
+ strgCnt = string_count_in_string(browser.text, strg)
957
+ if strgCnt > 0
958
+ browser.link(:text, strg).flash(count)
959
+ passed_to_log(msg)
960
+ true
961
+ else
962
+ failed_to_log("#{msg} Link not found.")
963
+ end
964
+ rescue
965
+ failed_to_log("Unable to #{msg} '#{$!}'")
966
+ end
967
+
968
+ def do_taskkill(severity, pid)
969
+ if pid and pid > 0 and pid < 538976288
970
+ info_to_log("Executing taskkill for pid #{pid}")
971
+ log_message(severity, %x[taskkill /t /f /pid #{pid}])
972
+ end
973
+ rescue
974
+ error_to_log("#{$!} (#{__LINE__})")
975
+ end
976
+
977
+ def rescue_me_command(element, how, what, command = nil, param = nil, container = :browser)
978
+ loc = "#{container}.#{element}(#{how}, #{what})"
979
+ loc << ".#{command}" if command
980
+ loc << "(#{param})" if param
981
+ loc
982
+ end
983
+
984
+ def method_to_title(method, no_sub = false)
985
+ title = method.to_s.titleize
986
+ title.gsub!(/And/, '&') unless no_sub
987
+ title
988
+ rescue
989
+ debug_to_log("#{__method__}: #{method} #{$!}")
990
+ end
991
+
992
+ def unable_to(message = '', no_dolbang = false, verify_that = false)
993
+ call_arr = get_call_array()
994
+ call_script, call_line, call_meth = parse_caller(call_arr[1])
995
+ strg = "Unable to"
996
+ strg << " verify" if verify_that
997
+ strg << " #{call_meth.titleize}:"
998
+ strg << " #{message}" if message.length > 0
999
+ strg << " '#{$!}'" unless no_dolbang
1000
+ strg
1001
+ end
1002
+
1003
+ def parse_caller(caller)
1004
+ call_script, call_line, call_meth = caller.split(':')
1005
+ call_script.gsub!(/\.rb/, '')
1006
+ call_script = call_script.camelize
1007
+ call_meth =~ /in .([\w\d_]+)./
1008
+ call_meth = $1
1009
+ [call_script, call_line, call_meth]
1010
+ end
1011
+
1012
+ def get_test_level
1013
+ arr = []
1014
+ each_line = 0
1015
+ call_list = Kernel.caller
1016
+ #debug_to_log("#{call_list.to_yaml}")
1017
+ call_list.each_index do |x|
1018
+ myCaller = call_list[x].to_s
1019
+ myCaller =~ /([\(\)\w_\_\-\.]+\:\d+\:?.*?)$/
1020
+ string = $1
1021
+ unless string =~ /logging\.rb|mark_testlevel|mark_test_level|debug_to_report|debug_toreport/
1022
+ if string.length > 0
1023
+ if string =~ /each|each_key/
1024
+ each_line = string.match(/\:(\d+)\:/)[1]
1025
+ elsif string.match(/\:(\d+)\:/)[1] == each_line
1026
+ next
1027
+ else
1028
+ arr << string.gsub(/eval/, @myName)
1029
+ end
1030
+ end
1031
+ end
1032
+ break if myCaller =~ /:in .run.$|runner\.rb/
1033
+ end
1034
+ #debug_to_log("#{arr.length} #{nice_array(arr)}")
1035
+ [arr.length, arr]
1036
+ end
1037
+
1038
+ def awetestlib?
1039
+ not Awetestlib::Runner.nil?
1040
+ rescue
1041
+ return false
1042
+ end
1043
+
1044
+ def get_os
1045
+ @os = OpenStruct.new(
1046
+ :name => Uname.sysname,
1047
+ :version => Uname.version,
1048
+ :release => Uname.release,
1049
+ :nodename => Uname.nodename,
1050
+ :machine => Uname.machine
1051
+ )
1052
+ end
1053
+
1054
+ end
1055
+ end
1056
+ end