appium_lib_core 0.1.0
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.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.rubocop.yml +20 -0
- data/.travis.yml +16 -0
- data/CHANGELOG.md +11 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +202 -0
- data/README.md +5 -0
- data/Rakefile +62 -0
- data/Thorfile +7 -0
- data/appium_lib_core.gemspec +35 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/appium_lib_core.rb +41 -0
- data/lib/appium_lib_core/android.rb +5 -0
- data/lib/appium_lib_core/android/device.rb +174 -0
- data/lib/appium_lib_core/android/espresso/bridge.rb +16 -0
- data/lib/appium_lib_core/android/search_context.rb +18 -0
- data/lib/appium_lib_core/android/touch.rb +17 -0
- data/lib/appium_lib_core/android/uiautomator1/bridge.rb +16 -0
- data/lib/appium_lib_core/android/uiautomator2/bridge.rb +16 -0
- data/lib/appium_lib_core/android_espresso.rb +5 -0
- data/lib/appium_lib_core/android_uiautomator2.rb +5 -0
- data/lib/appium_lib_core/common.rb +6 -0
- data/lib/appium_lib_core/common/base.rb +8 -0
- data/lib/appium_lib_core/common/base/bridge.rb +47 -0
- data/lib/appium_lib_core/common/base/capabilities.rb +16 -0
- data/lib/appium_lib_core/common/base/command.rb +10 -0
- data/lib/appium_lib_core/common/base/driver.rb +51 -0
- data/lib/appium_lib_core/common/base/http_default.rb +13 -0
- data/lib/appium_lib_core/common/base/search_context.rb +89 -0
- data/lib/appium_lib_core/common/base/wait.rb +56 -0
- data/lib/appium_lib_core/common/command.rb +77 -0
- data/lib/appium_lib_core/common/device.rb +567 -0
- data/lib/appium_lib_core/common/error.rb +18 -0
- data/lib/appium_lib_core/common/log.rb +30 -0
- data/lib/appium_lib_core/common/logger.rb +30 -0
- data/lib/appium_lib_core/device/multi_touch.rb +48 -0
- data/lib/appium_lib_core/device/touch_actions.rb +191 -0
- data/lib/appium_lib_core/driver.rb +459 -0
- data/lib/appium_lib_core/ios.rb +7 -0
- data/lib/appium_lib_core/ios/device.rb +54 -0
- data/lib/appium_lib_core/ios/search_context.rb +27 -0
- data/lib/appium_lib_core/ios/touch.rb +17 -0
- data/lib/appium_lib_core/ios/uiautomation/bridge.rb +18 -0
- data/lib/appium_lib_core/ios/uiautomation/patch.rb +20 -0
- data/lib/appium_lib_core/ios/xcuitest/bridge.rb +18 -0
- data/lib/appium_lib_core/ios/xcuitest/device.rb +66 -0
- data/lib/appium_lib_core/ios/xcuitest/search_context.rb +40 -0
- data/lib/appium_lib_core/ios_xcuitest.rb +8 -0
- data/lib/appium_lib_core/patch.rb +78 -0
- data/lib/appium_lib_core/version.rb +6 -0
- data/release_notes.md +0 -0
- metadata +262 -0
@@ -0,0 +1,174 @@
|
|
1
|
+
module Appium
|
2
|
+
module Android
|
3
|
+
module Device
|
4
|
+
extend Forwardable
|
5
|
+
|
6
|
+
# @!method hide_keyboard(close_key = nil, strategy = nil)
|
7
|
+
# Hide the onscreen keyboard
|
8
|
+
# @param [String] close_key The name of the key which closes the keyboard.
|
9
|
+
# Defaults to 'Done' for iOS(except for XCUITest).
|
10
|
+
# @param [Symbol] strategy The symbol of the strategy which closes the keyboard.
|
11
|
+
# XCUITest ignore this argument.
|
12
|
+
# Default for iOS is `:pressKey`. Default for Android is `:tapOutside`.
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
#
|
16
|
+
# @driver.hide_keyboard # Close a keyboard with the 'Done' button
|
17
|
+
# @driver.hide_keyboard('Finished') # Close a keyboard with the 'Finished' button
|
18
|
+
# @driver.hide_keyboard(nil, :tapOutside) # Close a keyboard with tapping out side of keyboard
|
19
|
+
#
|
20
|
+
|
21
|
+
# @!method end_coverage(path, intent)
|
22
|
+
# Android only; Ends the test coverage and writes the results to the given path on device.
|
23
|
+
# @param [String] path Path on the device to write too.
|
24
|
+
# @param [String] intent Intent to broadcast when ending coverage.
|
25
|
+
#
|
26
|
+
|
27
|
+
# @!method start_activity(opts)
|
28
|
+
# Android only. Start a new activity within the current app or launch a new app and start the target activity.
|
29
|
+
#
|
30
|
+
# @option [String] The package owning the activity [required]
|
31
|
+
# @option [String] The target activity [required]
|
32
|
+
# @option opts [String] The package to start before the target package [optional]
|
33
|
+
# @option opts [String] The activity to start before the target activity [optional]
|
34
|
+
#
|
35
|
+
# @example
|
36
|
+
#
|
37
|
+
# start_activity app_package: 'io.appium.android.apis',
|
38
|
+
# app_activity: '.accessibility.AccessibilityNodeProviderActivity'
|
39
|
+
#
|
40
|
+
|
41
|
+
# @!method set_network_connection(mode)
|
42
|
+
# Set the device network connection mode
|
43
|
+
# @param [String] mode Bit mask that represent the network mode
|
44
|
+
#
|
45
|
+
# Value (Alias) | Data | Wifi | Airplane Mode
|
46
|
+
# -------------------------------------------------
|
47
|
+
# 1 (Airplane Mode) | 0 | 0 | 1
|
48
|
+
# 6 (All network on) | 1 | 1 | 0
|
49
|
+
# 4 (Data only) | 1 | 0 | 0
|
50
|
+
# 2 (Wifi only) | 0 | 1 | 0
|
51
|
+
# 0 (None) | 0 | 0 | 0
|
52
|
+
#
|
53
|
+
# @example
|
54
|
+
#
|
55
|
+
# @driver.set_network_connection 1
|
56
|
+
#
|
57
|
+
|
58
|
+
# @!method get_performance_data_types
|
59
|
+
# Get the information type of the system state which is supported to read such as
|
60
|
+
# cpu, memory, network, battery via adb commands.
|
61
|
+
# https://github.com/appium/appium-base-driver/blob/be29aec2318316d12b5c3295e924a5ba8f09b0fb/lib/mjsonwp/routes.js#L300
|
62
|
+
#
|
63
|
+
# @example
|
64
|
+
#
|
65
|
+
# @driver.get_performance_data_types #=> ["cpuinfo", "batteryinfo", "networkinfo", "memoryinfo"]
|
66
|
+
#
|
67
|
+
|
68
|
+
# @!method get_performance_data(package_name:, data_type:, data_read_timeout: 1000)
|
69
|
+
# Get the resource usage information of the application.
|
70
|
+
# https://github.com/appium/appium-base-driver/blob/be29aec2318316d12b5c3295e924a5ba8f09b0fb/lib/mjsonwp/routes.js#L303
|
71
|
+
# @param [String] package_name Package name
|
72
|
+
# @param [String] data_type Data type get with `get_performance_data_types`
|
73
|
+
# @param [String] data_read_timeout Command timeout. Default is 2.
|
74
|
+
#
|
75
|
+
# @example
|
76
|
+
#
|
77
|
+
# @driver.get_performance_data package_name: package_name, data_type: data_type, data_read_timeout: 2
|
78
|
+
#
|
79
|
+
|
80
|
+
# @!method start_recording_screen(package_name:, data_type:, data_read_timeout: 1000)
|
81
|
+
# Record the display of devices running Android 4.4 (API level 19) and higher.
|
82
|
+
# It records screen activity to an MPEG-4 file. Audio is not recorded with the video file.
|
83
|
+
# @param [String] file_path A path to save the video. `/sdcard/default.mp4` is by default.
|
84
|
+
# @param [String] video_size A video size. '1280x720' is by default.
|
85
|
+
# @param [String] time_limit Recording time. 180 second is by default.
|
86
|
+
# @param [String] bit_rate The video bit rate for the video, in megabits per second. 3000000(3Mbps) is by default.
|
87
|
+
#
|
88
|
+
# @example
|
89
|
+
#
|
90
|
+
# @driver.start_recording_screen(file_path: '/sdcard/default.mp4', video_size: '1280x720',
|
91
|
+
# time_limit: '180', bit_rate: '3000000')
|
92
|
+
#
|
93
|
+
|
94
|
+
# @!method stop_recording_screen
|
95
|
+
# Stop recording the screen.
|
96
|
+
#
|
97
|
+
# @example
|
98
|
+
#
|
99
|
+
# @driver.stop_recording_screen
|
100
|
+
#
|
101
|
+
|
102
|
+
####
|
103
|
+
## class << self
|
104
|
+
####
|
105
|
+
|
106
|
+
class << self
|
107
|
+
def extended(_mod)
|
108
|
+
Appium::Core::Device.extend_webdriver_with_forwardable
|
109
|
+
|
110
|
+
# Android
|
111
|
+
Appium::Core::Device.add_endpoint_method(:start_activity) do
|
112
|
+
def start_activity(opts)
|
113
|
+
raise 'opts must be a hash' unless opts.is_a? Hash
|
114
|
+
app_package = opts[:app_package]
|
115
|
+
raise 'app_package is required' unless app_package
|
116
|
+
app_activity = opts[:app_activity]
|
117
|
+
raise 'app_activity is required' unless app_activity
|
118
|
+
app_wait_package = opts.fetch(:app_wait_package, '')
|
119
|
+
app_wait_activity = opts.fetch(:app_wait_activity, '')
|
120
|
+
|
121
|
+
unknown_opts = opts.keys - [:app_package, :app_activity, :app_wait_package, :app_wait_activity]
|
122
|
+
raise "Unknown options #{unknown_opts}" unless unknown_opts.empty?
|
123
|
+
|
124
|
+
execute :start_activity, {}, appPackage: app_package,
|
125
|
+
appActivity: app_activity,
|
126
|
+
appWaitPackage: app_wait_package,
|
127
|
+
appWaitActivity: app_wait_activity
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# Android, Override
|
132
|
+
Appium::Core::Device.add_endpoint_method(:hide_keyboard) do
|
133
|
+
def hide_keyboard(close_key = nil, strategy = nil)
|
134
|
+
option = {}
|
135
|
+
|
136
|
+
option[:key] = close_key if close_key
|
137
|
+
option[:strategy] = strategy || :tapOutside # default to pressKey
|
138
|
+
|
139
|
+
execute :hide_keyboard, {}, option
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# TODO: TEST ME
|
144
|
+
Appium::Core::Device.add_endpoint_method(:end_coverage) do
|
145
|
+
def end_coverage(path, intent)
|
146
|
+
execute :end_coverage, {}, path: path, intent: intent
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
Appium::Core::Device.add_endpoint_method(:set_network_connection) do
|
151
|
+
def set_network_connection(mode)
|
152
|
+
execute :set_network_connection, {}, type: mode
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
Appium::Core::Device.add_endpoint_method(:get_performance_data) do
|
157
|
+
def get_performance_data(package_name:, data_type:, data_read_timeout: 1000)
|
158
|
+
execute(:get_performance_data, {},
|
159
|
+
packageName: package_name, dataType: data_type, dataReadTimeout: data_read_timeout)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
Appium::Core::Device.add_endpoint_method(:start_recording_screen) do
|
164
|
+
def start_recording_screen(file_path: '/sdcard/default.mp4', video_size: '1280x720',
|
165
|
+
time_limit: '180', bit_rate: '3000000')
|
166
|
+
execute(:start_recording_screen, {},
|
167
|
+
filePath: file_path, videoSize: video_size, timeLimit: time_limit, bitRate: bit_rate)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end # module Device
|
173
|
+
end # module Android
|
174
|
+
end # module Appium
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Appium
|
2
|
+
module Core
|
3
|
+
module Android
|
4
|
+
module Espresso
|
5
|
+
module Bridge
|
6
|
+
def self.for(target)
|
7
|
+
target.extend Appium::Android::Device
|
8
|
+
Core::Android::SearchContext.extend
|
9
|
+
|
10
|
+
Core::Android::Touch.extend_touch_actions
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Appium
|
2
|
+
module Core
|
3
|
+
module Android
|
4
|
+
module SearchContext
|
5
|
+
# @!method uiautomator_find
|
6
|
+
# find_element/s can be used with a [UISelector](http://developer.android.com/tools/help/uiautomator/UiSelector.html).
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
#
|
10
|
+
# @driver.find_elements :uiautomator, 'new UiSelector().clickable(true)'
|
11
|
+
#
|
12
|
+
def self.extend
|
13
|
+
::Appium::Core::Base::SearchContext.add_finders(uiautomator: '-android uiautomator')
|
14
|
+
end
|
15
|
+
end # class << self
|
16
|
+
end # module Ios
|
17
|
+
end # module Core
|
18
|
+
end # module Appium
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Appium
|
2
|
+
module Core
|
3
|
+
module Android
|
4
|
+
module Touch
|
5
|
+
def self.extend_touch_actions
|
6
|
+
::Appium::Core::TouchAction.class_eval do
|
7
|
+
def swipe_coordinates(start_x: 0, start_y: 0, offset_x: 0, offset_y: 0)
|
8
|
+
Appium::Logger.info "extended Appium::Core::Android::Touch, start_x: #{start_x},"\
|
9
|
+
" start_y: #{start_y}, offset_x: #{offset_x}, offset_y: #{offset_y}"
|
10
|
+
{ offset_x: (start_x + offset_x), offset_y: (start_y + offset_y) }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Appium
|
2
|
+
module Core
|
3
|
+
module Android
|
4
|
+
module Uiautomator1
|
5
|
+
module Bridge
|
6
|
+
def self.for(target)
|
7
|
+
target.extend Appium::Android::Device
|
8
|
+
Core::Android::SearchContext.extend
|
9
|
+
|
10
|
+
Core::Android::Touch.extend_touch_actions
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Appium
|
2
|
+
module Core
|
3
|
+
module Android
|
4
|
+
module Uiautomator2
|
5
|
+
module Bridge
|
6
|
+
def self.for(target)
|
7
|
+
target.extend Appium::Android::Device
|
8
|
+
Core::Android::SearchContext.extend
|
9
|
+
|
10
|
+
Core::Android::Touch.extend_touch_actions
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
# The following files have selenium-webdriver related stuff.
|
2
|
+
require_relative 'base/driver'
|
3
|
+
require_relative 'base/bridge'
|
4
|
+
require_relative 'base/capabilities'
|
5
|
+
require_relative 'base/http_default'
|
6
|
+
require_relative 'base/search_context'
|
7
|
+
require_relative 'base/command'
|
8
|
+
require_relative 'base/wait'
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Appium
|
2
|
+
module Core
|
3
|
+
class Base
|
4
|
+
class Bridge < ::Selenium::WebDriver::Remote::Bridge
|
5
|
+
def self.handshake(**opts)
|
6
|
+
desired_capabilities = opts.delete(:desired_capabilities)
|
7
|
+
|
8
|
+
if desired_capabilities.is_a?(Symbol)
|
9
|
+
unless Remote::Capabilities.respond_to?(desired_capabilities)
|
10
|
+
raise Error::WebDriverError, "invalid desired capability: #{desired_capabilities.inspect}"
|
11
|
+
end
|
12
|
+
desired_capabilities = Remote::Capabilities.__send__(desired_capabilities)
|
13
|
+
end
|
14
|
+
|
15
|
+
bridge = new(opts)
|
16
|
+
capabilities = bridge.create_session(desired_capabilities)
|
17
|
+
|
18
|
+
case bridge.dialect
|
19
|
+
when :oss
|
20
|
+
CoreBridgeOSS.new(capabilities, bridge.session_id, opts)
|
21
|
+
when :w3c
|
22
|
+
CoreBridgeW3C.new(capabilities, bridge.session_id, opts)
|
23
|
+
else
|
24
|
+
raise CoreError, 'cannot understand dialect'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end # class Bridge
|
28
|
+
|
29
|
+
class CoreBridgeOSS < ::Selenium::WebDriver::Remote::OSS::Bridge
|
30
|
+
def commands(command)
|
31
|
+
::Appium::Core::Commands::COMMANDS_EXTEND_OSS[command]
|
32
|
+
end
|
33
|
+
end # class CoreBridgeOSS
|
34
|
+
|
35
|
+
class CoreBridgeW3C < ::Selenium::WebDriver::Remote::W3C::Bridge
|
36
|
+
def commands(command)
|
37
|
+
case command
|
38
|
+
when :status, :is_element_displayed
|
39
|
+
::Appium::Core::Commands::COMMANDS_EXTEND_OSS[command]
|
40
|
+
else
|
41
|
+
::Appium::Core::Commands::COMMANDS_EXTEND_W3C[command]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end # class CoreBridgeW3C
|
45
|
+
end # class Base
|
46
|
+
end # module Core
|
47
|
+
end # module Appium
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Appium
|
2
|
+
module Core
|
3
|
+
class Base
|
4
|
+
module Capabilities
|
5
|
+
# @private
|
6
|
+
# @param [Hash] opts_caps Capabilities for Appium server. All capability keys are converted to lowerCamelCase when
|
7
|
+
# this client sends capabilities to Appium server as JSON format.
|
8
|
+
# @return [::Selenium::WebDriver::Remote::W3C::Capabilities] Return instance of Appium::Core::Base::Capabilities
|
9
|
+
# inherited ::Selenium::WebDriver::Remote::W3C::Capabilities
|
10
|
+
def self.create_capabilities(opts_caps = {})
|
11
|
+
::Selenium::WebDriver::Remote::W3C::Capabilities.new(opts_caps)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module Appium
|
2
|
+
module Core
|
3
|
+
class Base
|
4
|
+
module Commands
|
5
|
+
OSS = ::Selenium::WebDriver::Remote::OSS::Bridge::COMMANDS.freeze
|
6
|
+
W3C = ::Selenium::WebDriver::Remote::W3C::Bridge::COMMANDS.freeze
|
7
|
+
end # module Commands
|
8
|
+
end # module Base
|
9
|
+
end # module Core
|
10
|
+
end # module Appium
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require_relative 'search_context'
|
2
|
+
|
3
|
+
module Appium
|
4
|
+
module Core
|
5
|
+
class Base
|
6
|
+
class Driver < ::Selenium::WebDriver::Driver
|
7
|
+
include ::Selenium::WebDriver::DriverExtensions::UploadsFiles
|
8
|
+
include ::Selenium::WebDriver::DriverExtensions::TakesScreenshot
|
9
|
+
include ::Selenium::WebDriver::DriverExtensions::HasSessionId
|
10
|
+
include ::Selenium::WebDriver::DriverExtensions::Rotatable
|
11
|
+
include ::Selenium::WebDriver::DriverExtensions::HasRemoteStatus
|
12
|
+
include ::Selenium::WebDriver::DriverExtensions::HasWebStorage
|
13
|
+
|
14
|
+
include ::Appium::Core::Base::SearchContext
|
15
|
+
|
16
|
+
def initialize(opts = {})
|
17
|
+
listener = opts.delete(:listener)
|
18
|
+
@bridge = ::Appium::Core::Base::Bridge.handshake(opts)
|
19
|
+
if @bridge.dialect == :oss
|
20
|
+
extend ::Selenium::WebDriver::DriverExtensions::HasTouchScreen
|
21
|
+
extend ::Selenium::WebDriver::DriverExtensions::HasLocation
|
22
|
+
extend ::Selenium::WebDriver::DriverExtensions::HasNetworkConnection
|
23
|
+
end
|
24
|
+
super(@bridge, listener: listener)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Get the device window's size.
|
28
|
+
# @return [Selenium::WebDriver::Dimension]
|
29
|
+
#
|
30
|
+
# @example
|
31
|
+
# size = @driver.window_size
|
32
|
+
# size.width #=> Integer
|
33
|
+
# size.height #=> Integer
|
34
|
+
#
|
35
|
+
def window_size
|
36
|
+
manage.window.size
|
37
|
+
end
|
38
|
+
|
39
|
+
# Get the device window's size.
|
40
|
+
# @return [String]
|
41
|
+
#
|
42
|
+
# @example
|
43
|
+
# @driver.back # back to the previous view
|
44
|
+
#
|
45
|
+
def back
|
46
|
+
navigate.back
|
47
|
+
end
|
48
|
+
end # class Driver
|
49
|
+
end # class Base
|
50
|
+
end # module Core
|
51
|
+
end # module Appium
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative '../../version'
|
2
|
+
|
3
|
+
module Appium
|
4
|
+
module Core
|
5
|
+
class Base
|
6
|
+
module Http
|
7
|
+
class Default < Selenium::WebDriver::Remote::Http::Default
|
8
|
+
DEFAULT_HEADERS = { 'Accept' => CONTENT_TYPE, 'User-Agent' => "appium/ruby_lib_core/#{VERSION}" }.freeze
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|