browza 0.0.2.beta2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,6 +2,7 @@ require 'selenium-webdriver'
2
2
  require 'singleton'
3
3
  require 'appmodel'
4
4
  require 'logging'
5
+ require 'sauce_whisk'
5
6
 
6
7
  module Browza
7
8
 
@@ -13,16 +14,148 @@ class Manager
13
14
  attr_accessor :appModels
14
15
  attr_accessor :browserType
15
16
  attr_accessor :defaultTimeout
17
+ attr_accessor :driverList
18
+ attr_accessor :browserMgr
19
+ attr_accessor :debug
16
20
 
17
- def initialize(logLevel = :warn)
21
+ def initialize(_logLevel = :warn)
22
+ @debug = false
23
+ @driverList = []
18
24
  @logger = Logging.logger(STDOUT)
19
- @logger.level = logLevel
25
+ @logger.level = _logLevel
20
26
  @defaultTimeout = 30
21
27
  @appModels=[]
28
+ @browserMgr = Browza::BrowzaMgr.new()
29
+ end
30
+
31
+ def _addDriver(d)
32
+ @logger.debug __FILE__ + (__LINE__).to_s + " _addDriver(#{d})" if @debug
33
+ @browserMgr.add(d)
34
+
35
+ if !d.is_a?(Hash)
36
+ @driverList << { :is_sauce => false, :drv => d }
37
+ else
38
+ @driverList << d
39
+ end
40
+
41
+ @driverList.last
42
+ end
43
+
44
+ def browserName
45
+ @driverList[0][:drv].browser.to_s
46
+ end
47
+
48
+ def count
49
+ @driverList.length
50
+ end
51
+
52
+ def setSauceStatus(id, status)
53
+ rc = false
54
+ @logger.debug __FILE__ + (__LINE__).to_s + " setSauceStatus(#{id}, #{status})" if @debug
55
+
56
+
57
+ if (ENV['SELENIUM_RUN'] && ENV['SELENIUM_RUN'].match(/local/i)) || (ENV['SELENIUM_PLATFORM'] && ENV['SELENIUM_PLATFORM'].match(/local/i))
58
+ @logger.debug __FILE__ + (__LINE__).to_s + " setSauceStatus() - ignored (running locally)"
59
+ return nil
60
+ end
61
+
62
+ begin
63
+ drv = @browserMgr.getDriver(id)
64
+
65
+ unless drv.nil?
66
+ job_id = drv.session_id
67
+ SauceWhisk::Jobs.change_status job_id, status
68
+ rc = true
69
+ end
70
+
71
+ rescue => ex
72
+ @logger.fatal __FILE__ + (__LINE__).to_s + " #{ex.class}"
73
+ @logger.fatal "Backtrace:\n\t#{ex.backtrace.join("\n\t")}"
74
+ end
75
+
76
+ rc
77
+ end
78
+
79
+
80
+ def connectSauce(id, _caps=nil)
81
+ @logger.debug __FILE__ + (__LINE__).to_s + " connectSauce(#{id}, #{_caps})" if @debug
82
+ runLocal = false
83
+
84
+ if _caps.is_a?(String) && File.exist?(caps)
85
+ caps = JSON.parse(File.read(caps), :symbolize_names => true)
86
+ else
87
+ caps = _caps.dup
88
+ end
89
+
90
+ if caps.has_key?('platform')
91
+ tmpCaps = caps.clone
92
+
93
+
94
+ if !ENV['SELENIUM_NAME'].nil? && (ENV['SELENIUM_NAME'].is_a?(String) && !ENV['SELENIUM_NAME'].empty?)
95
+ tmpCaps['name'] = ENV['SELENIUM_NAME'].to_s
96
+ elsif !tmpCaps.has_key?('name')
97
+ tmpCaps['name'] = Time.now.strftime("%m%d%y_#{caps['browserType'].to_s}")
98
+ end
99
+
100
+ if caps['platform'].match(/\s*(linux|macOS|osx|os x|windows)/i)
101
+
102
+ if caps.has_key?('browserType')
103
+ browserType = caps['browserType']
104
+
105
+ if browserType.match(/edge/i)
106
+ caps = Selenium::WebDriver::Remote::Capabilities.edge()
107
+ elsif browserType.match(/chrome/i)
108
+ caps = Selenium::WebDriver::Remote::Capabilities.chrome()
109
+ elsif browserType.match(/firefox/i)
110
+ caps = Selenium::WebDriver::Remote::Capabilities.firefox()
111
+ elsif browserType.match(/ie/i)
112
+ caps = Selenium::WebDriver::Remote::Capabilities.internet_explorer()
113
+ elsif browserType.match(/safari/)
114
+ caps = Selenium::WebDriver::Remote::Capabilities.safari()
115
+ else
116
+ raise "Browza::UnexpectedBrowser::#{browserType}"
117
+ end
118
+
119
+ end
120
+ else
121
+ runLocal = true
122
+ browserType = caps['browserType'] || ENV['SELENIUM_BROWSER'] || 'safari'
123
+ end
124
+
125
+ tmpCaps.each_pair do |k, v|
126
+ caps[k.to_s] = v
127
+ end
128
+
129
+ @logger.debug __FILE__ + (__LINE__).to_s + " caps => #{caps}" if @debug
130
+
131
+ begin
132
+
133
+ if runLocal
134
+ @drv=Selenium::WebDriver.for browserType.to_s.to_sym, :desired_capabilities => caps
135
+ else
136
+ sauce_endpoint = "http://#{ENV['SAUCE_USERNAME']}:#{ENV['SAUCE_ACCESS_KEY']}@ondemand.saucelabs.com:80/wd/hub"
137
+
138
+ @drv=Selenium::WebDriver.for :remote, :url => sauce_endpoint, :desired_capabilities => caps
139
+ # The following print to STDOUT is useful when running on JENKINS with SauceLabs plugin
140
+ # Reference:
141
+ # https://wiki.saucelabs.com/display/DOCS/Setting+Up+Reporting+between+Sauce+Labs+and+Jenkins
142
+ puts "SauceOnDemandSessionID=#{@drv.session_id} job-name=#{caps[:name]}"
143
+ end
144
+
145
+ _addDriver( { :id => id, :drv => @drv, :is_sauce => true })
146
+ rescue => ex
147
+ @logger.fatal __FILE__ + (__LINE__).to_s + " #{ex.class}"
148
+ @logger.fatal "Backtrace:\n\t#{ex.backtrace.join("\n\t")}"
149
+ end
150
+
151
+ caps
152
+
153
+ end
154
+
22
155
  end
23
156
 
24
157
  def setLogLevel(l)
25
- puts __FILE__ + (__LINE__).to_s + " setLogLevel(#{l})"
158
+ @logger.debug __FILE__ + (__LINE__).to_s + " setLogLevel(#{l})"
26
159
  @logger.level = l
27
160
  end
28
161
 
@@ -31,32 +164,238 @@ class Manager
31
164
  end
32
165
 
33
166
  def addModel(_a)
34
- @logger.debug __FILE__ + (__LINE__).to_s + " [addModel]: #{_a}"
167
+ @logger.debug __FILE__ + (__LINE__).to_s + " [addModel]: #{_a}" if @debug
35
168
  @appModels << Appmodel::Model.new(_a)
36
169
  end
37
170
 
38
171
  # Set innerWidth and innerHeight
39
- def setDimension(width=1035, height=768)
40
- target_size = Selenium::WebDriver::Dimension.new(width, height)
41
- getDriver().manage.window.size = target_size
172
+ # Ref.: /selenium-webdriver/lib/selenium/webdriver/common/window.rb
173
+ # o resize_to(width, height)
174
+ #
175
+ def setDimension(width = 1035, height = 768)
176
+ @logger.debug __FILE__ + (__LINE__).to_s + " setDimension(#{width}, #{height}) count:#{@driverList.length}" if @debug
177
+ begin
178
+ i=0
179
+ @driverList.each do |b|
180
+ target_size = Selenium::WebDriver::Dimension.new(width.to_i, height.to_i)
181
+ if b[:drv] && (b[:drv].is_a?(Selenium::WebDriver) || b[:drv].is_a?(Selenium::WebDriver::Driver))
182
+ b[:drv].manage.window.size = target_size
183
+ else
184
+ @logger.warn __FILE__ + (__LINE__).to_s + " Attempt to access driver failed. (#{b})"
185
+ end
186
+
187
+ end
188
+ rescue => ex
189
+ @logger.warn __FILE__ + (__LINE__).to_s + " browser[#{i}]: #{ex.class}"
190
+ @logger.warn __FILE__ + (__LINE__).to_s + " Error during processing: #{$!}"
191
+ @logger.warn " Backtrace:\n\t#{ex.backtrace.join("\n\t")}"
192
+ end
42
193
  end
43
194
 
44
195
  def maximize()
45
196
  getDriver().manage.window.maximize
46
197
  end
47
198
 
48
- def createBrowser(_type = :chrome)
49
- @browserType = _type
50
- @drv = Selenium::WebDriver.for @browserType
51
- setDimension
199
+ def _getBrowserType(browserType)
200
+ t = browserType
201
+
202
+ if browserType.match(/chrome/i)
203
+ t = :chrome
204
+ elsif browserType.match(/firefox/i)
205
+ t = :firefox
206
+ elsif browserType.match(/ie/i)
207
+ t = :ie
208
+ elsif browserType.match(/edge/i)
209
+ t = :edge
210
+ end
211
+
212
+ t
52
213
  end
53
214
 
54
- def getDriver()
55
- @drv
215
+
216
+ def start(*p)
217
+ if (ENV['SELENIUM_RUN'] && ENV['SELENIUM_RUN'].match(/local/i)) || ENV['SELENIUM_PLATFORM'].match(/local/i)
218
+ return createBrowser(p)
219
+ else
220
+ @logger.debug __FILE__ + (__LINE__).to_s + " connectSauce() => #{p} #{p.class} #{p.size}" if @debug
221
+
222
+ if p.size == 0
223
+ caps = {}
224
+ caps['name'] = ENV['SELENIUM_NAME']
225
+ caps['platform'] = ENV['SELENIUM_PLATFORM']
226
+ caps['browserType'] = ENV['SELENIUM_BROWSER']
227
+ caps['screenResolution'] = ENV['SELENIUM_RESOLUTION']
228
+ caps['version'] = ENV['SELENIUM_VERSION']
229
+ ENV['SELENIUM_RUN']='sauce'
230
+
231
+ connectSauce(caps['name'], caps)
232
+ end
233
+
234
+ end
56
235
  end
57
236
 
58
- def quit()
59
- getDriver().quit
237
+ def createBrowser(*p)
238
+
239
+ if ENV['SELENIUM_RESOLUTION']
240
+ @logger.debug " SELENIUM_RESOLUTION=#{ENV['SELENIUM_RESOLUTION']}" if @debug
241
+ _width = ENV['SELENIUM_RESOLUTION'].match(/\s*(\d+)\s*x\s*(\d+)\s*$/)[1].to_s
242
+ _height = ENV['SELENIUM_RESOLUTION'].match(/\s*(\d+)\s*x\s*(\d+)\s*$/)[2].to_s
243
+ else
244
+ _width = 1035
245
+ _height = 768
246
+ end
247
+
248
+ @logger.debug __FILE__ + (__LINE__).to_s + " createBrowser() : width x height : #{_width}, #{_height}" if @debug
249
+
250
+ _id = Time.now.to_i.to_s
251
+
252
+ @logger.debug __FILE__ + (__LINE__).to_s + " SELENIUM_BROWSER : #{ENV['SELENIUM_BROWSER']}" if @debug
253
+ @browserType = ENV['SELENIUM_BROWSER'] || 'chrome'
254
+ @browserType = _getBrowserType(@browserType)
255
+
256
+ if @debug
257
+ @logger.debug __FILE__ + (__LINE__).to_s + " createBrowser(#{@browserType}) (isSymbol: #{@browserType.is_a?(Symbol)} : #{p.class.to_s}"
258
+ end
259
+
260
+ if p.is_a?(Array) && p.length > 0
261
+
262
+ if @debug
263
+ @logger.debug __FILE__ + (__LINE__).to_s + " createBrowser() size: #{p.size} p[0]=#{p[0]} p[0].class=#{p[0].class} p[0].size=#{p[0].size} isSymbol(#{p[0].is_a?(Symbol)})"
264
+ end
265
+
266
+ if p.size == 1
267
+
268
+ if p[0].is_a?(Array) && p[0].size==1 && ( p[0][0].is_a?(Symbol) || p[0][0].is_a?(String) )
269
+ @browserType = p[0][0].to_s.to_sym
270
+ elsif p[0].is_a?(Array) && p[0].size==1 && p[0][0].is_a?(Hash)
271
+ @logger.debug __FILE__ + (__LINE__).to_s + " #{p[0]}"
272
+
273
+ h = p[0][0]
274
+
275
+ if h.has_key?(:browserType)
276
+ @browserType = h[:browserType]
277
+ end
278
+
279
+ if h.has_key?(:width) && h.has_key?(:height)
280
+ _width = h[:width]
281
+ _height = h[:height]
282
+ end
283
+
284
+ if h.has_key?(:id)
285
+ _id = h[:id]
286
+ end
287
+ elsif p[0].is_a?(Symbol) || p[0].is_a?(String)
288
+ @browserType = p[0].to_s.to_sym
289
+ elsif p[0].is_a?(Hash) && !p[0].empty?
290
+ @logger.debug __FILE__ + (__LINE__).to_s + " #{p[0]}"
291
+
292
+ h = p[0]
293
+
294
+ if h.has_key?(:browserType)
295
+ @logger.debug __FILE__ + (__LINE__).to_s + " UPDTE"
296
+ @browserType = h[:browserType]
297
+ end
298
+
299
+ if h.has_key?(:width) && h.has_key?(:height)
300
+ _width = h[:width]
301
+ _height = h[:height]
302
+ end
303
+
304
+ if h.has_key?(:id)
305
+ _id = h[:id]
306
+ end
307
+
308
+ end
309
+
310
+ end
311
+
312
+ else
313
+ @logger.debug __FILE__ + (__LINE__).to_s + " createBrowser without parms (width/height: #{_width}, #{_height})"
314
+ end
315
+
316
+ @logger.debug "Selenium::WebDriver.for #{@browserType} (isSymbol: #{@browserType.is_a?(Symbol)})" if @debug
317
+
318
+ begin
319
+ @drv = Selenium::WebDriver.for @browserType
320
+ rescue TypeError
321
+ @logger.warn __FILE__ + (__LINE__).to_s + " See https://github.com/mozilla/geckodriver/issues/676" if @browserType == :firefox
322
+ end
323
+
324
+ _addDriver( { :drv => @drv, :is_sauce => false, :id => _id })
325
+
326
+ setDimension(_width, _height)
327
+ end
328
+
329
+ def _getDriverIndex(id)
330
+ i = 0
331
+
332
+ @driverList.each do |b|
333
+ if b.has_key?(:id) && b[:id] == id
334
+ return i
335
+ end
336
+ i += 1
337
+ end
338
+
339
+ return nil
340
+ end
341
+
342
+
343
+ def deleteDriver(id)
344
+ i = _getDriverIndex(id)
345
+ unless i.nil?
346
+ @driverList.delete_at(i)
347
+ end
348
+ end
349
+
350
+ def getDriver(id=nil)
351
+ if id.nil?
352
+ return @driverList[0][:drv]
353
+ end
354
+
355
+ i = _getDriverIndex(id)
356
+
357
+ unless i.nil?
358
+ return @driverList[i][:drv]
359
+ end
360
+
361
+ nil
362
+ end
363
+
364
+
365
+ def quit(id=nil)
366
+
367
+ if id.nil?
368
+ @browserMgr.getBrowsers().each do |b|
369
+
370
+ begin
371
+ if b[:is_sauce]
372
+ job_id = b[:drv].session_id
373
+
374
+ if b.has_key?(:status)
375
+ SauceWhisk::Jobs.change_status job_id, b[:status]
376
+ end
377
+
378
+ end
379
+
380
+ @logger.debug __FILE__ + (__LINE__).to_s + " quit : #{b[:id]}"
381
+ @logger.debug __FILE__ + (__LINE__).to_s + " b.methods => #{b[:drv].methods.sort}"
382
+
383
+ b[:drv].quit
384
+ rescue => ex
385
+ @logger.fatal " #{ex.class}"
386
+ end
387
+
388
+ end
389
+
390
+ @browserMgr.clear()
391
+
392
+ @driverList=[]
393
+ else
394
+ @logger.debug __FILE__ + (__LINE__).to_s + " quit(#{id}"
395
+ getDriver(id).quit
396
+ deleteDriver(id)
397
+ end
398
+
60
399
  end
61
400
 
62
401
  def title()
@@ -69,12 +408,39 @@ class Manager
69
408
  !expected_title.match(current_title).nil? || regex==current_title
70
409
  end
71
410
 
72
- def goto(url)
73
- getDriver().navigate.to url
411
+ def goto(url, id=nil)
412
+
413
+ rc = false
414
+
415
+ if id.nil?
416
+ @driverList.each do |b|
417
+ @logger.debug __FILE__ + (__LINE__).to_s + " => #{b}"
418
+ b[:drv].navigate.to url
419
+ rc = true
420
+ end
421
+ else
422
+ getDriver(id).navigate.to url
423
+ rc = true
424
+ #getDriver().navigate.to url
425
+ end
426
+
427
+ rc
74
428
  end
75
429
 
76
- def navigate(url)
77
- goto(url)
430
+ # def navigate(url, id=nil)
431
+ def navigate(*p)
432
+ rc=false
433
+
434
+ if p.is_a?(Array)
435
+ if p.length == 1
436
+ rc = goto(p[0].to_s)
437
+ elsif p.length == 2
438
+ rc = goto(p[0], p[1])
439
+ end
440
+
441
+ end
442
+
443
+ rc
78
444
  end
79
445
 
80
446
  def _parseLocator(_locator)
@@ -97,7 +463,7 @@ class Manager
97
463
  end
98
464
 
99
465
  def getElements(_locator, drv=nil, _timeout=30)
100
- rc=nil
466
+ rc = nil
101
467
  begin
102
468
 
103
469
  if drv.nil?
@@ -128,9 +494,8 @@ class Manager
128
494
 
129
495
 
130
496
  def getElement(_locator, drv=nil, _timeout=30)
131
-
132
497
  @logger.debug __FILE__ + (__LINE__).to_s + " getElement(#{_locator})"
133
- rc=nil
498
+ rc = nil
134
499
  begin
135
500
  locator = _parseLocator(_locator)
136
501
 
@@ -150,6 +515,9 @@ class Manager
150
515
  !rc.nil?
151
516
  }
152
517
 
518
+ rescue Selenium::WebDriver::Error::TimeOutError
519
+ @logger.debug __FILE__ + (__LINE__).to_s + " TimeOutError: #{locator}"
520
+
153
521
  rescue Selenium::WebDriver::Error::NoSuchElementError
154
522
  @logger.warn __FILE__ + (__LINE__).to_s + " NoSuchElementError : #{locator}"
155
523
 
@@ -162,23 +530,59 @@ class Manager
162
530
  rc
163
531
  end
164
532
 
533
+ def _isBrowser?(drv, s)
534
+
535
+ @logger.debug __FILE__ + (__LINE__).to_s + " _isBrowser?(#{drv.class}, #{s})"
536
+ if drv.nil?
537
+ drv=@drv
538
+ end
539
+
540
+ !drv.browser.to_s.match(s).nil?
541
+ end
542
+
165
543
  def isChrome?(drv=nil)
166
544
  if drv.nil?
167
545
  drv=@drv
168
546
  end
169
547
 
170
- !drv.browser.to_s.match(/chrome/i).nil?
548
+ !drv.browser.to_s.match(/\s*chrome/i).nil?
171
549
  end
172
550
 
173
- def switch_into_frame(id)
174
- drv = @drv
175
- @logger.debug __FILE__ + (__LINE__).to_s + "== switch_into_frame(#{id})"
176
- _fcnId=" [switch_into_frame]"
177
- @logger.debug __FILE__ + (__LINE__).to_s + "#{_fcnId}: (#{id})"
551
+ def isEdge(drv=nil)
552
+ if drv.nil?
553
+ drv=@drv
554
+ end
555
+
556
+ !drv.browser.to_s.match(/\s*edge/i).nil?
557
+ end
558
+
559
+ def isIE(drv=nil)
560
+ if drv.nil?
561
+ drv=@drv
562
+ end
563
+
564
+ !drv.browser.to_s.match(/\s*ie/i).nil?
565
+ end
178
566
 
179
- hit=nil
567
+ def isFirefox?(drv=nil)
180
568
 
181
- if isChrome?(drv)
569
+ if drv.nil?
570
+ drv = @driverList[0][:drv]
571
+ end
572
+
573
+ Browza::Manager.instance._isBrowser?(drv, 'firefox')
574
+ end
575
+
576
+
577
+ def switch_into_frame(drv, id)
578
+ @logger.debug __FILE__ + (__LINE__).to_s + "[enter]: switch_into_frame(#{drv.class}, #{id})"
579
+ _fcnId = '[switch_into_frame]'
580
+ hit = nil
581
+
582
+ # _addDriver( { :id => id, :drv => @drv, :is_sauce => true })
583
+ if isChrome?(drv) || !@driverList[0][:is_sauce] # 5150|| isFirefox?(drv)
584
+
585
+ # drv.switch_to.default_content
182
586
 
183
587
  @logger.debug __FILE__ + (__LINE__).to_s + "#{_fcnId}: switch on Chrome browser"
184
588
  bframes = drv.find_elements(:xpath, '//iframe')
@@ -191,6 +595,7 @@ class Manager
191
595
  @logger.debug __FILE__ + (__LINE__).to_s + "#{_fcnId}: //frame : #{bframes.size}"
192
596
  end
193
597
 
598
+
194
599
  for i in 0 .. bframes.size - 1
195
600
  begin
196
601
 
@@ -221,9 +626,11 @@ class Manager
221
626
 
222
627
  else
223
628
  # Firefox, IE
224
- @logger.debug __FILE__ + (__LINE__).to_s + "#{_fcnId}: drv.switch_to.frame(#{id.to_s}";
629
+ @logger.debug __FILE__ + (__LINE__).to_s + "[switch_into_frame]: drv.switch_to.frame(#{id.to_s}";
225
630
 
226
631
  hit = drv.switch_to.frame(id.to_s.strip)
632
+
633
+ @logger.debug __FILE__ + (__LINE__).to_s + " [switch_into_frame]: #{hit} - #{id}"
227
634
  end
228
635
 
229
636
  @logger.debug __FILE__ + (__LINE__).to_s + " switch_into_frame(#{id}) => #{hit}"
@@ -231,9 +638,9 @@ class Manager
231
638
  end
232
639
 
233
640
 
234
- def switch_frame(e)
235
-
236
- drv = @drv
641
+ def switch_frame(e, drv=nil)
642
+ rc = true
643
+ drv = @driverList[0][:drv] if drv.nil?
237
644
  @logger.debug __FILE__ + (__LINE__).to_s + "\n\n== self.switch_frame(#{e}) =="
238
645
  frames=nil
239
646
  if e.is_a?(Hash) && e.has_key?('page') && e['page'].has_key?('frames')
@@ -251,6 +658,7 @@ class Manager
251
658
  # frame_list=frames.split(/(frame\(.*\))\.(?=[\w])/)
252
659
  frame_list=frames.split(/\.(?=frame)/)
253
660
 
661
+ @logger.debug __FILE__+ (__LINE__).to_s + " [switch_frame]: default_content"
254
662
  drv.switch_to.default_content
255
663
 
256
664
  frame_list.each do |_f|
@@ -263,9 +671,10 @@ class Manager
263
671
 
264
672
  # Swtich based on browser type
265
673
 
266
- if isChrome?(drv)
267
- if switch_into_frame(_id).nil?
674
+ if isChrome?(drv) || !@driverList[0][:is_sauce]# 5150|| isFirefox?(drv)
675
+ if switch_into_frame(drv, _id).nil?
268
676
  @logger.debug __FILE__ + (__LINE__).to_s + " Frame with name/id #{_id} not found"
677
+ rc = false
269
678
  break
270
679
  else
271
680
  @logger.debug __FILE__ + (__LINE__).to_s + " Sucessfully switched frame into #{_id}"
@@ -275,32 +684,18 @@ class Manager
275
684
  drv.switch_to.frame _id
276
685
  end
277
686
 
278
- if false
279
-
280
- if drv.browser.to_s.match(/firefox/i)
281
- @logger.debug __FILE__ + (__LINE__).to_s + " [firefox]: switch_to.frame #{_id}"
282
- drv.switch_to.frame _id
283
- else
284
-
285
- if switch_into_frame(_id).nil?
286
- @logger.debug __FILE__ + (__LINE__).to_s + " Frame with name/id #{_id} not found"
287
- break
288
- else
289
- @logger.debug __FILE__ + (__LINE__).to_s + " Sucessfully switched frame into #{_id}"
290
- end
291
- end
292
-
293
- end
294
-
295
-
296
687
  end
297
688
 
298
689
  end
299
690
 
300
691
  end
692
+
693
+ rc
301
694
  end
302
695
 
303
- def findLocator(_locator)
696
+ def findLocator(_locator, drv=nil)
697
+ drv = @driverList[0][:drv] if drv.nil?
698
+
304
699
  @logger.debug __FILE__ + (__LINE__).to_s + " [findLocator]: #{_locator} sz: #{@appModels.length}"
305
700
  obj = nil
306
701
  _hit = nil
@@ -315,8 +710,6 @@ class Manager
315
710
  ##
316
711
  pageObject = m.getPageElement(_locator)
317
712
 
318
- @logger.debug __FILE__ + (__LINE__).to_s + " pageObject => #{pageObject}"
319
-
320
713
  unless pageObject.nil?
321
714
  _hit = {}
322
715
  if pageObject.has_key?('frame')
@@ -327,6 +720,8 @@ class Manager
327
720
  _hit['locator'] = Appmodel::Model.toBy(pageObject['locator'], m)
328
721
  end
329
722
 
723
+ @logger.debug __FILE__ + (__LINE__).to_s + " pageObject => #{pageObject}"
724
+
330
725
  break
331
726
  end
332
727
 
@@ -339,42 +734,47 @@ class Manager
339
734
  elsif _locator.is_a?(String)
340
735
  _hit = Appmodel::Model.parseLocator(_locator)
341
736
  elsif _locator.is_a?(Hash)
342
- _hit = { 'locator' => _locator[:css] } if _locator.has_key?(:css)
343
- _hit = { 'locator' => _locator['css'] } if _locator.has_key?('css')
344
- _hit = { 'locator' => _locator[:xpath] } if _locator.has_key?(:xpath)
345
- _hit = { 'locator' => _locator[:xpath] } if _locator.has_key?('xpath')
737
+ _hit = { 'locator' => _locator[:css] } if _locator.has_key?(:css)
738
+ _hit = { 'locator' => _locator['css'] } if _locator.has_key?('css')
739
+ _hit = { 'locator' => _locator[:xpath] } if _locator.has_key?(:xpath)
740
+ _hit = { 'locator' => _locator['xpath'] } if _locator.has_key?('xpath')
346
741
 
347
- _hit['frame'] = _locator[:frame] if _locator.has_key?(:frame)
742
+ _hit['frame'] = _locator[:frame] if _locator.has_key?(:frame)
348
743
  _hit['frame'] = _locator['frame'] if _locator.has_key?('frame')
349
744
  end
350
745
 
746
+ @logger.debug __FILE__ + (__LINE__).to_s + " hit => #{_hit}"
747
+
351
748
  if _hit.is_a?(Hash)
352
749
 
353
750
  2.times {
354
751
 
355
752
  begin
356
- if _hit.has_key?('frame')
357
- @logger.debug __FILE__ + (__LINE__).to_s + "swtich_to_frame : #{_hit['frame']}"
358
- switch_frame(_hit['frame'])
359
- end
753
+ rcFrame = true
360
754
 
361
- if _hit.has_key?('locator')
362
- obj = getElement(_hit['locator'], @drv, @defaultTimeout)
755
+ if _hit.has_key?('frame')
756
+ @logger.debug __FILE__ + (__LINE__).to_s + " [findLocator]: swtich_to_frame : #{_hit['frame']}"
757
+ drv.switch_to.default_content
758
+ rcFrame = switch_frame(_hit['frame'], drv)
363
759
  end
364
760
 
365
- if !obj.nil?
366
- break
761
+ if rcFrame && _hit.has_key?('locator')
762
+ obj = getElement(_hit['locator'], drv, @defaultTimeout)
763
+ if !obj.nil?
764
+ break
765
+ end
367
766
  end
368
767
 
369
768
  sleep(0.25)
370
769
 
371
770
  rescue => e
771
+ @logger.debug __FILE__ + (__LINE__).to_s + " Exception: #{e.class}"
372
772
  ;
373
773
  end
374
774
  }
375
775
 
376
776
  else
377
- obj = getElement(Appmodel::Model.toBy(_locator), @drv, @defaultTimeout)
777
+ obj = getElement(Appmodel::Model.toBy(_locator), drv, @defaultTimeout)
378
778
  end
379
779
 
380
780
  @logger.debug __FILE__ + (__LINE__).to_s + " [return findLocator(#{_locator})] : #{_hit}"
@@ -383,61 +783,89 @@ class Manager
383
783
  obj
384
784
  end
385
785
 
786
+ def getDate()
787
+ return @driverList[0][:drv].execute_script('var s = new Date().toString(); return s')
788
+ end
386
789
 
387
790
  ##
388
791
  # Browza.instance.click('page(sideNav).get(desktop)')
389
792
  ##
390
793
  def click(_locator, _drv=nil, _timeout=30)
794
+
795
+ @logger.debug __FILE__ + (__LINE__).to_s + " click(#{_locator})"
391
796
  rc = false
392
797
 
393
- # obj = getElement(findLocator(_locator), _drv, _timeout)
394
- @drv.switch_to.default_content
395
- obj = findLocator(_locator)
396
- if !obj.nil?
397
- obj.click
398
- rc=true
399
- end
798
+ @driverList.each do |b|
799
+ begin
800
+ drv=b[:drv]
400
801
 
401
- rc
402
- end
802
+ obj = nil
403
803
 
404
- def highlight(_locator, _drv=nil, _timeout=30)
405
- rc = false
406
- style={"color" => 'rgb(255, 16, 16)'}
407
- color="rgb(255, 0, 0)"
804
+ # obj = findLocator(_locator, drv)
408
805
 
409
- obj = findLocator(_locator)
410
- if !obj.nil?
806
+ isDisplayed = Selenium::WebDriver::Wait.new(timeout: _timeout).until {
807
+ obj = findLocator(_locator, drv)
808
+ obj.is_a?(Selenium::WebDriver::Element) && obj.displayed? && obj.enabled?
809
+ }
411
810
 
811
+ # drv.action.move_to(obj).perform
812
+ scrollElementIntoMiddle = "var viewPortHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);"
813
+ + "var elementTop = arguments[0].getBoundingClientRect().top;"
814
+ + "window.scrollBy(0, elementTop-(viewPortHeight/2));";
412
815
 
413
- if style.has_key?("color")
414
816
 
415
- color=style.has_key?("color")? style["color"] : 'rgb(255, 16, 16)'
817
+ # drv.execute_script(scrollElementIntoMiddle, obj)
818
+ # drv.execute_script("arguments[0].scrollIntoView(true);", obj);
416
819
 
417
- _c = style["color"]
418
820
 
419
- # TODO: refactor with command 'highlight.rb'
821
+ @logger.debug __FILE__ + (__LINE__).to_s + " [click]: obj => #{obj.class} : #{isDisplayed}"
420
822
 
421
- if _c.match(/\s*blue/i)
422
- color='rgb(0, 0, 255)'
423
- elsif _c.match(/\s*red/i)
424
- color='rgb(255, 0, 0)'
425
- elsif _c.match(/\s*yellow/i)
426
- color='rgb(255, 255, 0)'
427
- elsif _c.match(/\s*green/i)
428
- color='rgb(0, 255, 0)'
429
- elsif _c.match(/\s*gray/i)
430
- color='rgb(128, 128, 128)'
823
+ if !obj.nil? && isDisplayed && obj.is_a?(Selenium::WebDriver::Element)
824
+ @logger.debug __FILE__ + (__LINE__).to_s + " clicked #{_locator}"
825
+ obj.click
826
+ rc = true
431
827
  end
828
+ rescue => ex
829
+ @logger.debug __FILE__ + (__LINE__).to_s + " #{ex.class}"
830
+ @logger.debug "Backtrace:\n\t#{ex.backtrace.join("\n\t")}"
831
+ end
832
+ end
833
+
834
+ unless rc
835
+ @logger.debug __FILE__ + (__LINE__).to_s + " WARN: unable to click #{_locator}"
836
+ end
432
837
 
838
+ @logger.debug __FILE__ + (__LINE__).to_s + " ==== [click]: #{_locator} = #{rc} ===="
839
+ rc
840
+ end
841
+
842
+ def highlight(_locator, color='red', _drv=nil, _timeout=30)
843
+ rc = false
844
+ rgb=nil
845
+
846
+ obj = findLocator(_locator)
847
+ if !obj.nil?
848
+ if color.match(/\s*blue/i)
849
+ rgb='rgb(0, 0, 255)'
850
+ elsif color.match(/\s*red/i)
851
+ rgb='rgb(255, 0, 0)'
852
+ elsif color.match(/\s*yellow/i)
853
+ rgb='rgb(255, 255, 0)'
854
+ elsif color.match(/\s*green/i)
855
+ rgb='rgb(0, 255, 0)'
856
+ elsif color.match(/\s*gray/i)
857
+ rgb='rgb(128, 128, 128)'
433
858
  end
434
859
 
435
- border=style.has_key?("border")? style["border"] : 1
860
+ border = 2
436
861
 
437
- parents = ""
862
+ begin
863
+ @drv.execute_script("hlt = function(c) { c.style.border='solid #{border}px #{rgb}'; }; return hlt(arguments[0]);", obj)
864
+ rc=true
865
+ rescue => ex
866
+ @logger.warn __FILE__ + (__LINE__).to_s + " #{ex.class}"
867
+ end
438
868
 
439
- @drv.execute_script("hlt = function(c) { c.style.border='solid #{border}px #{color}'; }; return hlt(arguments[0]);", obj)
440
- rc=true
441
869
  end
442
870
 
443
871
  obj.is_a?(Selenium::WebDriver::Element) && rc
@@ -472,19 +900,21 @@ class Manager
472
900
  obj = findLocator(_locator)
473
901
  if !obj.nil?
474
902
 
475
- if _text.match(/\s*__CLEAR__\s*$/)
476
- _text = :clear
477
- elsif _text.match(/\s*__DOWN__\s*$/)
478
- _text = :arrow_down
479
- elsif _text.match(/\s*__LEFT__\s*$/)
480
- _text = :arrow_left
481
- elsif _text.match(/\s*__RIGHT__\s*$/)
482
- _text = :arrow_right
483
- elsif _text.match(/\s*__UP__\s*$/)
484
- _text = :arrow_up
485
- elsif _text.match(/\s*__TAB__\s*$/)
486
- _text = :tab
487
- elsif _text.match(/\s*__SHIFT_TAB__\s*$/)
903
+ if _text.match(/\s*__CLEAR__\s*$/i)
904
+ _text = :clear
905
+ elsif _text.match(/\s*__DOWN__\s*$/i)
906
+ _text = :arrow_down
907
+ elsif _text.match(/\s*__ENTER__\s*$/i)
908
+ _text = :enter
909
+ elsif _text.match(/\s*__LEFT__\s*$/i)
910
+ _text = :arrow_left
911
+ elsif _text.match(/\s*__RIGHT__\s*$/i)
912
+ _text = :arrow_right
913
+ elsif _text.match(/\s*__UP__\s*$/i)
914
+ _text = :arrow_up
915
+ elsif _text.match(/\s*__TAB__\s*$/i)
916
+ _text = :tab
917
+ elsif _text.match(/\s*__SHIFT_TAB__\s*$/i)
488
918
  @drv.action.key_down(:shift).send_keys(:tab).perform
489
919
  @drv.action.key_up(:shift).perform
490
920
  rc = true
@@ -500,15 +930,14 @@ class Manager
500
930
  rc
501
931
  end
502
932
 
503
- def displayed?(_locator, _drv=nil, _timeout=30)
504
- rc=false
505
933
 
506
- # obj=getElement(findLocator(_locator), _drv, _timeout)
934
+ def isNotDisplayed?(_locator, _timeout=10)
935
+ !displayed?(_locator, getDriver(), _timeout)
936
+ end
937
+
938
+ def displayed?(_locator, _drv=nil, _timeout=30)
507
939
  obj = findLocator(_locator)
508
- if !obj.nil?
509
- rc=obj.displayed?
510
- end
511
- rc
940
+ obj.is_a?(Selenium::WebDriver::Element) && obj.displayed?
512
941
  end
513
942
 
514
943
  def focusedText()
@@ -517,8 +946,30 @@ class Manager
517
946
  end
518
947
 
519
948
  def focusedValue()
520
- activeElt = @drv.switch_to.active_element
521
- activeElt.attribute('value')
949
+ v = nil
950
+ begin
951
+ activeElt = @drv.switch_to.active_element
952
+ v = activeElt.attribute('value')
953
+ rescue => ex
954
+ @logger.warn __FILE__ + (__LINE__).to_s + " #{ex.class}"
955
+ @logger.warn "Backtrace:\n\t#{ex.backtrace.join("\n\t")}"
956
+ end
957
+
958
+ v
959
+ end
960
+
961
+ def focusedValue?(s, _timeout=10)
962
+ rc = false
963
+
964
+ Selenium::WebDriver::Wait.new(timeout: _timeout).until {
965
+ activeElt = @drv.switch_to.active_element
966
+ _v = activeElt.attribute('value')
967
+ if _v.match(/#{s}/)
968
+ rc = true
969
+ end
970
+
971
+ rc
972
+ }
522
973
  end
523
974
 
524
975
  def isFocused?(_locator)
@@ -537,32 +988,139 @@ class Manager
537
988
  end
538
989
 
539
990
 
991
+ def isVisible?(_locator, expected = true, _timeout = 30)
992
+ obj = nil
993
+ rc = Selenium::WebDriver::Wait.new(timeout: _timeout).until {
994
+ obj = findLocator(_locator, drv)
995
+ obj.is_a?(Selenium::WebDriver::Element) && obj.displayed?
996
+ }
540
997
 
541
- def press(k, n=1)
998
+ @logger.debug __FILE__ + (__LINE__).to_s + " isVisible?(#{_locator}) : #{rc}"
999
+ rc == expected
1000
+ end
542
1001
 
543
- n.times {
544
- if k.match(/^\s*tab/i)
545
- activeElt = @drv.switch_to.active_element
546
- activeElt.send_keys(:tab)
547
- elsif k.match(/^\s*clear\s*$/)
548
- activeElt = @drv.switch_to.active_element
549
- activeElt.clear
550
- elsif k.match(/\s*^enter/i)
551
- activeElt = @drv.switch_to.active_element
552
- activeElt.send_keys(:enter)
553
- elsif k.match(/\s*^down/i)
554
- activeElt = @drv.switch_to.active_element
555
- activeElt.send_keys(:arrow_down)
556
- elsif k.match(/\s*^up/i)
557
- activeElt = @drv.switch_to.active_element
558
- activeElt.send_keys(:arrow_up)
559
- elsif k.match(/\s*__SHIFT_TAB__\s*$/i)
560
- @drv.action.key_down(:shift).send_keys(:tab).perform
561
- @drv.action.key_up(:shift).perform
1002
+
1003
+ def isValue?(_locator, regex=nil, _timeout = 30)
1004
+ @logger.debug __FILE__ + (__LINE__).to_s + " isValue?(#{_locator}, #{regex})"
1005
+ rc = false
1006
+
1007
+ begin
1008
+ expected = Regexp.new(regex)
1009
+ drv = @driverList[0][:drv]
1010
+ obj = nil
1011
+
1012
+ isExists = Selenium::WebDriver::Wait.new(timeout: _timeout).until {
1013
+ obj = findLocator(_locator, drv)
1014
+ if obj.is_a?(Selenium::WebDriver::Element)
1015
+ rc = !expected.match(obj.attribute('value')).nil? || regex==obj.attribute('value')
1016
+ end
1017
+
1018
+ rc
1019
+ }
1020
+
1021
+ @logger.debug __FILE__ + (__LINE__).to_s + " | obj : #{obj} => #{isExists}"
1022
+
1023
+ if false && !obj.nil? && isExists
1024
+ @logger.debug __FILE__ + (__LINE__).to_s + " | obj.value: #{obj.attribute('value')}"
1025
+ expected = Regexp.new(regex)
1026
+ rc = !expected.match(obj.attribute('value')).nil? || regex==obj.attribute('value')
1027
+ end
1028
+
1029
+ rescue => ex
1030
+ @logger.warn __FILE__ + (__LINE__).to_s + " #{ex.class}"
1031
+ @logger.warn "Backtrace:\n\t#{ex.backtrace.join("\n\t")}"
1032
+ end
1033
+
1034
+ @logger.debug __FILE__ + (__LINE__).to_s + " [return]: isValue?(#{_locator}, #{regex}) : #{rc}"
1035
+ rc
1036
+ end
1037
+
1038
+
1039
+ def isText?(_locator, regex=nil)
1040
+ @logger.debug __FILE__ + (__LINE__).to_s + " isText?(#{_locator}, #{regex})"
1041
+ rc = false
1042
+
1043
+ begin
1044
+ obj = findLocator(_locator)
1045
+
1046
+ @logger.debug __FILE__ + (__LINE__).to_s + " | obj : #{obj}"
1047
+
1048
+ if !obj.nil?
1049
+ @logger.debug __FILE__ + (__LINE__).to_s + " | obj.text: #{obj.text}"
1050
+ expected = Regexp.new(regex)
1051
+ rc = !expected.match(obj.text).nil? || regex==obj.text
1052
+ end
1053
+
1054
+ rescue => ex
1055
+ @logger.warn __FILE__ + (__LINE__).to_s + " #{ex.class}"
1056
+ @logger.warn "Backtrace:\n\t#{ex.backtrace.join("\n\t")}"
1057
+ end
1058
+
1059
+ @logger.debug __FILE__ + (__LINE__).to_s + " [return]: isText?(#{_locator}, #{regex}) : #{rc}"
1060
+ rc
1061
+ end
1062
+
1063
+
1064
+ ##
1065
+ # press('enter')
1066
+ # press('tab', 5)
1067
+ # press('page(main).get(button)', 'enter')
1068
+ ##
1069
+ def press(*p)
1070
+ rc = nil
1071
+
1072
+ if p.length == 1
1073
+ rc = pressKey(p[0], 1)
1074
+ elsif p.length == 2
1075
+
1076
+ if p[1].is_a?(Integer) || p[1].to_s.match(/^\s*\d+$/)
1077
+ rc = pressKey(p[0], p[1].to_i)
562
1078
  else
563
- break
1079
+ rc = type(p[0], p[1])
564
1080
  end
565
- }
1081
+
1082
+ else
1083
+ raise "BROWZA::Press::Unexpected"
1084
+ end
1085
+
1086
+ rc
1087
+ end
1088
+
1089
+ def pressKey(k, n = 1)
1090
+
1091
+ rc = 0
1092
+ begin
1093
+ n.times {
1094
+ if k.match(/^\s*tab/i)
1095
+ activeElt = @drv.switch_to.active_element
1096
+ activeElt.send_keys(:tab)
1097
+ elsif k.match(/^\s*clear\s*$/)
1098
+ activeElt = @drv.switch_to.active_element
1099
+ activeElt.clear
1100
+ elsif k.match(/\s*^enter/i)
1101
+ activeElt = @drv.switch_to.active_element
1102
+ activeElt.send_keys(:enter)
1103
+ elsif k.match(/\s*^(down|__down__|arrow_down)/i)
1104
+ activeElt = @drv.switch_to.active_element
1105
+ activeElt.send_keys(:arrow_down)
1106
+ elsif k.match(/\s*^up/i)
1107
+ activeElt = @drv.switch_to.active_element
1108
+ activeElt.send_keys(:arrow_up)
1109
+ elsif k.match(/\s*__SHIFT_TAB__\s*$/i)
1110
+ @drv.action.key_down(:shift).send_keys(:tab).perform
1111
+ @drv.action.key_up(:shift).perform
1112
+ else
1113
+ break
1114
+ end
1115
+
1116
+ rc += 1
1117
+ }
1118
+
1119
+ rescue => ex
1120
+ ;
1121
+ end
1122
+
1123
+ rc
566
1124
  end
567
1125
 
568
1126
  def selected?(_locator, _drv=nil, _timeout=30)
@@ -590,6 +1148,45 @@ class Manager
590
1148
  end
591
1149
 
592
1150
 
1151
+ def hasStyle?(_locator, tag, expected = nil, _timeout = 30)
1152
+ @logger.debug __FILE__ + (__LINE__).to_s + " hasStyle?(#{_locator})"
1153
+ rc = nil
1154
+
1155
+ @driverList.each do |b|
1156
+ begin
1157
+ drv = b[:drv]
1158
+
1159
+ @logger.debug __FILE__ + (__LINE__).to_s + " [hasStyle]: switch_to.default_content"
1160
+ drv.switch_to.default_content
1161
+ obj = findLocator(_locator, drv)
1162
+
1163
+ isDisplayed = Selenium::WebDriver::Wait.new(timeout: _timeout).until {
1164
+ obj = findLocator(_locator, drv)
1165
+ obj.is_a?(Selenium::WebDriver::Element)
1166
+ }
1167
+
1168
+ if !obj.nil?
1169
+ @logger.debug __FILE__ + (__LINE__).to_s + " style #{_locator}"
1170
+ rc = obj.style(tag)
1171
+ end
1172
+ rescue => ex
1173
+ @logger.warn __FILE__ + (__LINE__).to_s + " #{ex.class}"
1174
+ @logger.warn "Backtrace:\n\t#{ex.backtrace.join("\n\t")}"
1175
+ end
1176
+ end
1177
+
1178
+ unless expected.nil?
1179
+ regex = Regexp.new(expected)
1180
+ rc = !regex.match(rc.to_s).nil? || (expected.to_s == rc.to_s)
1181
+
1182
+ @logger.debug __FILE__ + (__LINE__).to_s + " WARN: unable to get style #{tag} for #{_locator}"
1183
+ end
1184
+
1185
+ @logger.debug __FILE__ + (__LINE__).to_s + " hasStyle(#{_locator}, #{tag}) : #{rc.to_s}"
1186
+ rc
1187
+ end
1188
+
1189
+
593
1190
  end
594
1191
 
595
1192