appium_lib_core 1.6.0 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -2
  3. data/CHANGELOG.md +16 -0
  4. data/lib/appium_lib_core/android/device.rb +301 -406
  5. data/lib/appium_lib_core/android/device/clipboard.rb +42 -0
  6. data/lib/appium_lib_core/android/device/emulator.rb +149 -147
  7. data/lib/appium_lib_core/android/device/network.rb +47 -0
  8. data/lib/appium_lib_core/android/device/performance.rb +24 -0
  9. data/lib/appium_lib_core/android/device/screen.rb +39 -0
  10. data/lib/appium_lib_core/android/espresso/bridge.rb +1 -1
  11. data/lib/appium_lib_core/android/uiautomator1/bridge.rb +1 -1
  12. data/lib/appium_lib_core/android/uiautomator2/bridge.rb +1 -1
  13. data/lib/appium_lib_core/android/uiautomator2/device.rb +3 -14
  14. data/lib/appium_lib_core/android/uiautomator2/device/battery.rb +28 -0
  15. data/lib/appium_lib_core/common/base/http_default.rb +5 -1
  16. data/lib/appium_lib_core/device.rb +50 -370
  17. data/lib/appium_lib_core/device/app_management.rb +113 -0
  18. data/lib/appium_lib_core/device/app_state.rb +18 -1
  19. data/lib/appium_lib_core/device/context.rb +48 -0
  20. data/lib/appium_lib_core/device/device_lock.rb +28 -0
  21. data/lib/appium_lib_core/device/file_management.rb +32 -0
  22. data/lib/appium_lib_core/device/image_comparison.rb +1 -3
  23. data/lib/appium_lib_core/device/ime_actions.rb +43 -0
  24. data/lib/appium_lib_core/device/keyboard.rb +26 -0
  25. data/lib/appium_lib_core/device/keyevent.rb +44 -0
  26. data/lib/appium_lib_core/device/screen_record.rb +21 -0
  27. data/lib/appium_lib_core/device/setting.rb +21 -0
  28. data/lib/appium_lib_core/device/touch_actions.rb +22 -0
  29. data/lib/appium_lib_core/device/value.rb +23 -0
  30. data/lib/appium_lib_core/driver.rb +8 -0
  31. data/lib/appium_lib_core/ios/device.rb +70 -101
  32. data/lib/appium_lib_core/ios/device/clipboard.rb +41 -0
  33. data/lib/appium_lib_core/ios/uiautomation/bridge.rb +1 -1
  34. data/lib/appium_lib_core/ios/xcuitest/bridge.rb +2 -2
  35. data/lib/appium_lib_core/ios/xcuitest/device.rb +166 -227
  36. data/lib/appium_lib_core/ios/xcuitest/device/battery.rb +28 -0
  37. data/lib/appium_lib_core/ios/xcuitest/device/performance.rb +40 -0
  38. data/lib/appium_lib_core/ios/xcuitest/device/screen.rb +30 -0
  39. data/lib/appium_lib_core/version.rb +2 -2
  40. data/release_notes.md +12 -0
  41. metadata +21 -2
@@ -4,7 +4,7 @@ module Appium
4
4
  module Espresso
5
5
  module Bridge
6
6
  def self.for(target)
7
- target.extend Appium::Android::Device
7
+ target.extend Appium::Core::Android::Device
8
8
  Core::Android::SearchContext.extend
9
9
  end
10
10
  end
@@ -4,7 +4,7 @@ module Appium
4
4
  module Uiautomator1
5
5
  module Bridge
6
6
  def self.for(target)
7
- target.extend Appium::Android::Device
7
+ target.extend Appium::Core::Android::Device
8
8
  Core::Android::SearchContext.extend
9
9
  end
10
10
  end
@@ -4,7 +4,7 @@ module Appium
4
4
  module Uiautomator2
5
5
  module Bridge
6
6
  def self.for(target)
7
- target.extend Appium::Android::Device
7
+ target.extend Appium::Core::Android::Device
8
8
  Core::Android::SearchContext.extend
9
9
  target.extend Appium::Core::Android::Uiautomator2::Device
10
10
  end
@@ -1,3 +1,5 @@
1
+ require_relative 'device/battery'
2
+
1
3
  module Appium
2
4
  module Core
3
5
  module Android
@@ -27,20 +29,7 @@ module Appium
27
29
 
28
30
  class << self
29
31
  def extended(_mod)
30
- ::Appium::Core::Device.add_endpoint_method(:battery_info) do
31
- def battery_info
32
- response = execute_script 'mobile: batteryInfo', {}
33
-
34
- state = case response['state']
35
- when 2, 3, 4, 5
36
- ::Appium::Core::Device::BatteryStatus::ANDROID[response['state']]
37
- else
38
- Appium::Logger.warn("The state is unknown or undefined: #{response['state']}")
39
- ::Appium::Core::Device::BatteryStatus::ANDROID[1] # :unknown
40
- end
41
- { state: state, level: response['level'] }
42
- end
43
- end
32
+ Battery.add_methods
44
33
  end
45
34
  end # class << self
46
35
  end # module Device
@@ -0,0 +1,28 @@
1
+ module Appium
2
+ module Core
3
+ module Android
4
+ module Uiautomator2
5
+ module Device
6
+ module Battery
7
+ def self.add_methods
8
+ ::Appium::Core::Device.add_endpoint_method(:battery_info) do
9
+ def battery_info
10
+ response = execute_script 'mobile: batteryInfo', {}
11
+
12
+ state = case response['state']
13
+ when 2, 3, 4, 5
14
+ ::Appium::Core::Device::BatteryStatus::ANDROID[response['state']]
15
+ else
16
+ ::Appium::Logger.warn("The state is unknown or undefined: #{response['state']}")
17
+ ::Appium::Core::Device::BatteryStatus::ANDROID[1] # :unknown
18
+ end
19
+ { state: state, level: response['level'] }
20
+ end
21
+ end
22
+ end
23
+ end # module Battery
24
+ end # module Device
25
+ end # module Uiautomator2
26
+ end # module Android
27
+ end # module Core
28
+ end # module Appium
@@ -5,7 +5,11 @@ module Appium
5
5
  class Base
6
6
  module Http
7
7
  class Default < Selenium::WebDriver::Remote::Http::Default
8
- DEFAULT_HEADERS = { 'Accept' => CONTENT_TYPE, 'User-Agent' => "appium/ruby_lib_core/#{VERSION}" }.freeze
8
+ DEFAULT_HEADERS = {
9
+ 'Accept' => CONTENT_TYPE,
10
+ 'Content-Type' => "#{CONTENT_TYPE}; charset=UTF-8",
11
+ 'User-Agent' => "appium/ruby_lib_core/#{VERSION}"
12
+ }.freeze
9
13
  end
10
14
  end
11
15
  end
@@ -1,9 +1,20 @@
1
1
  require_relative 'common/touch_action/touch_actions'
2
2
  require_relative 'common/touch_action/multi_touch'
3
+
3
4
  require_relative 'device/screen_record'
4
5
  require_relative 'device/app_state'
5
6
  require_relative 'device/clipboard_content_type'
6
7
  require_relative 'device/image_comparison'
8
+ require_relative 'device/app_management'
9
+ require_relative 'device/keyboard'
10
+ require_relative 'device/file_management'
11
+ require_relative 'device/touch_actions'
12
+ require_relative 'device/device_lock'
13
+ require_relative 'device/ime_actions'
14
+ require_relative 'device/context'
15
+ require_relative 'device/keyevent'
16
+ require_relative 'device/setting'
17
+ require_relative 'device/value'
7
18
 
8
19
  require 'base64'
9
20
 
@@ -224,26 +235,44 @@ module Appium
224
235
  # @driver.keyevent 82
225
236
  #
226
237
 
227
- # @!method press_keycode(key, metastate = nil)
238
+ # @!method press_keycode(key, metastate: [], flags: [])
228
239
  # Press keycode on the device.
229
240
  # http://developer.android.com/reference/android/view/KeyEvent.html
230
- # @param [integer] key The key to press.
231
- # @param [String] metastate The state the metakeys should be in when pressing the key.
241
+ # @param [Integer] key The key to press. The values which have `KEYCODE_` prefix in http://developer.android.com/reference/android/view/KeyEvent.html
242
+ # e.g.: KEYCODE_HOME is `3` or `0x00000003`
243
+ # @param [[Integer]] metastate: The state the metakeys should be in when pressing the key. Default is empty Array.
244
+ # Metastate have `META_` prefix in https://developer.android.com/reference/android/view/KeyEvent.html
245
+ # e.g.: META_SHIFT_ON is `1` or `0x00000001`
246
+ # @param [[Integer]] flags: Native Android flag value. Several flags can be combined into a single key event.
247
+ # Default is empty Array. Can set multiple flags as Array.
248
+ # Flags have `FLAG_` prefix in http://developer.android.com/reference/android/view/KeyEvent.html
249
+ # e.g.: FLAG_CANCELED is `32` or `0x00000020`
232
250
  #
233
251
  # @example
234
252
  #
235
- # @driver.press_keycode 82
253
+ # @driver.press_keycode 66
254
+ # @driver.press_keycode 66, flags: [0x02]
255
+ # @driver.press_keycode 66, metastate: [1], flags: [32]
236
256
  #
237
257
 
238
- # @!method long_press_keycode(key, metastate = nil)
258
+ # @!method long_press_keycode(key, metastate: [], flags: [])
239
259
  # Long press keycode on the device.
240
260
  # http://developer.android.com/reference/android/view/KeyEvent.html
241
- # @param [integer] key The key to long press.
242
- # @param [String] metastate The state the metakeys should be in when long pressing the key.
261
+ # @param [Integer] key The key to long press. The values which have `KEYCODE_` prefix in http://developer.android.com/reference/android/view/KeyEvent.html
262
+ # e.g.: KEYCODE_HOME is `3` or `0x00000003`
263
+ # @param [[Integer]] metastate: The state the metakeys should be in when pressing the key. Default is empty Array.
264
+ # Metastate have `META_` prefix in https://developer.android.com/reference/android/view/KeyEvent.html
265
+ # e.g.: META_SHIFT_ON is `1` or `0x00000001`
266
+ # @param [[Integer]] flags: Native Android flag value. Several flags can be combined into a single key event.
267
+ # Default is empty Array. Can set multiple flags as Array.
268
+ # Flags have `FLAG_` prefix in http://developer.android.com/reference/android/view/KeyEvent.html
269
+ # e.g.: FLAG_CANCELED is `32` or `0x00000020`
243
270
  #
244
271
  # @example
245
272
  #
246
- # @driver.long_press_keycode 82
273
+ # @driver.long_press_keycode 66
274
+ # @driver.long_press_keycode 66, flags: [0x20, 0x2000]
275
+ # @driver.long_press_keycode 66, metastate: [1], flags: [32, 8192]
247
276
  #
248
277
 
249
278
  # @!method push_file(path, filedata)
@@ -471,32 +500,6 @@ module Appium
471
500
  end
472
501
  end
473
502
 
474
- add_endpoint_method(:set_immediate_value) do
475
- def set_immediate_value(element, *value)
476
- keys = ::Selenium::WebDriver::Keys.encode(value)
477
- execute :set_immediate_value, { id: element.ref }, value: Array(keys)
478
- end
479
- end
480
-
481
- add_endpoint_method(:replace_value) do
482
- def replace_value(element, *value)
483
- keys = ::Selenium::WebDriver::Keys.encode(value)
484
- execute :replace_value, { id: element.ref }, value: Array(keys)
485
- end
486
- end
487
-
488
- add_endpoint_method(:get_settings) do
489
- def get_settings
490
- execute :get_settings, {}
491
- end
492
- end
493
-
494
- add_endpoint_method(:update_settings) do
495
- def update_settings(settings)
496
- execute :update_settings, {}, settings: settings
497
- end
498
- end
499
-
500
503
  add_endpoint_method(:save_viewport_screenshot) do
501
504
  def save_viewport_screenshot(png_path)
502
505
  extension = File.extname(png_path).downcase
@@ -509,16 +512,19 @@ module Appium
509
512
  end
510
513
  end
511
514
 
512
- add_keyevent
513
- add_touch_actions
514
- add_ime_actions
515
- add_handling_context
516
- add_screen_recording
517
- add_app_management
518
- add_device_lock
519
- add_file_management
520
- add_keyboard
521
- Core::Device::ImageComparison.extended
515
+ Value.add_methods
516
+ Setting.add_methods
517
+ KeyEvent.add_methods
518
+ Context.add_methods
519
+ ImeActions.add_methods
520
+ DeviceLock.add_methods
521
+ TouchActions.add_methods
522
+ FileManagement.add_methods
523
+ Keyboard.add_methods
524
+ AppManagement.add_methods
525
+ ScreenRecord.add_methods
526
+ ImageComparison.add_methods
527
+ AppState.add_methods
522
528
  end
523
529
 
524
530
  # def extended
@@ -560,332 +566,6 @@ module Appium
560
566
  block_given? ? class_eval(&Proc.new) : define_method(method) { execute method }
561
567
  end
562
568
  end
563
-
564
- def add_device_lock
565
- add_endpoint_method(:lock) do
566
- def lock(duration = nil)
567
- opts = duration ? { seconds: duration } : {}
568
- execute :lock, {}, opts
569
- end
570
- end
571
-
572
- add_endpoint_method(:device_locked?) do
573
- def device_locked?
574
- execute :device_locked?
575
- end
576
- end
577
-
578
- add_endpoint_method(:unlock) do
579
- def unlock
580
- execute :unlock
581
- end
582
- end
583
- end
584
-
585
- def add_file_management
586
- add_endpoint_method(:push_file) do
587
- def push_file(path, filedata)
588
- encoded_data = Base64.encode64 filedata
589
- execute :push_file, {}, path: path, data: encoded_data
590
- end
591
- end
592
-
593
- add_endpoint_method(:pull_file) do
594
- def pull_file(path)
595
- data = execute :pull_file, {}, path: path
596
- Base64.decode64 data
597
- end
598
- end
599
-
600
- add_endpoint_method(:pull_folder) do
601
- def pull_folder(path)
602
- data = execute :pull_folder, {}, path: path
603
- Base64.decode64 data
604
- end
605
- end
606
- end
607
-
608
- # rubocop:disable Metrics/ParameterLists,Metrics/PerceivedComplexity,Metrics/CyclomaticComplexity
609
- def add_app_management
610
- add_endpoint_method(:launch_app) do
611
- def launch_app
612
- execute :launch_app
613
- end
614
- end
615
-
616
- add_endpoint_method(:close_app) do
617
- def close_app
618
- execute :close_app
619
- end
620
- end
621
-
622
- add_endpoint_method(:close_app) do
623
- def close_app
624
- execute :close_app
625
- end
626
- end
627
-
628
- add_endpoint_method(:reset) do
629
- def reset
630
- execute :reset
631
- end
632
- end
633
-
634
- add_endpoint_method(:app_strings) do
635
- def app_strings(language = nil)
636
- opts = language ? { language: language } : {}
637
- execute :app_strings, {}, opts
638
- end
639
- end
640
-
641
- add_endpoint_method(:background_app) do
642
- def background_app(duration = 0)
643
- execute :background_app, {}, seconds: duration
644
- end
645
- end
646
-
647
- add_endpoint_method(:install_app) do
648
- def install_app(path,
649
- replace: nil,
650
- timeout: nil,
651
- allow_test_packages: nil,
652
- use_sdcard: nil,
653
- grant_permissions: nil)
654
- args = { appPath: path }
655
-
656
- args[:options] = {} unless options?(replace, timeout, allow_test_packages, use_sdcard, grant_permissions)
657
-
658
- args[:options][:replace] = replace unless replace.nil?
659
- args[:options][:timeout] = timeout unless timeout.nil?
660
- args[:options][:allowTestPackages] = allow_test_packages unless allow_test_packages.nil?
661
- args[:options][:useSdcard] = use_sdcard unless use_sdcard.nil?
662
- args[:options][:grantPermissions] = grant_permissions unless grant_permissions.nil?
663
-
664
- execute :install_app, {}, args
665
- end
666
-
667
- private
668
-
669
- def options?(replace, timeout, allow_test_packages, use_sdcard, grant_permissions)
670
- replace.nil? || timeout.nil? || allow_test_packages.nil? || use_sdcard.nil? || grant_permissions.nil?
671
- end
672
- end
673
-
674
- add_endpoint_method(:remove_app) do
675
- def remove_app(id, keep_data: nil, timeout: nil)
676
- # required: [['appId'], ['bundleId']]
677
- args = { appId: id }
678
-
679
- args[:options] = {} unless keep_data.nil? || timeout.nil?
680
- args[:options][:keepData] = keep_data unless keep_data.nil?
681
- args[:options][:timeout] = timeout unless timeout.nil?
682
-
683
- execute :remove_app, {}, args
684
- end
685
- end
686
-
687
- add_endpoint_method(:app_installed?) do
688
- def app_installed?(app_id)
689
- # required: [['appId'], ['bundleId']]
690
- execute :app_installed?, {}, bundleId: app_id
691
- end
692
- end
693
-
694
- add_endpoint_method(:activate_app) do
695
- def activate_app(app_id)
696
- # required: [['appId'], ['bundleId']]
697
- execute :activate_app, {}, bundleId: app_id
698
- end
699
- end
700
-
701
- add_endpoint_method(:terminate_app) do
702
- def terminate_app(app_id, timeout: nil)
703
- # required: [['appId'], ['bundleId']]
704
- #
705
- args = { appId: app_id }
706
-
707
- args[:options] = {} unless timeout.nil?
708
- args[:options][:timeout] = timeout unless timeout.nil?
709
-
710
- execute :terminate_app, {}, args
711
- end
712
- end
713
-
714
- add_endpoint_method(:app_state) do
715
- def app_state(app_id)
716
- # required: [['appId'], ['bundleId']]
717
- response = execute :app_state, {}, appId: app_id
718
-
719
- case response
720
- when 0, 1, 2, 3, 4
721
- ::Appium::Core::Device::AppState::STATUS[response]
722
- else
723
- ::Appium::Logger.debug("Unexpected status in app_state: #{response}")
724
- response
725
- end
726
- end
727
- end
728
- end
729
- # rubocop:enable Metrics/ParameterLists,Metrics/PerceivedComplexity,Metrics/CyclomaticComplexity
730
-
731
- def add_keyevent
732
- # Only for Selendroid
733
- add_endpoint_method(:keyevent) do
734
- def keyevent(key, metastate = nil)
735
- args = { keycode: key }
736
- args[:metastate] = metastate if metastate
737
- execute :keyevent, {}, args
738
- end
739
- end
740
-
741
- add_endpoint_method(:press_keycode) do
742
- def press_keycode(key, metastate = nil)
743
- args = { keycode: key }
744
- args[:metastate] = metastate if metastate
745
- execute :press_keycode, {}, args
746
- end
747
- end
748
-
749
- add_endpoint_method(:long_press_keycode) do
750
- def long_press_keycode(key, metastate = nil)
751
- args = { keycode: key }
752
- args[:metastate] = metastate if metastate
753
- execute :long_press_keycode, {}, args
754
- end
755
- end
756
- end
757
-
758
- def add_keyboard
759
- add_endpoint_method(:hide_keyboard) do
760
- def hide_keyboard(close_key = nil, strategy = nil)
761
- option = {}
762
-
763
- option[:key] = close_key || 'Done' # default to Done key.
764
- option[:strategy] = strategy || :pressKey # default to pressKey
765
-
766
- execute :hide_keyboard, {}, option
767
- end
768
- end
769
-
770
- add_endpoint_method(:is_keyboard_shown) do
771
- def is_keyboard_shown # rubocop:disable Naming/PredicateName for compatibility
772
- execute :is_keyboard_shown
773
- end
774
- end
775
- end
776
-
777
- def add_touch_actions
778
- add_endpoint_method(:touch_actions) do
779
- def touch_actions(actions)
780
- actions = { actions: [actions].flatten }
781
- execute :touch_actions, {}, actions
782
- end
783
- end
784
-
785
- add_endpoint_method(:multi_touch) do
786
- def multi_touch(actions)
787
- execute :multi_touch, {}, actions: actions
788
- end
789
- end
790
- end
791
-
792
- def add_ime_actions
793
- add_endpoint_method(:ime_activate) do
794
- def ime_activate(ime_name)
795
- # from Selenium::WebDriver::Remote::OSS
796
- execute :ime_activate_engine, {}, engine: ime_name
797
- end
798
- end
799
-
800
- add_endpoint_method(:ime_available_engines) do
801
- def ime_available_engines
802
- execute :ime_get_available_engines
803
- end
804
- end
805
-
806
- add_endpoint_method(:ime_active_engine) do
807
- # from Selenium::WebDriver::Remote::OSS
808
- def ime_active_engine
809
- execute :ime_get_active_engine
810
- end
811
- end
812
-
813
- add_endpoint_method(:ime_activated) do
814
- # from Selenium::WebDriver::Remote::OSS
815
- def ime_activated
816
- execute :ime_is_activated
817
- end
818
- end
819
-
820
- add_endpoint_method(:ime_deactivate) do
821
- # from Selenium::WebDriver::Remote::OSS
822
- def ime_deactivate
823
- execute :ime_deactivate, {}
824
- end
825
- end
826
- end
827
-
828
- def add_handling_context
829
- add_endpoint_method(:within_context) do
830
- def within_context(context)
831
- existing_context = current_context
832
- set_context context
833
- if block_given?
834
- result = yield
835
- set_context existing_context
836
- result
837
- else
838
- set_context existing_context
839
- end
840
- end
841
- end
842
-
843
- add_endpoint_method(:switch_to_default_context) do
844
- def switch_to_default_context
845
- set_context nil
846
- end
847
- end
848
-
849
- add_endpoint_method(:current_context) do
850
- def current_context
851
- execute :current_context
852
- end
853
- end
854
-
855
- add_endpoint_method(:available_contexts) do
856
- def available_contexts
857
- # return empty array instead of nil on failure
858
- execute(:available_contexts, {}) || []
859
- end
860
- end
861
-
862
- add_endpoint_method(:set_context) do
863
- def set_context(context = null)
864
- execute :set_context, {}, name: context
865
- end
866
- end
867
- end
868
-
869
- def add_screen_recording
870
- add_endpoint_method(:stop_recording_screen) do
871
- def stop_recording_screen(remote_path: nil, user: nil, pass: nil, method: 'PUT')
872
- option = ::Appium::Core::Device::ScreenRecord.new(
873
- remote_path: remote_path, user: user, pass: pass, method: method
874
- ).upload_option
875
-
876
- params = option.empty? ? {} : { options: option }
877
-
878
- execute(:stop_recording_screen, {}, params)
879
- end
880
- end
881
-
882
- add_endpoint_method(:stop_and_save_recording_screen) do
883
- def stop_and_save_recording_screen(file_path)
884
- base64data = execute(:stop_recording_screen, {}, {})
885
- File.open(file_path, 'wb') { |f| f << Base64.decode64(base64data) }
886
- end
887
- end
888
- end
889
569
  end # class << self
890
570
  end # module Device
891
571
  end # module Core