browza 0.0.2.beta2 → 0.0.3

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.
@@ -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