@@ -371,30 +371,11 @@ def initialize(opts = {})
371
371
raise 'opts must be a hash' unless opts . is_a? Hash
372
372
373
373
opts = Appium . symbolize_keys opts
374
-
375
374
@caps = Capabilities . init_caps_for_appium ( opts [ :caps ] || { } )
376
375
377
376
appium_lib_opts = opts [ :appium_lib ] || { }
378
377
379
- # appium_lib specific values
380
- @custom_url = appium_lib_opts . fetch :server_url , false
381
- @export_session = appium_lib_opts . fetch :export_session , false
382
- @default_wait = appium_lib_opts . fetch :wait , 0
383
- @sauce_username = appium_lib_opts . fetch :sauce_username , ENV [ 'SAUCE_USERNAME' ]
384
- @sauce_username = nil if !@sauce_username || ( @sauce_username . is_a? ( String ) && @sauce_username . empty? )
385
- @sauce_access_key = appium_lib_opts . fetch :sauce_access_key , ENV [ 'SAUCE_ACCESS_KEY' ]
386
- @sauce_access_key = nil if !@sauce_access_key || ( @sauce_access_key . is_a? ( String ) && @sauce_access_key . empty? )
387
- @sauce_endpoint = appium_lib_opts . fetch :sauce_endpoint , ENV [ 'SAUCE_ENDPOINT' ]
388
- @sauce_endpoint = 'ondemand.saucelabs.com:443/wd/hub' if
389
- !@sauce_endpoint || ( @sauce_endpoint . is_a? ( String ) && @sauce_endpoint . empty? )
390
- @appium_port = appium_lib_opts . fetch :port , 4723
391
- # timeout and interval used in ::Appium::Comm.wait/wait_true
392
- @appium_wait_timeout = appium_lib_opts . fetch :wait_timeout , 30
393
- @appium_wait_interval = appium_lib_opts . fetch :wait_interval , 0.5
394
-
395
- # to pass it in Selenium.new.
396
- # `listener = opts.delete(:listener)` is called in Selenium::Driver.new
397
- @listener = appium_lib_opts . fetch :listener , nil
378
+ set_appium_lib_specific_values ( appium_lib_opts )
398
379
399
380
# Path to the .apk, .app or .app.zip.
400
381
# The path can be local or remote for Sauce.
@@ -407,6 +388,9 @@ def initialize(opts = {})
407
388
@appium_device = @appium_device . is_a? ( Symbol ) ? @appium_device : @appium_device . downcase . strip . intern if @appium_device
408
389
409
390
@automation_name = @caps [ :automationName ] if @caps [ :automationName ]
391
+ @automation_name = if @automation_name
392
+ @automation_name . is_a? ( Symbol ) ? @automation_name : @automation_name . downcase . strip . intern
393
+ end
410
394
411
395
# load common methods
412
396
extend Appium ::Common
@@ -416,7 +400,10 @@ def initialize(opts = {})
416
400
extend Appium ::Android
417
401
else
418
402
extend Appium ::Ios
419
- extend Appium ::Ios ::XcuitestGesture if automation_name_is_xcuitest? # Override touch actions
403
+ if automation_name_is_xcuitest? # Override touch actions
404
+ extend Appium ::Ios ::Xcuitest
405
+ extend Appium ::Ios ::Xcuitest ::Gesture
406
+ end
420
407
end
421
408
422
409
# apply os specific patches
@@ -442,6 +429,33 @@ def initialize(opts = {})
442
429
self # return newly created driver
443
430
end
444
431
432
+ private
433
+
434
+ def set_appium_lib_specific_values ( appium_lib_opts )
435
+ @custom_url = appium_lib_opts . fetch :server_url , false
436
+ @export_session = appium_lib_opts . fetch :export_session , false
437
+ @default_wait = appium_lib_opts . fetch :wait , 0
438
+
439
+ @sauce_username = appium_lib_opts . fetch :sauce_username , ENV [ 'SAUCE_USERNAME' ]
440
+ @sauce_username = nil if !@sauce_username || ( @sauce_username . is_a? ( String ) && @sauce_username . empty? )
441
+ @sauce_access_key = appium_lib_opts . fetch :sauce_access_key , ENV [ 'SAUCE_ACCESS_KEY' ]
442
+ @sauce_access_key = nil if !@sauce_access_key || ( @sauce_access_key . is_a? ( String ) && @sauce_access_key . empty? )
443
+ @sauce_endpoint = appium_lib_opts . fetch :sauce_endpoint , ENV [ 'SAUCE_ENDPOINT' ]
444
+ @sauce_endpoint = 'ondemand.saucelabs.com:443/wd/hub' if
445
+ !@sauce_endpoint || ( @sauce_endpoint . is_a? ( String ) && @sauce_endpoint . empty? )
446
+
447
+ @appium_port = appium_lib_opts . fetch :port , 4723
448
+ # timeout and interval used in ::Appium::Comm.wait/wait_true
449
+ @appium_wait_timeout = appium_lib_opts . fetch :wait_timeout , 30
450
+ @appium_wait_interval = appium_lib_opts . fetch :wait_interval , 0.5
451
+
452
+ # to pass it in Selenium.new.
453
+ # `listener = opts.delete(:listener)` is called in Selenium::Driver.new
454
+ @listener = appium_lib_opts . fetch :listener , nil
455
+ end
456
+
457
+ public
458
+
445
459
# Returns a hash of the driver attributes
446
460
def driver_attributes
447
461
{
@@ -469,13 +483,13 @@ def device_is_android?
469
483
# Return true if automationName is 'XCUITest'
470
484
# @return [Boolean]
471
485
def automation_name_is_xcuitest?
472
- !@automation_name . nil? && 'xcuitest' . casecmp ( @automation_name ) . zero?
486
+ !@automation_name . nil? && @automation_name == :xcuitest
473
487
end
474
488
475
489
# Return true if automationName is 'uiautomator2'
476
490
# @return [Boolean]
477
491
def automation_name_is_uiautomator2?
478
- !@automation_name . nil? && 'uiautomator2' . casecmp ( @automation_name ) . zero?
492
+ !@automation_name . nil? && @automation_name == :uiautomator2
479
493
end
480
494
481
495
# Return true if the target Appium server is over REQUIRED_VERSION_XCUITEST.
@@ -511,11 +525,11 @@ def check_server_version_xcuitest
511
525
def appium_server_version
512
526
driver . remote_status
513
527
rescue Selenium ::WebDriver ::Error ::WebDriverError => ex
514
- raise unless ex . message . include? ( 'content-type=""' )
528
+ raise :: Appium :: Error :: ServerError unless ex . message . include? ( 'content-type=""' )
515
529
# server (TestObject for instance) does not respond to status call
516
530
{ }
517
531
rescue Selenium ::WebDriver ::Error ::ServerError => e
518
- raise unless e . message . include? ( 'status code 500' )
532
+ raise :: Appium :: Error :: ServerError unless e . message . include? ( 'status code 500' )
519
533
# driver.remote_status returns 500 error for using selenium grid
520
534
{ }
521
535
end
@@ -611,11 +625,33 @@ def driver_quit
611
625
end
612
626
613
627
# Creates a new global driver and quits the old one if it exists.
628
+ # You can customise http_client as the following
629
+ #
630
+ # @example
631
+ # ```ruby
632
+ # require 'rubygems'
633
+ # require 'appium_lib'
634
+ #
635
+ # # platformName takes a string or a symbol.
636
+ #
637
+ # # Start iOS driver
638
+ # opts = {
639
+ # caps: {
640
+ # platformName: :ios,
641
+ # app: '/path/to/MyiOS.app'
642
+ # },
643
+ # appium_lib: {
644
+ # wait_timeout: 30
645
+ # }
646
+ # }
647
+ # custom_http_client = Custom::Http::Client.new(opts)
648
+ # Appium::Driver.new(opts).start_driver(custom_http_client)
614
649
#
615
650
# @return [Selenium::WebDriver] the new global driver
616
- def start_driver
651
+ def start_driver ( http_client =
652
+ Selenium ::WebDriver ::Remote ::Http ::Default . new ( open_timeout : 999_999 , read_timeout : 999_999 ) )
617
653
# open_timeout and read_timeout are explicit wait.
618
- @http_client ||= Selenium :: WebDriver :: Remote :: Http :: Default . new ( open_timeout : 999_999 , read_timeout : 999_999 )
654
+ @http_client ||= http_client
619
655
620
656
begin
621
657
driver_quit
@@ -630,12 +666,7 @@ def start_driver
630
666
@driver . extend Selenium ::WebDriver ::DriverExtensions ::HasLocation
631
667
632
668
# export session
633
- if @export_session
634
- # rubocop:disable Style/RescueModifier
635
- File . open ( '/tmp/appium_lib_session' , 'w' ) do |f |
636
- f . puts @driver . session_id
637
- end rescue nil
638
- end
669
+ write_session_id ( @driver . session_id ) if @export_session
639
670
rescue Errno ::ECONNREFUSED
640
671
raise "ERROR: Unable to connect to Appium. Is the server running on #{ server_url } ?"
641
672
end
@@ -773,6 +804,13 @@ def x
773
804
774
805
private
775
806
807
+ def write_session_id ( session_id )
808
+ File . open ( '/tmp/appium_lib_session' , 'w' ) { |f | f . puts session_id }
809
+ rescue IOError => e
810
+ ::Appium ::Logger . warn e
811
+ nil
812
+ end
813
+
776
814
# If "automationName" is set only server side, this method set "automationName" attribute into @automation_name.
777
815
# Since @automation_name is set only client side before start_driver is called.
778
816
def set_automation_name_if_nil
0 commit comments