appium_lib_core 4.1.0 → 9.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 +4 -4
- data/CHANGELOG.md +331 -270
- data/README.md +65 -15
- data/Rakefile +5 -22
- data/appium_lib_core.gemspec +6 -9
- data/bin/console +0 -4
- data/lib/appium_lib_core/android/device/auth_finger_print.rb +4 -1
- data/lib/appium_lib_core/android/device/network.rb +10 -0
- data/lib/appium_lib_core/android/device/performance.rb +3 -0
- data/lib/appium_lib_core/android/device/screen.rb +2 -0
- data/lib/appium_lib_core/android/device.rb +80 -17
- data/lib/appium_lib_core/common/base/bridge.rb +255 -93
- data/lib/appium_lib_core/common/base/capabilities.rb +21 -8
- data/lib/appium_lib_core/common/{command/mjsonwp.rb → base/device_ime.rb} +33 -12
- data/lib/appium_lib_core/common/base/driver.rb +263 -334
- data/lib/appium_lib_core/common/base/driver_settings.rb +51 -0
- data/lib/appium_lib_core/common/base/has_location.rb +80 -0
- data/lib/appium_lib_core/common/base/has_network_connection.rb +56 -0
- data/lib/appium_lib_core/common/base/http_default.rb +22 -38
- data/lib/appium_lib_core/{ios/uiautomation/bridge.rb → common/base/remote_status.rb} +9 -8
- data/lib/appium_lib_core/common/base/rotable.rb +62 -0
- data/lib/appium_lib_core/common/base/screenshot.rb +8 -8
- data/lib/appium_lib_core/common/base/search_context.rb +98 -172
- data/lib/appium_lib_core/common/base.rb +1 -5
- data/lib/appium_lib_core/common/command.rb +244 -4
- data/lib/appium_lib_core/common/device/app_management.rb +2 -26
- data/lib/appium_lib_core/common/device/context.rb +1 -5
- data/lib/appium_lib_core/common/device/image_comparison.rb +12 -4
- data/lib/appium_lib_core/common/device/keyevent.rb +4 -4
- data/lib/appium_lib_core/common/device/{touch_actions.rb → orientation.rb} +6 -10
- data/lib/appium_lib_core/common/error.rb +4 -5
- data/lib/appium_lib_core/common/log.rb +5 -4
- data/lib/appium_lib_core/common/wait.rb +38 -6
- data/lib/appium_lib_core/device.rb +3 -9
- data/lib/appium_lib_core/driver.rb +191 -160
- data/lib/appium_lib_core/{patch.rb → element.rb} +64 -26
- data/lib/appium_lib_core/ios/xcuitest/device.rb +2 -0
- data/lib/appium_lib_core/{common/base/command.rb → mac2/bridge.rb} +9 -8
- data/lib/appium_lib_core/mac2/device/screen.rb +48 -0
- data/lib/appium_lib_core/mac2/device.rb +92 -0
- data/lib/appium_lib_core/{ios.rb → mac2.rb} +2 -5
- data/lib/appium_lib_core/support/event_firing_bridge.rb +57 -0
- data/lib/appium_lib_core/version.rb +2 -2
- data/lib/appium_lib_core.rb +23 -10
- metadata +28 -94
- data/.github/ISSUE_TEMPLATE/issue-report.md +0 -29
- data/.github/contributing.md +0 -26
- data/.github/issue_template.md +0 -20
- data/.github/workflows/unittest.yml +0 -68
- data/.gitignore +0 -18
- data/.rubocop.yml +0 -58
- data/azure-pipelines.yml +0 -15
- data/ci-jobs/functional/android_setup.yml +0 -3
- data/ci-jobs/functional/ios_setup.yml +0 -7
- data/ci-jobs/functional/publish_test_result.yml +0 -18
- data/ci-jobs/functional/run_appium.yml +0 -25
- data/ci-jobs/functional/start-emulator.sh +0 -26
- data/ci-jobs/functional_test.yml +0 -298
- data/docs/mobile_command.md +0 -34
- data/lib/appium_lib_core/common/base/bridge/mjsonwp.rb +0 -81
- data/lib/appium_lib_core/common/base/bridge/w3c.rb +0 -252
- data/lib/appium_lib_core/common/command/common.rb +0 -110
- data/lib/appium_lib_core/common/command/w3c.rb +0 -56
- data/lib/appium_lib_core/common/device/value.rb +0 -52
- data/lib/appium_lib_core/common/touch_action/multi_touch.rb +0 -56
- data/lib/appium_lib_core/common/touch_action/touch_actions.rb +0 -203
- data/lib/appium_lib_core/ios/uiautomation/device.rb +0 -44
- data/lib/appium_lib_core/ios/uiautomation/patch.rb +0 -34
- data/release_notes.md +0 -816
- data/script/commands.rb +0 -200
@@ -12,176 +12,102 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
#
|
101
|
-
# # For iOS
|
102
|
-
# ## With :predicate
|
103
|
-
# @driver.find_elements :predicate, "isWDVisible == 1"
|
104
|
-
# @driver.find_elements :predicate, 'wdName == "Buttons"'
|
105
|
-
# @driver.find_elements :predicate, 'wdValue == "SearchBar" AND isWDDivisible == 1'
|
106
|
-
#
|
107
|
-
# ## With Class Chain
|
108
|
-
# ### select the third child button of the first child window element
|
109
|
-
# @driver.find_elements :class_chain, 'XCUIElementTypeWindow/XCUIElementTypeButton[3]'
|
110
|
-
# ### select all the children windows
|
111
|
-
# @driver.find_elements :class_chain, 'XCUIElementTypeWindow'
|
112
|
-
# ### select the second last child of the second child window
|
113
|
-
# @driver.find_elements :class_chain, 'XCUIElementTypeWindow[2]/XCUIElementTypeAny[-2]'
|
114
|
-
# ### matching predicate. <code>'</code> is the mark.
|
115
|
-
# @driver.find_elements :class_chain, 'XCUIElementTypeWindow['visible = 1]['name = "bla"']'
|
116
|
-
# ### containing predicate. '$' is the mark.
|
117
|
-
# ### Require appium-xcuitest-driver 2.54.0+. PR: https://github.com/facebook/WebDriverAgent/pull/707/files
|
118
|
-
# @driver.find_elements :class_chain, 'XCUIElementTypeWindow[$name = \"bla$$$bla\"$]'
|
119
|
-
# e = find_element :class_chain, "**/XCUIElementTypeWindow[$name == 'Buttons'$]"
|
120
|
-
# e.tag_name #=> "XCUIElementTypeWindow"
|
121
|
-
# e = find_element :class_chain, "**/XCUIElementTypeStaticText[$name == 'Buttons'$]"
|
122
|
-
# e.tag_name #=> "XCUIElementTypeStaticText"
|
123
|
-
#
|
124
|
-
# # For Windows
|
125
|
-
# @driver.find_elements :windows_uiautomation, '....'
|
126
|
-
#
|
127
|
-
# # For Tizen
|
128
|
-
# @driver.find_elements :tizen_uiautomation, '....'
|
129
|
-
#
|
130
|
-
# rubocop:enable Layout/LineLength
|
131
|
-
def find_element(*args)
|
132
|
-
how, what = extract_args(args)
|
133
|
-
by = _set_by_from_finders(how)
|
134
|
-
begin
|
135
|
-
bridge.find_element_by by, what.to_s, ref
|
136
|
-
rescue Selenium::WebDriver::Error::TimeoutError
|
137
|
-
raise Selenium::WebDriver::Error::NoSuchElementError
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
#
|
142
|
-
# Find all elements matching the given arguments
|
143
|
-
#
|
144
|
-
# @see SearchContext#find_elements
|
145
|
-
#
|
146
|
-
def find_elements(*args)
|
147
|
-
how, what = extract_args(args)
|
148
|
-
by = _set_by_from_finders(how)
|
149
|
-
begin
|
150
|
-
bridge.find_elements_by by, what.to_s, ref
|
151
|
-
rescue Selenium::WebDriver::Error::TimeoutError
|
152
|
-
[]
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
private
|
157
|
-
|
158
|
-
def _set_by_from_finders(how)
|
159
|
-
by = FINDERS[how.to_sym]
|
160
|
-
raise ArgumentError, "cannot find element by #{how.inspect}. Available finders are #{FINDERS.keys}." unless by
|
161
|
-
|
162
|
-
by
|
163
|
-
end
|
164
|
-
|
165
|
-
def extract_args(args)
|
166
|
-
case args.size
|
167
|
-
when 2
|
168
|
-
args
|
169
|
-
when 1
|
170
|
-
arg = args.first
|
171
|
-
|
172
|
-
raise ArgumentError, "expected #{arg.inspect}:#{arg.class} to respond to #shift" unless arg.respond_to?(:shift)
|
173
|
-
|
174
|
-
# this will be a single-entry hash, so use #shift over #first or #[]
|
175
|
-
arr = arg.dup.shift
|
176
|
-
|
177
|
-
raise ArgumentError, "expected #{arr.inspect} to have 2 elements" unless arr.size == 2
|
15
|
+
# rubocop:disable Layout/LineLength
|
16
|
+
#
|
17
|
+
# Find the first element matching the given arguments
|
18
|
+
#
|
19
|
+
# - Android can find with uiautomator like a {http://developer.android.com/tools/help/uiautomator/UiSelector.html UISelector}.
|
20
|
+
# - iOS can find with a {https://developer.apple.com/library/ios/documentation/ToolsLanguages/Reference/UIAWindowClassReference/UIAWindow/UIAWindow.html#//apple_ref/doc/uid/TP40009930 UIAutomation command}.
|
21
|
+
# - iOS, only for XCUITest(WebDriverAgent), can find with a {https://github.com/facebook/WebDriverAgent/wiki/Queries class chain}
|
22
|
+
#
|
23
|
+
# == Find with image
|
24
|
+
# Return an element if current view has a partial image. The logic depends on template matching by OpenCV.
|
25
|
+
# {https://github.com/appium/appium/blob/1.x/docs/en/writing-running-appium/image-comparison.md image-comparison}
|
26
|
+
#
|
27
|
+
# You can handle settings for the comparision following {https://github.com/appium/appium-base-driver/blob/master/lib/basedriver/device-settings.js#L6 here}
|
28
|
+
#
|
29
|
+
# == Espresso viewmatcher and datamatcher
|
30
|
+
# Espresso has {https://developer.android.com/training/testing/espresso/basics _onView_ matcher}
|
31
|
+
# and {https://medium.com/androiddevelopers/adapterviews-and-espresso-f4172aa853cf _onData_ matcher} for more reference
|
32
|
+
# that allows you to target adapters instead of Views. This method find methods based on reflections
|
33
|
+
#
|
34
|
+
# This is a selector strategy that allows users to pass a selector of the form:
|
35
|
+
#
|
36
|
+
# <code>{ name: '<name>', args: ['arg1', 'arg2', '...'], class: '<optional class>' }</code>
|
37
|
+
#
|
38
|
+
# - _name_: The name of a method to invoke. The method must return
|
39
|
+
# a Hamcrest {http://hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matcher.html Matcher}
|
40
|
+
# - _args_: The args provided to the method
|
41
|
+
# - _class_: The class name that the method is part of (defaults to <code>org.hamcrest.Matchers</code>).
|
42
|
+
# Can be fully qualified, or simple, and simple defaults to <code>androidx.test.espresso.matcher</code> package
|
43
|
+
# (e.g.: <code>class=CursorMatchers</code> fully qualified is <code>class=androidx.test.espresso.matcher.CursorMatchers</code>
|
44
|
+
#
|
45
|
+
# See example how to send viewmatcher and datamatcher in Ruby client
|
46
|
+
#
|
47
|
+
#
|
48
|
+
# @overload find_element(how, what)
|
49
|
+
# @param [Symbol, String] how The method to find the element by
|
50
|
+
# @param [String] what The locator to use
|
51
|
+
#
|
52
|
+
# @overload find_element(opts)
|
53
|
+
# @param [Hash] opts Find options
|
54
|
+
# @option opts [Symbol] :how Key named after the method to find the element by, containing the locator
|
55
|
+
# @return [Element]
|
56
|
+
# @raise [Error::NoSuchElementError] if the element doesn't exist
|
57
|
+
#
|
58
|
+
# @example Find element with each keys
|
59
|
+
#
|
60
|
+
# # with accessibility id. All platforms.
|
61
|
+
# @driver.find_elements :accessibility_id, 'Animation'
|
62
|
+
# @driver.find_elements :accessibility_id, 'Animation'
|
63
|
+
#
|
64
|
+
# # with base64 encoded template image. All platforms.
|
65
|
+
# @driver.find_elements :image, Base64.strict_encode64(File.read(file_path))
|
66
|
+
#
|
67
|
+
# # For Android
|
68
|
+
# ## With uiautomator
|
69
|
+
# @driver.find_elements :uiautomator, 'new UiSelector().clickable(true)'
|
70
|
+
# ## With viewtag, but only for Espresso
|
71
|
+
# ## 'setTag'/'getTag' in https://developer.android.com/reference/android/view/View
|
72
|
+
# @driver.find_elements :viewtag, 'new UiSelector().clickable(true)'
|
73
|
+
# # With data_matcher. The argument should be JSON format.
|
74
|
+
# @driver.find_elements :data_matcher, { name: 'hasEntry', args: %w(title Animation) }.to_json
|
75
|
+
#
|
76
|
+
# # For iOS
|
77
|
+
# ## With :predicate
|
78
|
+
# @driver.find_elements :predicate, "isWDVisible == 1"
|
79
|
+
# @driver.find_elements :predicate, 'wdName == "Buttons"'
|
80
|
+
# @driver.find_elements :predicate, 'wdValue == "SearchBar" AND isWDDivisible == 1'
|
81
|
+
#
|
82
|
+
# ## With Class Chain
|
83
|
+
# ### select the third child button of the first child window element
|
84
|
+
# @driver.find_elements :class_chain, 'XCUIElementTypeWindow/XCUIElementTypeButton[3]'
|
85
|
+
# ### select all the children windows
|
86
|
+
# @driver.find_elements :class_chain, 'XCUIElementTypeWindow'
|
87
|
+
# ### select the second last child of the second child window
|
88
|
+
# @driver.find_elements :class_chain, 'XCUIElementTypeWindow[2]/XCUIElementTypeAny[-2]'
|
89
|
+
# ### matching predicate. <code>'</code> is the mark.
|
90
|
+
# @driver.find_elements :class_chain, 'XCUIElementTypeWindow['visible = 1]['name = "bla"']'
|
91
|
+
# ### containing predicate. '$' is the mark.
|
92
|
+
# ### Require appium-xcuitest-driver 2.54.0+. PR: https://github.com/facebook/WebDriverAgent/pull/707/files
|
93
|
+
# @driver.find_elements :class_chain, 'XCUIElementTypeWindow[$name = \"bla$$$bla\"$]'
|
94
|
+
# e = find_element :class_chain, "**/XCUIElementTypeWindow[$name == 'Buttons'$]"
|
95
|
+
# e.tag_name #=> "XCUIElementTypeWindow"
|
96
|
+
# e = find_element :class_chain, "**/XCUIElementTypeStaticText[$name == 'Buttons'$]"
|
97
|
+
# e.tag_name #=> "XCUIElementTypeStaticText"
|
98
|
+
#
|
99
|
+
# rubocop:enable Layout/LineLength
|
178
100
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
101
|
+
APPIUM_EXTRA_FINDERS = {
|
102
|
+
accessibility_id: 'accessibility id',
|
103
|
+
image: '-image',
|
104
|
+
custom: '-custom',
|
105
|
+
# Android
|
106
|
+
uiautomator: '-android uiautomator', # Unavailable in Espresso
|
107
|
+
viewtag: '-android viewtag', # Available in Espresso
|
108
|
+
data_matcher: '-android datamatcher', # Available in Espresso
|
109
|
+
view_matcher: '-android viewmatcher', # Available in Espresso
|
110
|
+
# iOS
|
111
|
+
predicate: '-ios predicate string',
|
112
|
+
class_chain: '-ios class chain'
|
113
|
+
}.freeze
|
@@ -17,7 +17,6 @@ require_relative 'device/keyboard'
|
|
17
17
|
require_relative 'device/ime_actions'
|
18
18
|
require_relative 'device/setting'
|
19
19
|
require_relative 'device/context'
|
20
|
-
require_relative 'device/value'
|
21
20
|
require_relative 'device/file_management'
|
22
21
|
require_relative 'device/keyevent'
|
23
22
|
require_relative 'device/image_comparison'
|
@@ -27,16 +26,13 @@ require_relative 'device/screen_record'
|
|
27
26
|
require_relative 'device/battery_status'
|
28
27
|
require_relative 'device/clipboard_content_type'
|
29
28
|
require_relative 'device/device'
|
30
|
-
require_relative 'device/touch_actions'
|
31
29
|
require_relative 'device/execute_driver'
|
30
|
+
require_relative 'device/orientation'
|
32
31
|
|
33
32
|
# The following files have selenium-webdriver related stuff.
|
34
33
|
require_relative 'base/driver'
|
35
34
|
require_relative 'base/bridge'
|
36
|
-
require_relative 'base/bridge/mjsonwp'
|
37
|
-
require_relative 'base/bridge/w3c'
|
38
35
|
require_relative 'base/capabilities'
|
39
36
|
require_relative 'base/http_default'
|
40
37
|
require_relative 'base/search_context'
|
41
|
-
require_relative 'base/command'
|
42
38
|
require_relative 'base/platform'
|
@@ -12,7 +12,247 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
module Appium
|
16
|
+
module Core
|
17
|
+
# ref: https://github.com/appium/appium-base-driver/blob/master/lib/mjsonwp/routes.js
|
18
|
+
module Commands
|
19
|
+
# Some commands differ for each driver.
|
20
|
+
COMMAND = {
|
21
|
+
###
|
22
|
+
# W3C
|
23
|
+
###
|
24
|
+
status: [:get, 'status'],
|
25
|
+
|
26
|
+
#
|
27
|
+
# session handling
|
28
|
+
#
|
29
|
+
|
30
|
+
new_session: [:post, 'session'],
|
31
|
+
delete_session: [:delete, 'session/:session_id'],
|
32
|
+
|
33
|
+
#
|
34
|
+
# basic driver
|
35
|
+
#
|
36
|
+
|
37
|
+
get: [:post, 'session/:session_id/url'],
|
38
|
+
get_current_url: [:get, 'session/:session_id/url'],
|
39
|
+
back: [:post, 'session/:session_id/back'],
|
40
|
+
forward: [:post, 'session/:session_id/forward'],
|
41
|
+
refresh: [:post, 'session/:session_id/refresh'],
|
42
|
+
get_title: [:get, 'session/:session_id/title'],
|
43
|
+
|
44
|
+
#
|
45
|
+
# window and Frame handling
|
46
|
+
#
|
47
|
+
|
48
|
+
get_window_handle: [:get, 'session/:session_id/window'],
|
49
|
+
new_window: [:post, 'session/:session_id/window/new'],
|
50
|
+
close_window: [:delete, 'session/:session_id/window'],
|
51
|
+
switch_to_window: [:post, 'session/:session_id/window'],
|
52
|
+
get_window_handles: [:get, 'session/:session_id/window/handles'],
|
53
|
+
fullscreen_window: [:post, 'session/:session_id/window/fullscreen'],
|
54
|
+
minimize_window: [:post, 'session/:session_id/window/minimize'],
|
55
|
+
maximize_window: [:post, 'session/:session_id/window/maximize'],
|
56
|
+
set_window_size: [:post, 'session/:session_id/window/size'],
|
57
|
+
get_window_size: [:get, 'session/:session_id/window/size'],
|
58
|
+
set_window_position: [:post, 'session/:session_id/window/position'],
|
59
|
+
get_window_position: [:get, 'session/:session_id/window/position'],
|
60
|
+
set_window_rect: [:post, 'session/:session_id/window/rect'],
|
61
|
+
get_window_rect: [:get, 'session/:session_id/window/rect'],
|
62
|
+
switch_to_frame: [:post, 'session/:session_id/frame'],
|
63
|
+
switch_to_parent_frame: [:post, 'session/:session_id/frame/parent'],
|
64
|
+
|
65
|
+
#
|
66
|
+
# element
|
67
|
+
#
|
68
|
+
|
69
|
+
find_element: [:post, 'session/:session_id/element'],
|
70
|
+
find_elements: [:post, 'session/:session_id/elements'],
|
71
|
+
find_child_element: [:post, 'session/:session_id/element/:id/element'],
|
72
|
+
find_child_elements: [:post, 'session/:session_id/element/:id/elements'],
|
73
|
+
find_shadow_child_element: [:post, 'session/:session_id/shadow/:id/element'],
|
74
|
+
find_shadow_child_elements: [:post, 'session/:session_id/shadow/:id/elements'],
|
75
|
+
get_active_element: [:get, 'session/:session_id/element/active'],
|
76
|
+
is_element_selected: [:get, 'session/:session_id/element/:id/selected'],
|
77
|
+
get_element_attribute: [:get, 'session/:session_id/element/:id/attribute/:name'],
|
78
|
+
get_element_property: [:get, 'session/:session_id/element/:id/property/:name'],
|
79
|
+
get_element_css_value: [:get, 'session/:session_id/element/:id/css/:property_name'],
|
80
|
+
get_element_aria_role: [:get, 'session/:session_id/element/:id/computedrole'],
|
81
|
+
get_element_aria_label: [:get, 'session/:session_id/element/:id/computedlabel'],
|
82
|
+
get_element_text: [:get, 'session/:session_id/element/:id/text'],
|
83
|
+
get_element_tag_name: [:get, 'session/:session_id/element/:id/name'],
|
84
|
+
get_element_rect: [:get, 'session/:session_id/element/:id/rect'],
|
85
|
+
is_element_enabled: [:get, 'session/:session_id/element/:id/enabled'],
|
86
|
+
|
87
|
+
#
|
88
|
+
# document handling
|
89
|
+
#
|
90
|
+
|
91
|
+
get_page_source: [:get, 'session/:session_id/source'],
|
92
|
+
execute_script: [:post, 'session/:session_id/execute/sync'],
|
93
|
+
execute_async_script: [:post, 'session/:session_id/execute/async'],
|
94
|
+
|
95
|
+
#
|
96
|
+
# cookies
|
97
|
+
#
|
98
|
+
|
99
|
+
get_all_cookies: [:get, 'session/:session_id/cookie'],
|
100
|
+
get_cookie: [:get, 'session/:session_id/cookie/:name'],
|
101
|
+
add_cookie: [:post, 'session/:session_id/cookie'],
|
102
|
+
delete_cookie: [:delete, 'session/:session_id/cookie/:name'],
|
103
|
+
delete_all_cookies: [:delete, 'session/:session_id/cookie'],
|
104
|
+
|
105
|
+
#
|
106
|
+
# timeouts
|
107
|
+
#
|
108
|
+
|
109
|
+
set_timeout: [:post, 'session/:session_id/timeouts'],
|
110
|
+
|
111
|
+
#
|
112
|
+
# actions
|
113
|
+
#
|
114
|
+
|
115
|
+
actions: [:post, 'session/:session_id/actions'],
|
116
|
+
release_actions: [:delete, 'session/:session_id/actions'],
|
117
|
+
print_page: [:post, 'session/:session_id/print'],
|
118
|
+
|
119
|
+
#
|
120
|
+
# Element Operations
|
121
|
+
#
|
122
|
+
|
123
|
+
element_click: [:post, 'session/:session_id/element/:id/click'],
|
124
|
+
element_tap: [:post, 'session/:session_id/element/:id/tap'],
|
125
|
+
element_clear: [:post, 'session/:session_id/element/:id/clear'],
|
126
|
+
element_send_keys: [:post, 'session/:session_id/element/:id/value'],
|
127
|
+
|
128
|
+
#
|
129
|
+
# alerts
|
130
|
+
#
|
131
|
+
|
132
|
+
dismiss_alert: [:post, 'session/:session_id/alert/dismiss'],
|
133
|
+
accept_alert: [:post, 'session/:session_id/alert/accept'],
|
134
|
+
get_alert_text: [:get, 'session/:session_id/alert/text'],
|
135
|
+
send_alert_text: [:post, 'session/:session_id/alert/text'],
|
136
|
+
|
137
|
+
#
|
138
|
+
# screenshot
|
139
|
+
#
|
140
|
+
|
141
|
+
take_screenshot: [:get, 'session/:session_id/screenshot'],
|
142
|
+
take_element_screenshot: [:get, 'session/:session_id/element/:id/screenshot'],
|
143
|
+
|
144
|
+
#
|
145
|
+
# server extensions
|
146
|
+
#
|
147
|
+
|
148
|
+
upload_file: [:post, 'session/:session_id/se/file'],
|
149
|
+
|
150
|
+
###
|
151
|
+
# Used by Appium, but no in W3C
|
152
|
+
###
|
153
|
+
|
154
|
+
# ::Appium::Core::Base::Commands::OSS has the following commands and Appium also use them.
|
155
|
+
# Delegated to ::Appium::Core::Base::Commands::OSS commands
|
156
|
+
is_element_displayed: [:get, 'session/:session_id/element/:id/displayed'], # hint: https://w3c.github.io/webdriver/#element-displayedness
|
157
|
+
|
158
|
+
get_timeouts: [:get, 'session/:session_id/timeouts'], # https://w3c.github.io/webdriver/#get-timeouts
|
159
|
+
|
160
|
+
### rotatable
|
161
|
+
get_screen_orientation: [:get, 'session/:session_id/orientation'],
|
162
|
+
set_screen_orientation: [:post, 'session/:session_id/orientation'],
|
163
|
+
|
164
|
+
get_location: [:get, 'session/:session_id/location'],
|
165
|
+
set_location: [:post, 'session/:session_id/location'],
|
166
|
+
|
167
|
+
### For IME
|
168
|
+
ime_get_available_engines: [:get, 'session/:session_id/ime/available_engines'],
|
169
|
+
ime_get_active_engine: [:get, 'session/:session_id/ime/active_engine'],
|
170
|
+
ime_is_activated: [:get, 'session/:session_id/ime/activated'],
|
171
|
+
ime_deactivate: [:post, 'session/:session_id/ime/deactivate'],
|
172
|
+
ime_activate_engine: [:post, 'session/:session_id/ime/activate'],
|
173
|
+
|
174
|
+
### Logs
|
175
|
+
get_available_log_types: [:get, 'session/:session_id/log/types'],
|
176
|
+
get_log: [:post, 'session/:session_id/log'],
|
177
|
+
|
178
|
+
###
|
179
|
+
# Appium own
|
180
|
+
###
|
181
|
+
|
182
|
+
# common
|
183
|
+
available_contexts: [:get, 'session/:session_id/contexts'],
|
184
|
+
set_context: [:post, 'session/:session_id/context'],
|
185
|
+
current_context: [:get, 'session/:session_id/context'],
|
186
|
+
|
187
|
+
background_app: [:post, 'session/:session_id/appium/app/background'],
|
188
|
+
app_strings: [:post, 'session/:session_id/appium/app/strings'],
|
189
|
+
|
190
|
+
device_locked?: [:post, 'session/:session_id/appium/device/is_locked'],
|
191
|
+
unlock: [:post, 'session/:session_id/appium/device/unlock'],
|
192
|
+
lock: [:post, 'session/:session_id/appium/device/lock'],
|
193
|
+
device_time: [:get, 'session/:session_id/appium/device/system_time'],
|
194
|
+
install_app: [:post, 'session/:session_id/appium/device/install_app'],
|
195
|
+
remove_app: [:post, 'session/:session_id/appium/device/remove_app'],
|
196
|
+
app_installed?: [:post, 'session/:session_id/appium/device/app_installed'],
|
197
|
+
activate_app: [:post, 'session/:session_id/appium/device/activate_app'],
|
198
|
+
terminate_app: [:post, 'session/:session_id/appium/device/terminate_app'],
|
199
|
+
app_state: [:post, 'session/:session_id/appium/device/app_state'],
|
200
|
+
shake: [:post, 'session/:session_id/appium/device/shake'],
|
201
|
+
hide_keyboard: [:post, 'session/:session_id/appium/device/hide_keyboard'],
|
202
|
+
press_keycode: [:post, 'session/:session_id/appium/device/press_keycode'],
|
203
|
+
long_press_keycode: [:post, 'session/:session_id/appium/device/long_press_keycode'],
|
204
|
+
push_file: [:post, 'session/:session_id/appium/device/push_file'],
|
205
|
+
pull_file: [:post, 'session/:session_id/appium/device/pull_file'],
|
206
|
+
pull_folder: [:post, 'session/:session_id/appium/device/pull_folder'],
|
207
|
+
get_clipboard: [:post, 'session/:session_id/appium/device/get_clipboard'],
|
208
|
+
set_clipboard: [:post, 'session/:session_id/appium/device/set_clipboard'],
|
209
|
+
finger_print: [:post, 'session/:session_id/appium/device/finger_print'],
|
210
|
+
get_settings: [:get, 'session/:session_id/appium/settings'],
|
211
|
+
update_settings: [:post, 'session/:session_id/appium/settings'],
|
212
|
+
stop_recording_screen: [:post, 'session/:session_id/appium/stop_recording_screen'],
|
213
|
+
start_recording_screen: [:post, 'session/:session_id/appium/start_recording_screen'],
|
214
|
+
compare_images: [:post, 'session/:session_id/appium/compare_images'],
|
215
|
+
is_keyboard_shown: [:get, 'session/:session_id/appium/device/is_keyboard_shown'],
|
216
|
+
execute_driver: [:post, 'session/:session_id/appium/execute_driver'],
|
217
|
+
post_log_event: [:post, 'session/:session_id/appium/log_event'],
|
218
|
+
get_log_events: [:post, 'session/:session_id/appium/events']
|
219
|
+
}.freeze
|
220
|
+
|
221
|
+
COMMAND_ANDROID = {
|
222
|
+
open_notifications: [:post, 'session/:session_id/appium/device/open_notifications'],
|
223
|
+
toggle_airplane_mode: [:post, 'session/:session_id/appium/device/toggle_airplane_mode'],
|
224
|
+
start_activity: [:post, 'session/:session_id/appium/device/start_activity'],
|
225
|
+
current_activity: [:get, 'session/:session_id/appium/device/current_activity'],
|
226
|
+
current_package: [:get, 'session/:session_id/appium/device/current_package'],
|
227
|
+
get_system_bars: [:get, 'session/:session_id/appium/device/system_bars'],
|
228
|
+
get_display_density: [:get, 'session/:session_id/appium/device/display_density'],
|
229
|
+
toggle_wifi: [:post, 'session/:session_id/appium/device/toggle_wifi'],
|
230
|
+
toggle_data: [:post, 'session/:session_id/appium/device/toggle_data'],
|
231
|
+
toggle_location_services: [:post, 'session/:session_id/appium/device/toggle_location_services'],
|
232
|
+
get_performance_data_types: [:post, 'session/:session_id/appium/performanceData/types'],
|
233
|
+
get_performance_data: [:post, 'session/:session_id/appium/getPerformanceData'],
|
234
|
+
get_network_connection: [:get, 'session/:session_id/network_connection'], # defined also in OSS
|
235
|
+
set_network_connection: [:post, 'session/:session_id/network_connection'], # defined also in OSS
|
236
|
+
|
237
|
+
# only emulator
|
238
|
+
send_sms: [:post, 'session/:session_id/appium/device/send_sms'],
|
239
|
+
gsm_call: [:post, 'session/:session_id/appium/device/gsm_call'],
|
240
|
+
gsm_signal: [:post, 'session/:session_id/appium/device/gsm_signal'],
|
241
|
+
gsm_voice: [:post, 'session/:session_id/appium/device/gsm_voice'],
|
242
|
+
set_network_speed: [:post, 'session/:session_id/appium/device/network_speed'],
|
243
|
+
set_power_capacity: [:post, 'session/:session_id/appium/device/power_capacity'],
|
244
|
+
set_power_ac: [:post, 'session/:session_id/appium/device/power_ac'],
|
245
|
+
|
246
|
+
# For chromium: https://chromium.googlesource.com/chromium/src/+/master/chrome/test/chromedriver/server/http_handler.cc
|
247
|
+
chrome_send_command: [:post, 'session/:session_id/goog/cdp/execute']
|
248
|
+
}.freeze
|
249
|
+
|
250
|
+
COMMAND_IOS = {
|
251
|
+
touch_id: [:post, 'session/:session_id/appium/simulator/touch_id'],
|
252
|
+
toggle_touch_id_enrollment: [:post, 'session/:session_id/appium/simulator/toggle_touch_id_enrollment']
|
253
|
+
}.freeze
|
254
|
+
|
255
|
+
COMMANDS = {}.merge(COMMAND).merge(COMMAND_ANDROID).merge(COMMAND_IOS).freeze
|
256
|
+
end # module Commands
|
257
|
+
end # module Core
|
258
|
+
end # module Appium
|
@@ -17,18 +17,6 @@ module Appium
|
|
17
17
|
class Base
|
18
18
|
module Device
|
19
19
|
module AppManagement
|
20
|
-
def launch_app
|
21
|
-
execute :launch_app
|
22
|
-
end
|
23
|
-
|
24
|
-
def close_app
|
25
|
-
execute :close_app
|
26
|
-
end
|
27
|
-
|
28
|
-
def reset
|
29
|
-
execute :reset
|
30
|
-
end
|
31
|
-
|
32
20
|
def app_strings(language = nil)
|
33
21
|
opts = language ? { language: language } : {}
|
34
22
|
execute :app_strings, {}, opts
|
@@ -39,21 +27,9 @@ module Appium
|
|
39
27
|
raise NotImplementedError
|
40
28
|
end
|
41
29
|
|
42
|
-
def install_app(path,
|
43
|
-
replace: nil,
|
44
|
-
timeout: nil,
|
45
|
-
allow_test_packages: nil,
|
46
|
-
use_sdcard: nil,
|
47
|
-
grant_permissions: nil)
|
30
|
+
def install_app(path, options = {})
|
48
31
|
args = { appPath: path }
|
49
|
-
|
50
|
-
args[:options] = {} if options?(replace, timeout, allow_test_packages, use_sdcard, grant_permissions)
|
51
|
-
|
52
|
-
args[:options][:replace] = replace unless replace.nil?
|
53
|
-
args[:options][:timeout] = timeout unless timeout.nil?
|
54
|
-
args[:options][:allowTestPackages] = allow_test_packages unless allow_test_packages.nil?
|
55
|
-
args[:options][:useSdcard] = use_sdcard unless use_sdcard.nil?
|
56
|
-
args[:options][:grantPermissions] = grant_permissions unless grant_permissions.nil?
|
32
|
+
args[:options] = options unless options.empty?
|
57
33
|
|
58
34
|
execute :install_app, {}, args
|
59
35
|
end
|
@@ -29,10 +29,6 @@ module Appium
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
def switch_to_default_context
|
33
|
-
set_context nil
|
34
|
-
end
|
35
|
-
|
36
32
|
def current_context
|
37
33
|
execute :current_context
|
38
34
|
end
|
@@ -42,7 +38,7 @@ module Appium
|
|
42
38
|
execute(:available_contexts, {}) || []
|
43
39
|
end
|
44
40
|
|
45
|
-
def set_context(context =
|
41
|
+
def set_context(context = nil)
|
46
42
|
execute :set_context, {}, name: context
|
47
43
|
end
|
48
44
|
end # module ImeActions
|