appium_lib 9.6.1 → 9.7.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 +2 -2
- data/CHANGELOG.md +43 -0
- data/Rakefile +1 -1
- data/appium_lib.gemspec +1 -1
- data/docs/android_docs.md +440 -1295
- data/docs/docs.md +10 -103
- data/docs/index_paths.md +2 -0
- data/docs/ios_docs.md +725 -1674
- data/docs/migration.md +17 -0
- data/lib/appium_lib.rb +1 -2
- data/lib/appium_lib/android/android.rb +20 -0
- data/lib/appium_lib/android/{helper.rb → common/helper.rb} +1 -1
- data/lib/appium_lib/android/uiautomator2.rb +5 -4
- data/lib/appium_lib/android/uiautomator2/bridge.rb +16 -0
- data/lib/appium_lib/appium.rb +201 -0
- data/lib/appium_lib/common/helper.rb +18 -20
- data/lib/appium_lib/common/log.rb +24 -0
- data/lib/appium_lib/common/multi_touch.rb +89 -0
- data/lib/appium_lib/common/touch_actions.rb +48 -0
- data/lib/appium_lib/common/wait.rb +10 -49
- data/lib/appium_lib/core/android.rb +4 -0
- data/lib/appium_lib/core/android/device.rb +142 -0
- data/lib/appium_lib/core/android/search_context.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_uiautomator2.rb +4 -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 +40 -0
- data/lib/appium_lib/core/common/base/http_default.rb +12 -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/{common → core/common}/command.rb +20 -16
- data/lib/appium_lib/core/common/device.rb +470 -0
- data/lib/appium_lib/core/common/error.rb +13 -0
- data/lib/appium_lib/core/common/log.rb +30 -0
- data/lib/appium_lib/{logger.rb → core/common/logger.rb} +2 -0
- data/lib/appium_lib/core/core.rb +38 -0
- data/lib/appium_lib/core/device/multi_touch.rb +213 -0
- data/lib/appium_lib/core/device/touch_actions.rb +206 -0
- data/lib/appium_lib/core/driver.rb +274 -0
- data/lib/appium_lib/core/ios.rb +6 -0
- data/lib/appium_lib/core/ios/device.rb +44 -0
- data/lib/appium_lib/core/ios/search_context.rb +27 -0
- data/lib/appium_lib/core/ios/uiautomation/bridge.rb +17 -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/{ios → core/ios}/xcuitest/device.rb +5 -5
- data/lib/appium_lib/{ios → core/ios}/xcuitest/search_context.rb +13 -9
- data/lib/appium_lib/core/ios_xcuitest.rb +7 -0
- data/lib/appium_lib/core/patch.rb +56 -0
- data/lib/appium_lib/driver.rb +174 -446
- data/lib/appium_lib/ios/{errors.rb → common/errors.rb} +0 -0
- data/lib/appium_lib/ios/{helper.rb → common/helper.rb} +9 -110
- data/lib/appium_lib/ios/ios.rb +20 -0
- data/lib/appium_lib/ios/xcuitest.rb +1 -3
- data/lib/appium_lib/ios/xcuitest/bridge.rb +19 -0
- data/lib/appium_lib/ios/xcuitest/command.rb +4 -1
- data/lib/appium_lib/ios/xcuitest/{gestures.rb → command/gestures.rb} +1 -1
- data/lib/appium_lib/ios/xcuitest/element.rb +1 -18
- data/lib/appium_lib/ios/xcuitest/helper.rb +0 -6
- data/lib/appium_lib/sauce_labs.rb +29 -0
- data/lib/appium_lib/version.rb +5 -0
- data/release_notes.md +8 -0
- metadata +50 -25
- data/lib/appium_lib/android/client_xpath.rb +0 -51
- data/lib/appium_lib/android/device.rb +0 -39
- data/lib/appium_lib/android/mobile_methods.rb +0 -15
- data/lib/appium_lib/android/patch.rb +0 -16
- data/lib/appium_lib/capabilities.rb +0 -13
- data/lib/appium_lib/common/element/window.rb +0 -10
- data/lib/appium_lib/common/error.rb +0 -8
- data/lib/appium_lib/common/patch.rb +0 -190
- data/lib/appium_lib/common/search_context.rb +0 -10
- data/lib/appium_lib/common/version.rb +0 -5
- data/lib/appium_lib/device/device.rb +0 -611
- data/lib/appium_lib/device/multi_touch.rb +0 -225
- data/lib/appium_lib/device/touch_actions.rb +0 -230
- data/lib/appium_lib/ios/mobile_methods.rb +0 -25
- data/lib/appium_lib/ios/patch.rb +0 -22
data/docs/migration.md
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
### Breaking Changes in 9.6.0
|
|
2
|
+
Raise warning if users call `Appium::Driver.new(opts)`.
|
|
3
|
+
|
|
4
|
+
- After
|
|
5
|
+
|
|
6
|
+
```ruby
|
|
7
|
+
Appium::Driver.new(opts).start_driver # Raise warning.
|
|
8
|
+
Appium::Driver.new(opts, true).start_driver # $driver is defined.
|
|
9
|
+
Appium::Driver.new(opts, false).start_driver # $driver isn't defined.
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
- Before
|
|
13
|
+
|
|
14
|
+
```ruby
|
|
15
|
+
Appium::Driver.new(opts).start_driver # $driver is defined.
|
|
16
|
+
```
|
|
17
|
+
|
|
1
18
|
### Breaking Changes in 9.3.7
|
|
2
19
|
change `@selenium_driver.find_element/s_with_appium` to `@selenium_driver.find_element/s`.
|
|
3
20
|
ref: https://github.com/appium/ruby_lib/pull/532
|
data/lib/appium_lib.rb
CHANGED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require_relative 'common/helper'
|
|
2
|
+
|
|
3
|
+
require_relative 'element/alert'
|
|
4
|
+
require_relative 'element/button'
|
|
5
|
+
require_relative 'element/generic'
|
|
6
|
+
require_relative 'element/textfield'
|
|
7
|
+
require_relative 'element/text'
|
|
8
|
+
|
|
9
|
+
# android - uiautomator2
|
|
10
|
+
require_relative 'uiautomator2'
|
|
11
|
+
|
|
12
|
+
module Appium
|
|
13
|
+
module Android
|
|
14
|
+
class Bridge
|
|
15
|
+
def self.for(target)
|
|
16
|
+
target.extend Appium::Android
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -91,7 +91,7 @@ module Appium
|
|
|
91
91
|
source_is_html = source_header.start_with?(doctype_string, '<html')
|
|
92
92
|
|
|
93
93
|
parser = if source_is_html # parse html from webview
|
|
94
|
-
@android_html_parser ||= Nokogiri::HTML::SAX::Parser.new(Common::HTMLElements.new)
|
|
94
|
+
@android_html_parser ||= Nokogiri::HTML::SAX::Parser.new(Appium::Common::HTMLElements.new)
|
|
95
95
|
else
|
|
96
96
|
@android_native_parser ||= Nokogiri::XML::SAX::Parser.new(AndroidElements.new)
|
|
97
97
|
end
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
require_relative 'uiautomator2/helper'
|
|
2
2
|
require_relative 'uiautomator2/element'
|
|
3
|
+
require_relative 'uiautomator2/bridge'
|
|
3
4
|
|
|
4
5
|
module Appium
|
|
5
|
-
module
|
|
6
|
-
module
|
|
6
|
+
module Android
|
|
7
|
+
module Uiautomator2
|
|
7
8
|
# parent
|
|
8
|
-
end # module
|
|
9
|
-
end # module
|
|
9
|
+
end # module Uiautomator2
|
|
10
|
+
end # module Android
|
|
10
11
|
end # module Appium
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require_relative '../android'
|
|
2
|
+
|
|
3
|
+
module Appium
|
|
4
|
+
module Android
|
|
5
|
+
module Uiautomator2
|
|
6
|
+
class Bridge
|
|
7
|
+
def self.for(target)
|
|
8
|
+
target.extend Appium::Android
|
|
9
|
+
target.extend Appium::Android::Uiautomator2
|
|
10
|
+
target.extend Appium::Android::Uiautomator2::Helper
|
|
11
|
+
target.extend Appium::Android::Uiautomator2::Element
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
require 'rubygems'
|
|
2
|
+
require 'selenium-webdriver'
|
|
3
|
+
require 'nokogiri'
|
|
4
|
+
|
|
5
|
+
# base
|
|
6
|
+
require_relative 'driver'
|
|
7
|
+
require_relative 'sauce_labs'
|
|
8
|
+
|
|
9
|
+
# common
|
|
10
|
+
require_relative 'common/wait'
|
|
11
|
+
require_relative 'common/log'
|
|
12
|
+
require_relative 'common/helper'
|
|
13
|
+
require_relative 'common/multi_touch'
|
|
14
|
+
require_relative 'common/touch_actions'
|
|
15
|
+
|
|
16
|
+
# core
|
|
17
|
+
require_relative 'core/core'
|
|
18
|
+
|
|
19
|
+
# ios
|
|
20
|
+
require_relative 'ios/ios'
|
|
21
|
+
|
|
22
|
+
# android
|
|
23
|
+
require_relative 'android/android'
|
|
24
|
+
|
|
25
|
+
module Appium
|
|
26
|
+
class << self
|
|
27
|
+
# Load arbitrary text ([toml format](https://github.com/toml-lang/toml))
|
|
28
|
+
# The toml is parsed by https://github.com/fbernier/tomlrb .
|
|
29
|
+
#
|
|
30
|
+
# ```
|
|
31
|
+
# [caps]
|
|
32
|
+
# app = "path/to/app"
|
|
33
|
+
#
|
|
34
|
+
# [appium_lib]
|
|
35
|
+
# port = 8080
|
|
36
|
+
# ```
|
|
37
|
+
#
|
|
38
|
+
# :app is expanded
|
|
39
|
+
# :require is expanded
|
|
40
|
+
# all keys are converted to symbols
|
|
41
|
+
#
|
|
42
|
+
# @param opts [Hash] file: '/path/to/appium.txt', verbose: true
|
|
43
|
+
# @return [hash] the symbolized hash with updated :app and :require keys
|
|
44
|
+
def load_settings(opts = {})
|
|
45
|
+
raise 'opts must be a hash' unless opts.is_a? Hash
|
|
46
|
+
raise 'opts must not be empty' if opts.empty?
|
|
47
|
+
|
|
48
|
+
toml = opts[:file]
|
|
49
|
+
raise 'Must pass a capability file which has [caps] and [appium_lib]' unless toml
|
|
50
|
+
verbose = opts.fetch :verbose, false
|
|
51
|
+
|
|
52
|
+
Appium::Logger.info "appium settings path: #{toml}" if verbose
|
|
53
|
+
|
|
54
|
+
toml_exists = File.exist? toml
|
|
55
|
+
Appium::Logger.info "Exists? #{toml_exists}" if verbose
|
|
56
|
+
|
|
57
|
+
raise "toml doesn't exist #{toml}" unless toml_exists
|
|
58
|
+
require 'tomlrb'
|
|
59
|
+
Appium::Logger.info "Loading #{toml}" if verbose
|
|
60
|
+
|
|
61
|
+
data = Tomlrb.load_file(toml, symbolize_keys: true)
|
|
62
|
+
if verbose
|
|
63
|
+
Appium::Logger.ap_info data unless data.empty?
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
if data && data[:caps] && data[:caps][:app] && !data[:caps][:app].empty?
|
|
67
|
+
data[:caps][:app] = Appium::Driver.absolute_app_path data
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
if data && data[:appium_lib] && data[:appium_lib][:require]
|
|
71
|
+
parent_dir = File.dirname toml
|
|
72
|
+
data[:appium_lib][:require] = expand_required_files(parent_dir, data[:appium_lib][:require])
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
data
|
|
76
|
+
end
|
|
77
|
+
alias load_appium_txt load_settings
|
|
78
|
+
|
|
79
|
+
# @param [String] base_dir parent directory of loaded appium.txt (toml)
|
|
80
|
+
# @param [String] file_paths
|
|
81
|
+
# @return [Array] list of require files as an array, nil if require doesn't exist
|
|
82
|
+
def expand_required_files(base_dir, file_paths)
|
|
83
|
+
# ensure files are absolute
|
|
84
|
+
Array(file_paths).map! do |f|
|
|
85
|
+
file = File.exist?(f) ? f : File.join(base_dir, f)
|
|
86
|
+
file = File.expand_path file
|
|
87
|
+
|
|
88
|
+
File.exist?(file) ? file : nil
|
|
89
|
+
end
|
|
90
|
+
file_paths.compact! # remove nils
|
|
91
|
+
|
|
92
|
+
files = []
|
|
93
|
+
|
|
94
|
+
# now expand dirs
|
|
95
|
+
file_paths.each do |item|
|
|
96
|
+
unless File.directory? item
|
|
97
|
+
# save file
|
|
98
|
+
files << item
|
|
99
|
+
next # only look inside folders
|
|
100
|
+
end
|
|
101
|
+
Dir.glob(File.expand_path(File.join(item, '**', '*.rb'))) do |f|
|
|
102
|
+
# do not add folders to the file list
|
|
103
|
+
files << File.expand_path(f) unless File.directory? f
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
files
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# This method is intended to work with page objects that share
|
|
111
|
+
# a common module. For example, Page::HomePage, Page::SignIn
|
|
112
|
+
# those could be promoted on with Appium.promote_singleton_appium_methods Page
|
|
113
|
+
#
|
|
114
|
+
# If you are promoting on an individual class then you should use
|
|
115
|
+
# Appium.promote_appium_methods instead. The singleton method is intended
|
|
116
|
+
# only for the shared module use case.
|
|
117
|
+
#
|
|
118
|
+
# if modules is a module instead of an array, then the constants of
|
|
119
|
+
# that module are promoted on.
|
|
120
|
+
# otherwise, the array of modules will be used as the promotion target.
|
|
121
|
+
def promote_singleton_appium_methods(modules, driver = $driver)
|
|
122
|
+
raise 'Global $driver is nil' if driver.nil?
|
|
123
|
+
|
|
124
|
+
target_modules = []
|
|
125
|
+
|
|
126
|
+
if modules.is_a? Module
|
|
127
|
+
modules.constants.each do |sub_module|
|
|
128
|
+
target_modules << modules.const_get(sub_module)
|
|
129
|
+
end
|
|
130
|
+
else
|
|
131
|
+
raise 'modules must be a module or an array' unless modules.is_a? Array
|
|
132
|
+
target_modules = modules
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
target_modules.each do |const|
|
|
136
|
+
# noinspection RubyResolve
|
|
137
|
+
# rubocop:disable Style/MultilineIfModifier
|
|
138
|
+
driver.public_methods(false).each do |m|
|
|
139
|
+
const.send(:define_singleton_method, m) do |*args, &block|
|
|
140
|
+
begin
|
|
141
|
+
super(*args, &block) # promote.rb
|
|
142
|
+
rescue NoMethodError, ArgumentError
|
|
143
|
+
driver.send m, *args, &block if driver.respond_to?(m)
|
|
144
|
+
end
|
|
145
|
+
# override unless there's an existing method with matching arity
|
|
146
|
+
end unless const.respond_to?(m) && const.method(m).arity == driver.method(m).arity
|
|
147
|
+
end
|
|
148
|
+
# rubocop:enable Style/MultilineIfModifier
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
##
|
|
153
|
+
# Promote appium methods to class instance methods
|
|
154
|
+
#
|
|
155
|
+
# @param class_array [Array<Class>] An array of classes
|
|
156
|
+
#
|
|
157
|
+
# To promote methods to all classes:
|
|
158
|
+
#
|
|
159
|
+
# ```ruby
|
|
160
|
+
# Appium.promote_appium_methods Object
|
|
161
|
+
# ```
|
|
162
|
+
#
|
|
163
|
+
# It's better to promote on specific classes instead of Object
|
|
164
|
+
#
|
|
165
|
+
# ```ruby
|
|
166
|
+
# # promote on rspec
|
|
167
|
+
# Appium.promote_appium_methods RSpec::Core::ExampleGroup
|
|
168
|
+
# ```
|
|
169
|
+
#
|
|
170
|
+
# ```ruby
|
|
171
|
+
# # promote on minispec
|
|
172
|
+
# Appium.promote_appium_methods Minitest::Spec
|
|
173
|
+
# ```
|
|
174
|
+
def promote_appium_methods(class_array, driver = $driver)
|
|
175
|
+
raise 'Driver is nil' if driver.nil?
|
|
176
|
+
# Wrap single class into an array
|
|
177
|
+
class_array = [class_array] unless class_array.class == Array
|
|
178
|
+
# Promote Appium driver methods to class instance methods.
|
|
179
|
+
class_array.each do |klass|
|
|
180
|
+
driver.public_methods(false).each do |m|
|
|
181
|
+
klass.class_eval do
|
|
182
|
+
define_method m do |*args, &block|
|
|
183
|
+
begin
|
|
184
|
+
# Prefer existing method.
|
|
185
|
+
# super will invoke method missing on driver
|
|
186
|
+
super(*args, &block)
|
|
187
|
+
|
|
188
|
+
# minitest also defines a name method,
|
|
189
|
+
# so rescue argument error
|
|
190
|
+
# and call the name method on $driver
|
|
191
|
+
rescue NoMethodError, ArgumentError
|
|
192
|
+
driver.send m, *args, &block if driver.respond_to?(m)
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
nil # return nil
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|
|
@@ -1,14 +1,7 @@
|
|
|
1
|
-
require 'selenium/webdriver/common/error'
|
|
2
|
-
|
|
3
1
|
# Generic helper methods not specific
|
|
4
2
|
# to a particular tag name
|
|
5
3
|
module Appium
|
|
6
4
|
module Common
|
|
7
|
-
# json and ap are required for the source method.
|
|
8
|
-
require 'json'
|
|
9
|
-
require 'ap' # awesome print
|
|
10
|
-
require 'timeout' # for wait
|
|
11
|
-
|
|
12
5
|
# iOS .name returns the accessibility attribute if it's set. if not set, the string value is used.
|
|
13
6
|
# Android .name returns the accessibility attribute and nothing if it's not set.
|
|
14
7
|
#
|
|
@@ -42,7 +35,7 @@ module Appium
|
|
|
42
35
|
# @param xpath_str [String] the XPath string
|
|
43
36
|
# @return [Element]
|
|
44
37
|
def xpath(xpath_str)
|
|
45
|
-
find_element :xpath, xpath_str
|
|
38
|
+
@driver.find_element :xpath, xpath_str
|
|
46
39
|
end
|
|
47
40
|
|
|
48
41
|
# Returns all elements that match the provided xpath.
|
|
@@ -50,18 +43,12 @@ module Appium
|
|
|
50
43
|
# @param xpath_str [String] the XPath string
|
|
51
44
|
# @return [Array<Element>]
|
|
52
45
|
def xpaths(xpath_str)
|
|
53
|
-
find_elements :xpath, xpath_str
|
|
46
|
+
@driver.find_elements :xpath, xpath_str
|
|
54
47
|
end
|
|
55
48
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
Nokogiri::HTML(source) { |cfg| cfg.options = opts }
|
|
60
|
-
else
|
|
61
|
-
Nokogiri::XML(source) { |cfg| cfg.options = opts }
|
|
62
|
-
end
|
|
63
|
-
puts doc.to_xml indent: 2
|
|
64
|
-
end
|
|
49
|
+
# json and ap are required for the source method.
|
|
50
|
+
require 'json'
|
|
51
|
+
require 'ap' # awesome print
|
|
65
52
|
|
|
66
53
|
# @private
|
|
67
54
|
# http://nokogiri.org/Nokogiri/XML/SAX.html
|
|
@@ -219,5 +206,16 @@ module Appium
|
|
|
219
206
|
error_message = 'An element could not be located on the page using the given search parameters.'
|
|
220
207
|
raise Selenium::WebDriver::Error::NoSuchElementError, error_message
|
|
221
208
|
end
|
|
222
|
-
|
|
223
|
-
|
|
209
|
+
|
|
210
|
+
# @private
|
|
211
|
+
def _print_source(source)
|
|
212
|
+
opts = Nokogiri::XML::ParseOptions::NOBLANKS | Nokogiri::XML::ParseOptions::NONET
|
|
213
|
+
doc = if source.start_with? '<html'
|
|
214
|
+
Nokogiri::HTML(source) { |cfg| cfg.options = opts }
|
|
215
|
+
else
|
|
216
|
+
Nokogiri::XML(source) { |cfg| cfg.options = opts }
|
|
217
|
+
end
|
|
218
|
+
puts doc.to_xml indent: 2
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Appium
|
|
2
|
+
module Common
|
|
3
|
+
# @param [String|Hash] type You can get particular type's logs.
|
|
4
|
+
# @return [[Selenium::WebDriver::LogEntry]] A list of logs data.
|
|
5
|
+
#
|
|
6
|
+
# @example
|
|
7
|
+
# @driver.get_log("syslog") #=> [[Selenium::WebDriver::LogEntry]]
|
|
8
|
+
# @driver.get_log(:syslog) #=> [[Selenium::WebDriver::LogEntry]]
|
|
9
|
+
#
|
|
10
|
+
def get_log(type)
|
|
11
|
+
Appium::Core::Logs.new(@driver.manage.logs).get type
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Get a list of available log types
|
|
15
|
+
#
|
|
16
|
+
# @return [[String]] A list of available log types.
|
|
17
|
+
# @example
|
|
18
|
+
# @driver.get_available_log_types #=> [:syslog, :crashlog, :performance]
|
|
19
|
+
#
|
|
20
|
+
def get_available_log_types
|
|
21
|
+
Appium::Core::Logs.new(@driver.manage.logs).available_types
|
|
22
|
+
end
|
|
23
|
+
end # module Common
|
|
24
|
+
end # module Appium
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
module Appium
|
|
2
|
+
# MultiTouch actions allow for multiple touches to happen at the same time,
|
|
3
|
+
# for instance, to simulate multiple finger swipes.
|
|
4
|
+
#
|
|
5
|
+
# Create a series of touch actions by themselves (without a `prepare()`), then
|
|
6
|
+
# add to a new MultiTouch action. When ready, call `prepare()` and all
|
|
7
|
+
# actions will be executed simultaneously.
|
|
8
|
+
#
|
|
9
|
+
# ```ruby
|
|
10
|
+
# action_1 = TouchAction.new.press(x: 45, y: 100).wait(5).release
|
|
11
|
+
# action_2 = TouchAction.new.tap(element: el, x: 50, y:5, count: 3)
|
|
12
|
+
#
|
|
13
|
+
# multi_touch_action = MultiTouch.new
|
|
14
|
+
# multi_touch_action.add action_1
|
|
15
|
+
# multi_touch_action.add action_2
|
|
16
|
+
# multi_touch_action.perform
|
|
17
|
+
# ```
|
|
18
|
+
#
|
|
19
|
+
# ```
|
|
20
|
+
# # with an arbitrary driver
|
|
21
|
+
# driver = Appium::Driver.new(opts, false).start_driver
|
|
22
|
+
# multi_touch_action = MultiTouch.new(driver)
|
|
23
|
+
# multi_touch_action.add action_1
|
|
24
|
+
# multi_touch_action.add action_2
|
|
25
|
+
# multi_touch_action.perform
|
|
26
|
+
# ```
|
|
27
|
+
|
|
28
|
+
class MultiTouch < ::Appium::Core::MultiTouch
|
|
29
|
+
class << self
|
|
30
|
+
# Convenience method for pinching the screen.
|
|
31
|
+
# Places two fingers at the edges of the screen and brings them together.
|
|
32
|
+
# @param percentage (int) The percent size by which to shrink the screen when pinched.
|
|
33
|
+
# @param auto_perform (boolean) Whether to perform the action immediately (default true)
|
|
34
|
+
# @param driver (Driver) Set a driver to conduct the action. DEfault is global driver($driver)
|
|
35
|
+
#
|
|
36
|
+
# ```ruby
|
|
37
|
+
# pinch 75 #=> Pinch the screen from the top right and bottom left corners
|
|
38
|
+
# ```
|
|
39
|
+
#
|
|
40
|
+
# Without auto_perform
|
|
41
|
+
#
|
|
42
|
+
# ```ruby
|
|
43
|
+
# action = pinch 75, false #=> Pinch the screen from the top right and bottom left corners
|
|
44
|
+
# action.perform #=> to 25% of its size.
|
|
45
|
+
# ```
|
|
46
|
+
#
|
|
47
|
+
# With driver
|
|
48
|
+
#
|
|
49
|
+
# ```ruby
|
|
50
|
+
# driver = Appium::Driver.new(opts, false).start_driver
|
|
51
|
+
# pinch 75, true, driver #=> Pinch the screen from the top right and bottom left corners
|
|
52
|
+
# ```
|
|
53
|
+
def pinch(percentage = 25, auto_perform = true, driver = $driver)
|
|
54
|
+
::Appium::Core::MultiTouch.pinch percentage: percentage, auto_perform: auto_perform, driver: driver
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Convenience method for zooming the screen.
|
|
58
|
+
# Places two fingers at the edges of the screen and brings them together.
|
|
59
|
+
# @param percentage (int) The percent size by which to shrink the screen when pinched.
|
|
60
|
+
# @param auto_perform (boolean) Whether to perform the action immediately (default true)
|
|
61
|
+
# @param driver (Driver) Set a driver to conduct the action. DEfault is global driver($driver)
|
|
62
|
+
#
|
|
63
|
+
# ```ruby
|
|
64
|
+
# action = zoom 200 #=> Zoom in the screen from the center until it doubles in size.
|
|
65
|
+
# ```
|
|
66
|
+
#
|
|
67
|
+
# Without auto_perform
|
|
68
|
+
#
|
|
69
|
+
# ```ruby
|
|
70
|
+
# action = zoom 200, false #=> Zoom in the screen from the center until it doubles in size.
|
|
71
|
+
# action.perform #=> to 25% of its size.
|
|
72
|
+
# ```
|
|
73
|
+
#
|
|
74
|
+
# With driver
|
|
75
|
+
#
|
|
76
|
+
# ```ruby
|
|
77
|
+
# driver = Appium::Driver.new(opts, false).start_driver
|
|
78
|
+
# pinch 200, true, driver #=> Zoom in the screen from the center until it doubles in size.
|
|
79
|
+
# ```
|
|
80
|
+
def zoom(percentage = 200, auto_perform = true, driver = $driver)
|
|
81
|
+
::Appium::Core::MultiTouch.zoom percentage: percentage, auto_perform: auto_perform, driver: driver
|
|
82
|
+
end
|
|
83
|
+
end # self
|
|
84
|
+
|
|
85
|
+
def initialize(driver = $driver)
|
|
86
|
+
super driver
|
|
87
|
+
end
|
|
88
|
+
end # class MultiTouch
|
|
89
|
+
end # module Appium
|