appium_lib_core 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|