appium_lib 9.0.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/.rubocop.yml +21 -0
- data/android_tests/lib/android/specs/android/helper.rb +3 -5
- data/android_tests/lib/android/specs/common/command.rb +47 -0
- data/android_tests/lib/android/specs/common/helper.rb +8 -8
- data/android_tests/lib/android/specs/common/web_context.rb +1 -1
- data/android_tests/lib/android/specs/driver.rb +19 -11
- data/android_tests/lib/format.rb +3 -3
- data/android_tests/lib/run.rb +7 -5
- data/android_tests/readme.md +1 -1
- data/appium_lib.gemspec +6 -7
- data/contributing.md +10 -0
- data/docs/android_docs.md +252 -217
- data/docs/ios_docs.md +257 -222
- data/docs/ios_xcuitest.md +32 -4
- data/ios_tests/lib/common.rb +11 -55
- data/ios_tests/lib/ios/specs/common/command.rb +44 -0
- data/ios_tests/lib/ios/specs/common/helper.rb +8 -8
- data/ios_tests/lib/ios/specs/device/device.rb +5 -5
- data/ios_tests/lib/ios/specs/driver.rb +34 -15
- data/ios_tests/lib/ios/specs/ios/element/textfield.rb +1 -1
- data/ios_tests/readme.md +1 -1
- data/ios_tests/upload/sauce_storage.rb +10 -8
- data/lib/appium_lib/android/element/button.rb +3 -3
- data/lib/appium_lib/android/element/text.rb +1 -1
- data/lib/appium_lib/android/element/textfield.rb +1 -1
- data/lib/appium_lib/android/helper.rb +12 -12
- data/lib/appium_lib/android/mobile_methods.rb +1 -3
- data/lib/appium_lib/common/command.rb +55 -0
- data/lib/appium_lib/common/helper.rb +7 -7
- data/lib/appium_lib/common/patch.rb +21 -8
- data/lib/appium_lib/common/search_context.rb +10 -0
- data/lib/appium_lib/common/version.rb +2 -2
- data/lib/appium_lib/common/wait.rb +8 -14
- data/lib/appium_lib/device/device.rb +65 -83
- data/lib/appium_lib/device/multi_touch.rb +2 -2
- data/lib/appium_lib/device/touch_actions.rb +4 -7
- data/lib/appium_lib/driver.rb +66 -38
- data/lib/appium_lib/ios/element/alert.rb +4 -4
- data/lib/appium_lib/ios/element/textfield.rb +3 -3
- data/lib/appium_lib/ios/errors.rb +6 -0
- data/lib/appium_lib/ios/helper.rb +25 -25
- data/lib/appium_lib/ios/mobile_methods.rb +2 -4
- data/readme.md +3 -1
- data/release_notes.md +13 -0
- metadata +23 -12
@@ -50,8 +50,8 @@ module Appium
|
|
50
50
|
|
51
51
|
string_ids = nil
|
52
52
|
|
53
|
-
if id_matches && id_matches.
|
54
|
-
space_suffix = ' ' * ' strings.xml: '.length
|
53
|
+
if id_matches && !id_matches.empty?
|
54
|
+
space_suffix = ' ' * 15 # 15 is ' strings.xml: '.length
|
55
55
|
string_ids = ''
|
56
56
|
|
57
57
|
# add first
|
@@ -130,11 +130,11 @@ module Appium
|
|
130
130
|
source_header = source[0..doctype_string.length].downcase
|
131
131
|
source_is_html = source_header.start_with?(doctype_string, '<html')
|
132
132
|
|
133
|
-
if source_is_html # parse html from webview
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
133
|
+
parser = if source_is_html # parse html from webview
|
134
|
+
@android_html_parser ||= Nokogiri::HTML::SAX::Parser.new(Common::HTMLElements.new)
|
135
|
+
else
|
136
|
+
@android_native_parser ||= Nokogiri::XML::SAX::Parser.new(AndroidElements.new)
|
137
|
+
end
|
138
138
|
parser.document.reset # ensure document is reset before parsing
|
139
139
|
parser.document.filter = class_name
|
140
140
|
parser.parse source
|
@@ -208,7 +208,7 @@ module Appium
|
|
208
208
|
index = results.length
|
209
209
|
index -= 1 if index >= 0
|
210
210
|
else
|
211
|
-
|
211
|
+
raise 'Index must be >= 1' unless index >= 1
|
212
212
|
index -= 1 if index >= 1
|
213
213
|
end
|
214
214
|
|
@@ -289,9 +289,9 @@ module Appium
|
|
289
289
|
value = %("#{value}")
|
290
290
|
|
291
291
|
if class_name == '*'
|
292
|
-
return _resource_id(value, "new UiSelector().resourceId(#{value});") +
|
292
|
+
return (_resource_id(value, "new UiSelector().resourceId(#{value});") +
|
293
293
|
"new UiSelector().descriptionContains(#{value});" \
|
294
|
-
"new UiSelector().textContains(#{value});"
|
294
|
+
"new UiSelector().textContains(#{value});")
|
295
295
|
end
|
296
296
|
|
297
297
|
class_name = %("#{class_name}")
|
@@ -326,9 +326,9 @@ module Appium
|
|
326
326
|
value = %("#{value}")
|
327
327
|
|
328
328
|
if class_name == '*'
|
329
|
-
return _resource_id(value, "new UiSelector().resourceId(#{value});") +
|
329
|
+
return (_resource_id(value, "new UiSelector().resourceId(#{value});") +
|
330
330
|
"new UiSelector().description(#{value});" \
|
331
|
-
"new UiSelector().text(#{value});"
|
331
|
+
"new UiSelector().text(#{value});")
|
332
332
|
end
|
333
333
|
|
334
334
|
class_name = %("#{class_name}")
|
@@ -8,9 +8,7 @@ module Appium
|
|
8
8
|
# find_elements :uiautomator, 'new UiSelector().clickable(true)'
|
9
9
|
# ```
|
10
10
|
def extended(_mod)
|
11
|
-
|
12
|
-
Selenium::WebDriver::SearchContext::FINDERS[:uiautomator] = '-android uiautomator'
|
13
|
-
end
|
11
|
+
::Appium::Driver::SearchContext::FINDERS[:uiautomator] = '-android uiautomator'
|
14
12
|
end
|
15
13
|
end # class << self
|
16
14
|
end # module Android
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Appium
|
2
|
+
class Driver
|
3
|
+
module Commands
|
4
|
+
COMMAND_NO_ARG = {
|
5
|
+
# common
|
6
|
+
shake: [:post, 'session/:session_id/appium/device/shake'.freeze],
|
7
|
+
launch_app: [:post, 'session/:session_id/appium/app/launch'.freeze],
|
8
|
+
close_app: [:post, 'session/:session_id/appium/app/close'.freeze],
|
9
|
+
reset: [:post, 'session/:session_id/appium/app/reset'.freeze],
|
10
|
+
device_locked?: [:post, 'session/:session_id/appium/device/is_locked'.freeze],
|
11
|
+
|
12
|
+
# Android
|
13
|
+
open_notifications: [:post, 'session/:session_id/appium/device/open_notifications'.freeze],
|
14
|
+
toggle_airplane_mode: [:post, 'session/:session_id/appium/device/toggle_airplane_mode'.freeze],
|
15
|
+
current_activity: [:get, 'session/:session_id/appium/device/current_activity'.freeze],
|
16
|
+
get_network_connection: [:get, 'session/:session_id/network_connection'.freeze],
|
17
|
+
|
18
|
+
# iOS
|
19
|
+
device_time: [:get, 'session/:session_id/appium/device/system_time'.freeze],
|
20
|
+
current_context: [:get, 'session/:session_id/context'.freeze]
|
21
|
+
}.freeze
|
22
|
+
|
23
|
+
COMMAND = {
|
24
|
+
# common
|
25
|
+
available_contexts: [:get, 'session/:session_id/contexts'.freeze],
|
26
|
+
set_context: [:post, 'session/:session_id/context'.freeze],
|
27
|
+
app_strings: [:post, 'session/:session_id/appium/app/strings'.freeze],
|
28
|
+
lock: [:post, 'session/:session_id/appium/device/lock'.freeze],
|
29
|
+
install_app: [:post, 'session/:session_id/appium/device/install_app'.freeze],
|
30
|
+
remove_app: [:post, 'session/:session_id/appium/device/remove_app'.freeze],
|
31
|
+
app_installed?: [:post, 'session/:session_id/appium/device/app_installed'.freeze],
|
32
|
+
background_app: [:post, 'session/:session_id/appium/app/background'.freeze],
|
33
|
+
hide_keyboard: [:post, 'session/:session_id/appium/device/hide_keyboard'.freeze],
|
34
|
+
press_keycode: [:post, 'session/:session_id/appium/device/press_keycode'.freeze],
|
35
|
+
long_press_keycode: [:post, 'session/:session_id/appium/device/long_press_keycode'.freeze],
|
36
|
+
set_immediate_value: [:post, 'session/:session_id/appium/element/:id/value'.freeze],
|
37
|
+
push_file: [:post, 'session/:session_id/appium/device/push_file'.freeze],
|
38
|
+
pull_file: [:post, 'session/:session_id/appium/device/pull_file'.freeze],
|
39
|
+
pull_folder: [:post, 'session/:session_id/appium/device/pull_folder'.freeze],
|
40
|
+
get_settings: [:get, 'session/:session_id/appium/settings'.freeze],
|
41
|
+
update_settings: [:post, 'session/:session_id/appium/settings'.freeze],
|
42
|
+
touch_actions: [:post, 'session/:session_id/touch/perform'.freeze],
|
43
|
+
multi_touch: [:post, 'session/:session_id/touch/multi/perform'.freeze],
|
44
|
+
|
45
|
+
# Android
|
46
|
+
start_activity: [:post, 'session/:session_id/appium/device/start_activity'.freeze],
|
47
|
+
end_coverage: [:post, 'session/:session_id/appium/app/end_test_coverage'.freeze],
|
48
|
+
set_network_connection: [:post, 'session/:session_id/network_connection'.freeze],
|
49
|
+
|
50
|
+
# iOS
|
51
|
+
touch_id: [:post, 'session/:session_id/appium/simulator/touch_id'.freeze]
|
52
|
+
}.merge(COMMAND_NO_ARG).merge(::Selenium::WebDriver::Remote::Bridge::COMMANDS).freeze
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -55,11 +55,11 @@ module Appium
|
|
55
55
|
|
56
56
|
def _print_source(source)
|
57
57
|
opts = Nokogiri::XML::ParseOptions::NOBLANKS | Nokogiri::XML::ParseOptions::NONET
|
58
|
-
if source.start_with? '<html'
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
58
|
+
doc = if source.start_with? '<html'
|
59
|
+
Nokogiri::HTML(source) { |cfg| cfg.options = opts }
|
60
|
+
else
|
61
|
+
Nokogiri::XML(source) { |cfg| cfg.options = opts }
|
62
|
+
end
|
63
63
|
puts doc.to_xml indent: 2
|
64
64
|
end
|
65
65
|
|
@@ -215,8 +215,8 @@ module Appium
|
|
215
215
|
end
|
216
216
|
|
217
217
|
def _no_such_element
|
218
|
-
|
219
|
-
|
218
|
+
error_message = 'An element could not be located on the page using the given search parameters.'
|
219
|
+
raise Selenium::WebDriver::Error::NoSuchElementError, error_message
|
220
220
|
end
|
221
221
|
end # module Common
|
222
222
|
end # module Appium
|
@@ -52,10 +52,13 @@ end # module Appium
|
|
52
52
|
#
|
53
53
|
# Requires from lib/selenium/webdriver/remote.rb
|
54
54
|
require 'selenium/webdriver/remote/capabilities'
|
55
|
+
require 'selenium/webdriver/remote/w3c_capabilities'
|
55
56
|
require 'selenium/webdriver/remote/bridge'
|
57
|
+
require 'selenium/webdriver/remote/w3c_bridge'
|
56
58
|
require 'selenium/webdriver/remote/server_error'
|
57
59
|
require 'selenium/webdriver/remote/response'
|
58
60
|
require 'selenium/webdriver/remote/commands'
|
61
|
+
require 'selenium/webdriver/remote/w3c_commands'
|
59
62
|
require 'selenium/webdriver/remote/http/common'
|
60
63
|
require 'selenium/webdriver/remote/http/default'
|
61
64
|
|
@@ -67,14 +70,15 @@ def patch_webdriver_bridge
|
|
67
70
|
Selenium::WebDriver::Remote::Bridge.class_eval do
|
68
71
|
# Code from lib/selenium/webdriver/remote/bridge.rb
|
69
72
|
def raw_execute(command, opts = {}, command_hash = nil)
|
70
|
-
verb, path =
|
71
|
-
|
72
|
-
path = path.dup
|
73
|
+
verb, path = commands(command) || raise(ArgumentError, "unknown command: #{command.inspect}")
|
74
|
+
path = path.dup
|
73
75
|
|
74
76
|
path[':session_id'] = @session_id if path.include?(':session_id')
|
75
77
|
|
76
78
|
begin
|
77
|
-
opts.each
|
79
|
+
opts.each do |key, value|
|
80
|
+
path[key.inspect] = escaper.escape(value.to_s)
|
81
|
+
end
|
78
82
|
rescue IndexError
|
79
83
|
raise ArgumentError, "#{opts.inspect} invalid for #{command.inspect}"
|
80
84
|
end
|
@@ -107,10 +111,11 @@ def patch_webdriver_bridge
|
|
107
111
|
else
|
108
112
|
Appium::Logger.ap_info print_command
|
109
113
|
end
|
110
|
-
|
114
|
+
elsif command_hash
|
115
|
+
# non-standard command hash
|
111
116
|
# It's important to output this for debugging problems.
|
112
117
|
# for example invalid JSON will not be a Hash
|
113
|
-
Appium::Logger.ap_info command_hash
|
118
|
+
Appium::Logger.ap_info command_hash
|
114
119
|
end
|
115
120
|
delay = $driver.global_webdriver_http_sleep
|
116
121
|
sleep delay if !delay.nil? && delay > 0
|
@@ -131,7 +136,7 @@ class Selenium::WebDriver::Remote::Response
|
|
131
136
|
case val
|
132
137
|
when Hash
|
133
138
|
msg = val['origValue'] || val['message'] or return 'unknown error'
|
134
|
-
msg << " (#{
|
139
|
+
msg << " (#{val['class']})" if val['class']
|
135
140
|
when String
|
136
141
|
msg = val
|
137
142
|
else
|
@@ -144,5 +149,13 @@ end
|
|
144
149
|
|
145
150
|
class Selenium::WebDriver::Remote::Http::Common # rubocop:disable Style/ClassAndModuleChildren
|
146
151
|
remove_const :DEFAULT_HEADERS if defined? DEFAULT_HEADERS
|
147
|
-
DEFAULT_HEADERS = { 'Accept' => CONTENT_TYPE, 'User-Agent' => "appium/ruby_lib/#{::Appium::VERSION}" }
|
152
|
+
DEFAULT_HEADERS = { 'Accept' => CONTENT_TYPE, 'User-Agent' => "appium/ruby_lib/#{::Appium::VERSION}" }.freeze
|
153
|
+
end
|
154
|
+
|
155
|
+
def patch_remote_driver_commands
|
156
|
+
Selenium::WebDriver::Remote::Bridge.class_eval do
|
157
|
+
def commands(command)
|
158
|
+
::Appium::Driver::Commands::COMMAND[command]
|
159
|
+
end
|
160
|
+
end
|
148
161
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Appium
|
2
2
|
# Version and Date are defined on the 'Appium' module, not 'Appium::Common'
|
3
|
-
VERSION = '9.
|
4
|
-
DATE = '2016-12-
|
3
|
+
VERSION = '9.1.0'.freeze unless defined? ::Appium::VERSION
|
4
|
+
DATE = '2016-12-18'.freeze unless defined? ::Appium::DATE
|
5
5
|
end
|
@@ -11,7 +11,7 @@ module Appium
|
|
11
11
|
invalid_keys = []
|
12
12
|
opts.keys.each { |key| invalid_keys << key unless valid_keys.include?(key) }
|
13
13
|
# [:one, :two] => :one, :two
|
14
|
-
|
14
|
+
raise "Invalid keys #{invalid_keys.to_s[1..-2]}. Valid keys are #{valid_keys.to_s[1..-2]}" unless invalid_keys.empty?
|
15
15
|
|
16
16
|
timeout = opts.fetch(:timeout, 30)
|
17
17
|
interval = opts.fetch(:interval, 0.5)
|
@@ -24,12 +24,10 @@ module Appium
|
|
24
24
|
|
25
25
|
until Time.now > end_time
|
26
26
|
begin
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
return block.call
|
32
|
-
end
|
27
|
+
return block.call unless return_if_true
|
28
|
+
|
29
|
+
result = block.call
|
30
|
+
return result if result
|
33
31
|
rescue ::Errno::ECONNREFUSED => e
|
34
32
|
raise e
|
35
33
|
rescue *ignored => last_error # rubocop:disable Lint/HandleExceptions
|
@@ -39,21 +37,17 @@ module Appium
|
|
39
37
|
sleep interval
|
40
38
|
end
|
41
39
|
|
42
|
-
|
43
|
-
msg = message.dup
|
44
|
-
else
|
45
|
-
msg = "timed out after #{timeout} seconds"
|
46
|
-
end
|
40
|
+
msg = message ? message.dup : "timed out after #{timeout} seconds"
|
47
41
|
|
48
42
|
msg << " (#{last_error.message})" if last_error
|
49
43
|
|
50
|
-
|
44
|
+
raise Selenium::WebDriver::Error::TimeOutError, msg
|
51
45
|
end
|
52
46
|
|
53
47
|
# process opts before calling _generic_wait
|
54
48
|
def _process_wait_opts(opts)
|
55
49
|
opts = { timeout: opts } if opts.is_a?(Numeric)
|
56
|
-
|
50
|
+
raise 'opts must be a hash' unless opts.is_a? Hash
|
57
51
|
opts
|
58
52
|
end
|
59
53
|
|
@@ -4,24 +4,6 @@ module Appium
|
|
4
4
|
module Device
|
5
5
|
extend Forwardable
|
6
6
|
|
7
|
-
NoArgMethods = {
|
8
|
-
post: {
|
9
|
-
open_notifications: 'session/:session_id/appium/device/open_notifications',
|
10
|
-
shake: 'session/:session_id/appium/device/shake',
|
11
|
-
launch_app: 'session/:session_id/appium/app/launch',
|
12
|
-
close_app: 'session/:session_id/appium/app/close',
|
13
|
-
reset: 'session/:session_id/appium/app/reset',
|
14
|
-
toggle_airplane_mode: 'session/:session_id/appium/device/toggle_airplane_mode',
|
15
|
-
device_locked?: 'session/:session_id/appium/device/is_locked'
|
16
|
-
},
|
17
|
-
get: {
|
18
|
-
device_time: 'session/:session_id/appium/device/system_time',
|
19
|
-
current_activity: 'session/:session_id/appium/device/current_activity',
|
20
|
-
current_context: 'session/:session_id/context',
|
21
|
-
get_network_connection: 'session/:session_id/network_connection'
|
22
|
-
}
|
23
|
-
}
|
24
|
-
|
25
7
|
# @!method app_strings
|
26
8
|
# Return the hash of all localization strings.
|
27
9
|
# ```ruby
|
@@ -117,49 +99,49 @@ module Appium
|
|
117
99
|
def extended(_mod)
|
118
100
|
extend_webdriver_with_forwardable
|
119
101
|
|
120
|
-
|
121
|
-
|
102
|
+
::Appium::Driver::Commands::COMMAND_NO_ARG.each_key do |method|
|
103
|
+
add_endpoint_method method
|
122
104
|
end
|
123
105
|
|
124
|
-
add_endpoint_method(:available_contexts
|
106
|
+
add_endpoint_method(:available_contexts) do
|
125
107
|
def available_contexts
|
126
108
|
# return empty array instead of nil on failure
|
127
109
|
execute(:available_contexts, {}) || []
|
128
110
|
end
|
129
111
|
end
|
130
112
|
|
131
|
-
add_endpoint_method(:app_strings
|
113
|
+
add_endpoint_method(:app_strings) do
|
132
114
|
def app_strings(language = nil)
|
133
115
|
opts = language ? { language: language } : {}
|
134
116
|
execute :app_strings, {}, opts
|
135
117
|
end
|
136
118
|
end
|
137
119
|
|
138
|
-
add_endpoint_method(:lock
|
120
|
+
add_endpoint_method(:lock) do
|
139
121
|
def lock(duration)
|
140
122
|
execute :lock, {}, seconds: duration
|
141
123
|
end
|
142
124
|
end
|
143
125
|
|
144
|
-
add_endpoint_method(:install_app
|
126
|
+
add_endpoint_method(:install_app) do
|
145
127
|
def install_app(path)
|
146
128
|
execute :install_app, {}, appPath: path
|
147
129
|
end
|
148
130
|
end
|
149
131
|
|
150
|
-
add_endpoint_method(:remove_app
|
132
|
+
add_endpoint_method(:remove_app) do
|
151
133
|
def remove_app(id)
|
152
134
|
execute :remove_app, {}, appId: id
|
153
135
|
end
|
154
136
|
end
|
155
137
|
|
156
|
-
add_endpoint_method(:app_installed
|
138
|
+
add_endpoint_method(:app_installed?) do
|
157
139
|
def app_installed?(app_id)
|
158
140
|
execute :app_installed?, {}, bundleId: app_id
|
159
141
|
end
|
160
142
|
end
|
161
143
|
|
162
|
-
add_endpoint_method(:background_app
|
144
|
+
add_endpoint_method(:background_app) do
|
163
145
|
def background_app(duration)
|
164
146
|
execute :background_app, {}, seconds: duration
|
165
147
|
end
|
@@ -178,18 +160,18 @@ module Appium
|
|
178
160
|
# start_activity app_package: 'io.appium.android.apis',
|
179
161
|
# app_activity: '.accessibility.AccessibilityNodeProviderActivity'
|
180
162
|
# ```
|
181
|
-
add_endpoint_method(:start_activity
|
163
|
+
add_endpoint_method(:start_activity) do
|
182
164
|
def start_activity(opts)
|
183
|
-
|
165
|
+
raise 'opts must be a hash' unless opts.is_a? Hash
|
184
166
|
app_package = opts[:app_package]
|
185
|
-
|
167
|
+
raise 'app_package is required' unless app_package
|
186
168
|
app_activity = opts[:app_activity]
|
187
|
-
|
169
|
+
raise 'app_activity is required' unless opts[:app_activity]
|
188
170
|
app_wait_package = opts.fetch(:app_wait_package, '')
|
189
171
|
app_wait_activity = opts.fetch(:app_wait_activity, '')
|
190
172
|
|
191
173
|
unknown_opts = opts.keys - [:app_package, :app_activity, :app_wait_package, :app_wait_activity]
|
192
|
-
|
174
|
+
raise "Unknown options #{unknown_opts}" unless unknown_opts.empty?
|
193
175
|
|
194
176
|
execute :start_activity, {}, appPackage: app_package,
|
195
177
|
appActivity: app_activity,
|
@@ -198,13 +180,13 @@ module Appium
|
|
198
180
|
end
|
199
181
|
end
|
200
182
|
|
201
|
-
add_endpoint_method(:set_context
|
183
|
+
add_endpoint_method(:set_context) do
|
202
184
|
def set_context(context = null)
|
203
185
|
execute :set_context, {}, name: context
|
204
186
|
end
|
205
187
|
end
|
206
188
|
|
207
|
-
add_endpoint_method(:hide_keyboard
|
189
|
+
add_endpoint_method(:hide_keyboard) do
|
208
190
|
def hide_keyboard(close_key = nil)
|
209
191
|
# Android can only tapOutside.
|
210
192
|
if $driver.device_is_android?
|
@@ -222,7 +204,7 @@ module Appium
|
|
222
204
|
end
|
223
205
|
end
|
224
206
|
|
225
|
-
add_endpoint_method(:press_keycode
|
207
|
+
add_endpoint_method(:press_keycode) do
|
226
208
|
def press_keycode(key, metastate = nil)
|
227
209
|
args = { keycode: key }
|
228
210
|
args[:metastate] = metastate if metastate
|
@@ -230,7 +212,7 @@ module Appium
|
|
230
212
|
end
|
231
213
|
end
|
232
214
|
|
233
|
-
add_endpoint_method(:long_press_keycode
|
215
|
+
add_endpoint_method(:long_press_keycode) do
|
234
216
|
def long_press_keycode(key, metastate = nil)
|
235
217
|
args = { keycode: key }
|
236
218
|
args[:metastate] = metastate if metastate
|
@@ -239,20 +221,20 @@ module Appium
|
|
239
221
|
end
|
240
222
|
|
241
223
|
# TODO: TEST ME
|
242
|
-
add_endpoint_method(:set_immediate_value
|
224
|
+
add_endpoint_method(:set_immediate_value) do
|
243
225
|
def set_immediate_value(element, value)
|
244
226
|
execute :set_immediate_value, { id: element.ref }, value: value
|
245
227
|
end
|
246
228
|
end
|
247
229
|
|
248
|
-
add_endpoint_method(:push_file
|
230
|
+
add_endpoint_method(:push_file) do
|
249
231
|
def push_file(path, filedata)
|
250
232
|
encoded_data = Base64.encode64 filedata
|
251
233
|
execute :push_file, {}, path: path, data: encoded_data
|
252
234
|
end
|
253
235
|
end
|
254
236
|
|
255
|
-
add_endpoint_method(:pull_file
|
237
|
+
add_endpoint_method(:pull_file) do
|
256
238
|
def pull_file(path)
|
257
239
|
data = execute :pull_file, {}, path: path
|
258
240
|
Base64.decode64 data
|
@@ -260,7 +242,7 @@ module Appium
|
|
260
242
|
end
|
261
243
|
|
262
244
|
# TODO: TEST ME
|
263
|
-
add_endpoint_method(:pull_folder
|
245
|
+
add_endpoint_method(:pull_folder) do
|
264
246
|
def pull_folder(path)
|
265
247
|
data = execute :pull_folder, {}, path: path
|
266
248
|
Base64.decode64 data
|
@@ -268,26 +250,26 @@ module Appium
|
|
268
250
|
end
|
269
251
|
|
270
252
|
# TODO: TEST ME
|
271
|
-
add_endpoint_method(:touch_id
|
253
|
+
add_endpoint_method(:touch_id) do
|
272
254
|
def touch_id(match = true)
|
273
255
|
execute :touch_id, {}, match: match
|
274
256
|
end
|
275
257
|
end
|
276
258
|
|
277
259
|
# TODO: TEST ME
|
278
|
-
add_endpoint_method(:end_coverage
|
260
|
+
add_endpoint_method(:end_coverage) do
|
279
261
|
def end_coverage(path, intent)
|
280
262
|
execute :end_coverage, {}, path: path, intent: intent
|
281
263
|
end
|
282
264
|
end
|
283
265
|
|
284
|
-
add_endpoint_method(:get_settings
|
266
|
+
add_endpoint_method(:get_settings) do
|
285
267
|
def get_settings
|
286
268
|
execute :get_settings, {}
|
287
269
|
end
|
288
270
|
end
|
289
271
|
|
290
|
-
add_endpoint_method(:update_settings
|
272
|
+
add_endpoint_method(:update_settings) do
|
291
273
|
def update_settings(settings)
|
292
274
|
execute :update_settings, {}, settings: settings
|
293
275
|
end
|
@@ -308,7 +290,7 @@ module Appium
|
|
308
290
|
# 2 (Wifi only) | 0 | 1 | 0
|
309
291
|
# 0 (None) | 0 | 0 | 0
|
310
292
|
#
|
311
|
-
add_endpoint_method(:set_network_connection
|
293
|
+
add_endpoint_method(:set_network_connection) do
|
312
294
|
def set_network_connection(mode)
|
313
295
|
execute :set_network_connection, {}, type: mode
|
314
296
|
end
|
@@ -322,13 +304,11 @@ module Appium
|
|
322
304
|
# def extended
|
323
305
|
|
324
306
|
# @private
|
325
|
-
def add_endpoint_method(method
|
307
|
+
def add_endpoint_method(method)
|
326
308
|
if block_given?
|
327
|
-
|
328
|
-
# Because creating Procs from blocks is slow
|
329
|
-
create_bridge_command method, verb, path, &Proc.new
|
309
|
+
create_bridge_command method, &Proc.new
|
330
310
|
else
|
331
|
-
create_bridge_command method
|
311
|
+
create_bridge_command method
|
332
312
|
end
|
333
313
|
|
334
314
|
delegate_driver_method method
|
@@ -355,31 +335,7 @@ module Appium
|
|
355
335
|
end
|
356
336
|
|
357
337
|
# @private
|
358
|
-
def create_bridge_command(method
|
359
|
-
Selenium::WebDriver::Remote::Bridge.class_eval do
|
360
|
-
command method, verb, path
|
361
|
-
if block_given?
|
362
|
-
class_eval(&Proc.new)
|
363
|
-
else
|
364
|
-
define_method(method) { execute method }
|
365
|
-
end
|
366
|
-
end
|
367
|
-
end
|
368
|
-
|
369
|
-
# @private
|
370
|
-
def add_bridge_method(method)
|
371
|
-
if block_given?
|
372
|
-
create_bridge method, &Proc.new
|
373
|
-
else
|
374
|
-
create_bridge method
|
375
|
-
end
|
376
|
-
|
377
|
-
delegate_driver_method method
|
378
|
-
delegate_from_appium_driver method
|
379
|
-
end
|
380
|
-
|
381
|
-
# @private
|
382
|
-
def create_bridge(method)
|
338
|
+
def create_bridge_command(method)
|
383
339
|
Selenium::WebDriver::Remote::Bridge.class_eval do
|
384
340
|
if block_given?
|
385
341
|
class_eval(&Proc.new)
|
@@ -399,19 +355,45 @@ module Appium
|
|
399
355
|
# ```
|
400
356
|
def extend_search_contexts
|
401
357
|
Selenium::WebDriver::SearchContext.class_eval do
|
402
|
-
|
358
|
+
def find_element_with_appium(*args)
|
359
|
+
how, what = extract_args(args)
|
360
|
+
|
361
|
+
finders = ::Selenium::WebDriver::SearchContext::FINDERS.merge ::Appium::Driver::SearchContext::FINDERS
|
362
|
+
by = finders[how.to_sym]
|
363
|
+
raise ArgumentError, "cannot find element by #{how.inspect}" unless by
|
364
|
+
|
365
|
+
begin
|
366
|
+
bridge.find_element_by by, what.to_s, ref
|
367
|
+
rescue Selenium::WebDriver::Error::TimeOutError
|
368
|
+
raise Selenium::WebDriver::Error::NoSuchElementError
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
def find_elements_with_appium(*args)
|
373
|
+
how, what = extract_args(args)
|
374
|
+
|
375
|
+
finders = ::Selenium::WebDriver::SearchContext::FINDERS.merge ::Appium::Driver::SearchContext::FINDERS
|
376
|
+
by = finders[how.to_sym]
|
377
|
+
raise ArgumentError, "cannot find element by #{how.inspect}" unless by
|
378
|
+
|
379
|
+
begin
|
380
|
+
bridge.find_elements_by by, what.to_s, ref
|
381
|
+
rescue Selenium::WebDriver::Error::TimeOutError
|
382
|
+
raise Selenium::WebDriver::Error::NoSuchElementError
|
383
|
+
end
|
384
|
+
end
|
403
385
|
end
|
404
386
|
end
|
405
387
|
|
406
388
|
def add_touch_actions
|
407
|
-
add_endpoint_method(:touch_actions
|
389
|
+
add_endpoint_method(:touch_actions) do
|
408
390
|
def touch_actions(actions)
|
409
391
|
actions = { actions: [actions].flatten }
|
410
392
|
execute :touch_actions, {}, actions
|
411
393
|
end
|
412
394
|
end
|
413
395
|
|
414
|
-
add_endpoint_method(:multi_touch
|
396
|
+
add_endpoint_method(:multi_touch) do
|
415
397
|
def multi_touch(actions)
|
416
398
|
execute :multi_touch, {}, actions: actions
|
417
399
|
end
|
@@ -440,7 +422,7 @@ module Appium
|
|
440
422
|
# ```ruby
|
441
423
|
# ime_activate engine: 'com.android.inputmethod.latin/.LatinIME'
|
442
424
|
# ```
|
443
|
-
|
425
|
+
add_endpoint_method(:ime_activate) do
|
444
426
|
def ime_activate(ime_name)
|
445
427
|
execute :imeActivateEngine, {}, engine: ime_name
|
446
428
|
end
|
@@ -453,7 +435,7 @@ module Appium
|
|
453
435
|
# ```ruby
|
454
436
|
# ime_available_engines #=> Get the list of IME installed in the target device
|
455
437
|
# ```
|
456
|
-
|
438
|
+
add_endpoint_method(:ime_available_engines) do
|
457
439
|
def ime_available_engines
|
458
440
|
execute :imeGetAvailableEngines
|
459
441
|
end
|
@@ -466,7 +448,7 @@ module Appium
|
|
466
448
|
# ```ruby
|
467
449
|
# ime_active_engine #=> Get the current active IME such as 'com.android.inputmethod.latin/.LatinIME'
|
468
450
|
# ```
|
469
|
-
|
451
|
+
add_endpoint_method(:ime_active_engine) do
|
470
452
|
def ime_active_engine
|
471
453
|
execute :imeGetActiveEngine
|
472
454
|
end
|
@@ -479,7 +461,7 @@ module Appium
|
|
479
461
|
# ```ruby
|
480
462
|
# ime_activated #=> True if IME is activated
|
481
463
|
# ```
|
482
|
-
|
464
|
+
add_endpoint_method(:ime_activated) do
|
483
465
|
def ime_activated
|
484
466
|
execute :imeIsActivated
|
485
467
|
end
|
@@ -493,7 +475,7 @@ module Appium
|
|
493
475
|
# ```ruby
|
494
476
|
# ime_deactivate #=> Deactivate current IME engine
|
495
477
|
# ```
|
496
|
-
|
478
|
+
add_endpoint_method(:ime_deactivate) do
|
497
479
|
def ime_deactivate
|
498
480
|
execute :imeDeactivate, {}
|
499
481
|
end
|