appium_lib 9.7.1 → 9.7.2
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 +12 -0
- data/docs/android_docs.md +199 -240
- data/docs/ios_docs.md +251 -292
- data/lib/appium_lib/appium.rb +20 -14
- data/lib/appium_lib/common/helper.rb +34 -5
- data/lib/appium_lib/common/http_client.rb +1 -0
- data/lib/appium_lib/common/log.rb +3 -0
- data/lib/appium_lib/common/multi_touch.rb +38 -39
- data/lib/appium_lib/common/touch_actions.rb +20 -17
- data/lib/appium_lib/core/common/error.rb +5 -0
- data/lib/appium_lib/core/core.rb +28 -0
- data/lib/appium_lib/core/driver.rb +99 -32
- data/lib/appium_lib/core/ios/uiautomation/bridge.rb +2 -1
- data/lib/appium_lib/core/ios/uiautomation/patch.rb +2 -2
- data/lib/appium_lib/driver.rb +78 -92
- data/lib/appium_lib/ios/common/helper.rb +1 -0
- data/lib/appium_lib/sauce_labs.rb +42 -1
- data/lib/appium_lib/version.rb +2 -2
- data/release_notes.md +6 -0
- metadata +2 -2
data/lib/appium_lib/appium.rb
CHANGED
@@ -75,6 +75,7 @@ module Appium
|
|
75
75
|
|
76
76
|
data
|
77
77
|
end
|
78
|
+
# @see load_settings
|
78
79
|
alias load_appium_txt load_settings
|
79
80
|
|
80
81
|
# @param [String] base_dir parent directory of loaded appium.txt (toml)
|
@@ -119,6 +120,9 @@ module Appium
|
|
119
120
|
# if modules is a module instead of an array, then the constants of
|
120
121
|
# that module are promoted on.
|
121
122
|
# otherwise, the array of modules will be used as the promotion target.
|
123
|
+
#
|
124
|
+
# @param [Array<Module>] modules An array of modules
|
125
|
+
# @param [Driver] driver A driver to extend for
|
122
126
|
def promote_singleton_appium_methods(modules, driver = $driver)
|
123
127
|
raise 'Global $driver is nil' if driver.nil?
|
124
128
|
|
@@ -153,25 +157,27 @@ module Appium
|
|
153
157
|
##
|
154
158
|
# Promote appium methods to class instance methods
|
155
159
|
#
|
156
|
-
# @param
|
160
|
+
# @param [Array<Class>] class_array An array of classes
|
161
|
+
# @param [Driver] driver A driver to extend for
|
157
162
|
#
|
158
163
|
# To promote methods to all classes:
|
159
164
|
#
|
160
|
-
#
|
161
|
-
#
|
162
|
-
#
|
165
|
+
# @example
|
166
|
+
#
|
167
|
+
# Appium.promote_appium_methods Object
|
163
168
|
#
|
164
169
|
# It's better to promote on specific classes instead of Object
|
165
170
|
#
|
166
|
-
#
|
167
|
-
#
|
168
|
-
#
|
169
|
-
#
|
171
|
+
# @example
|
172
|
+
#
|
173
|
+
# # promote on rspec
|
174
|
+
# Appium.promote_appium_methods RSpec::Core::ExampleGroup
|
175
|
+
#
|
176
|
+
# @example
|
177
|
+
#
|
178
|
+
# # promote on minispec
|
179
|
+
# Appium.promote_appium_methods Minitest::Spec
|
170
180
|
#
|
171
|
-
# ```ruby
|
172
|
-
# # promote on minispec
|
173
|
-
# Appium.promote_appium_methods Minitest::Spec
|
174
|
-
# ```
|
175
181
|
def promote_appium_methods(class_array, driver = $driver)
|
176
182
|
raise 'Driver is nil' if driver.nil?
|
177
183
|
# Wrap single class into an array
|
@@ -198,5 +204,5 @@ module Appium
|
|
198
204
|
end
|
199
205
|
nil # return nil
|
200
206
|
end
|
201
|
-
end
|
202
|
-
end
|
207
|
+
end # class << self
|
208
|
+
end # module Appium
|
@@ -1,5 +1,4 @@
|
|
1
|
-
# Generic helper methods not specific
|
2
|
-
# to a particular tag name
|
1
|
+
# Generic helper methods not specific to a particular tag name
|
3
2
|
module Appium
|
4
3
|
module Common
|
5
4
|
# iOS .name returns the accessibility attribute if it's set. if not set, the string value is used.
|
@@ -26,6 +25,12 @@ module Appium
|
|
26
25
|
end
|
27
26
|
|
28
27
|
# For Sauce Labs reporting. Returns the current session id.
|
28
|
+
# @return [String]
|
29
|
+
#
|
30
|
+
# @example
|
31
|
+
#
|
32
|
+
# @driver.session_id #=> "some-session-ids"
|
33
|
+
#
|
29
34
|
def session_id
|
30
35
|
@driver.session_id
|
31
36
|
end
|
@@ -81,6 +86,14 @@ module Appium
|
|
81
86
|
end # class CountElements
|
82
87
|
|
83
88
|
# Returns a string of class counts of visible elements.
|
89
|
+
# @return [String]
|
90
|
+
#
|
91
|
+
# @example
|
92
|
+
#
|
93
|
+
# get_page_class #=> "24x XCUIElementTypeStaticText\n12x XCUIElementTypeCell\n8x XCUIElementTypeOther\n
|
94
|
+
# # 2x XCUIElementTypeWindow\n1x XCUIElementTypeStatusBar\n1x XCUIElementTypeTable\n1
|
95
|
+
# # x XCUIElementTypeNavigationBar\n1x XCUIElementTypeApplication"
|
96
|
+
#
|
84
97
|
def get_page_class
|
85
98
|
parser = @count_elements_parser ||= Nokogiri::XML::SAX::Parser.new(CountElements.new)
|
86
99
|
|
@@ -92,6 +105,20 @@ module Appium
|
|
92
105
|
|
93
106
|
# Count all classes on screen and print to stdout.
|
94
107
|
# Useful for appium_console.
|
108
|
+
# @return [nil]
|
109
|
+
#
|
110
|
+
# @example
|
111
|
+
#
|
112
|
+
# page_class
|
113
|
+
# # 24x XCUIElementTypeStaticText
|
114
|
+
# # 12x XCUIElementTypeCell
|
115
|
+
# # 8x XCUIElementTypeOther
|
116
|
+
# # 2x XCUIElementTypeWindow
|
117
|
+
# # 1x XCUIElementTypeStatusBar
|
118
|
+
# # 1x XCUIElementTypeTable
|
119
|
+
# # 1x XCUIElementTypeNavigationBar
|
120
|
+
# # 1x XCUIElementTypeApplication
|
121
|
+
#
|
95
122
|
def page_class
|
96
123
|
puts get_page_class
|
97
124
|
nil
|
@@ -99,9 +126,10 @@ module Appium
|
|
99
126
|
|
100
127
|
# Converts pixel values to window relative values
|
101
128
|
#
|
102
|
-
#
|
103
|
-
#
|
104
|
-
#
|
129
|
+
# @example
|
130
|
+
#
|
131
|
+
# px_to_window_rel x: 50, y: 150 #=> #<OpenStruct x="50.0 / 375.0", y="150.0 / 667.0">
|
132
|
+
#
|
105
133
|
def px_to_window_rel(opts = {}, driver = $driver)
|
106
134
|
w = driver.window_size
|
107
135
|
x = opts.fetch :x, 0
|
@@ -142,6 +170,7 @@ module Appium
|
|
142
170
|
@strings_xml[id]
|
143
171
|
end
|
144
172
|
|
173
|
+
# @private
|
145
174
|
class HTMLElements < Nokogiri::XML::SAX::Document
|
146
175
|
attr_reader :filter
|
147
176
|
|
@@ -4,6 +4,7 @@ require_relative '../version'
|
|
4
4
|
module Appium
|
5
5
|
module Http
|
6
6
|
class Default < ::Appium::Core::Base::Http::Default
|
7
|
+
# Default HTTP client inherit Appium::Core::Base::Http::Default, but has different DEFAULT_HEADERS
|
7
8
|
DEFAULT_HEADERS = { 'Accept' => CONTENT_TYPE, 'User-Agent' => "appium/ruby_lib/#{::Appium::VERSION}" }.freeze
|
8
9
|
end
|
9
10
|
end
|
@@ -4,6 +4,7 @@ module Appium
|
|
4
4
|
# @return [[Selenium::WebDriver::LogEntry]] A list of logs data.
|
5
5
|
#
|
6
6
|
# @example
|
7
|
+
#
|
7
8
|
# @driver.get_log("syslog") #=> [[Selenium::WebDriver::LogEntry]]
|
8
9
|
# @driver.get_log(:syslog) #=> [[Selenium::WebDriver::LogEntry]]
|
9
10
|
#
|
@@ -14,7 +15,9 @@ module Appium
|
|
14
15
|
# Get a list of available log types
|
15
16
|
#
|
16
17
|
# @return [[String]] A list of available log types.
|
18
|
+
#
|
17
19
|
# @example
|
20
|
+
#
|
18
21
|
# @driver.get_available_log_types #=> [:syslog, :crashlog, :performance]
|
19
22
|
#
|
20
23
|
def get_available_log_types
|
@@ -6,25 +6,23 @@ module Appium
|
|
6
6
|
# add to a new MultiTouch action. When ready, call `prepare()` and all
|
7
7
|
# actions will be executed simultaneously.
|
8
8
|
#
|
9
|
-
#
|
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)
|
9
|
+
# @example
|
12
10
|
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
11
|
+
# action_1 = TouchAction.new.press(x: 45, y: 100).wait(5).release
|
12
|
+
# action_2 = TouchAction.new.tap(element: el, x: 50, y:5, count: 3)
|
13
|
+
#
|
14
|
+
# multi_touch_action = MultiTouch.new
|
15
|
+
# multi_touch_action.add action_1
|
16
|
+
# multi_touch_action.add action_2
|
17
|
+
# multi_touch_action.perform
|
18
|
+
#
|
19
|
+
# # with an arbitrary driver
|
20
|
+
# driver = Appium::Driver.new(opts, false).start_driver
|
21
|
+
# multi_touch_action = MultiTouch.new(driver)
|
22
|
+
# multi_touch_action.add action_1
|
23
|
+
# multi_touch_action.add action_2
|
24
|
+
# multi_touch_action.perform
|
18
25
|
#
|
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
26
|
class MultiTouch < ::Appium::Core::MultiTouch
|
29
27
|
class << self
|
30
28
|
# Convenience method for pinching the screen.
|
@@ -33,23 +31,23 @@ module Appium
|
|
33
31
|
# @param auto_perform (boolean) Whether to perform the action immediately (default true)
|
34
32
|
# @param driver (Driver) Set a driver to conduct the action. DEfault is global driver($driver)
|
35
33
|
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
34
|
+
# @example
|
35
|
+
#
|
36
|
+
# pinch 75 #=> Pinch the screen from the top right and bottom left corners
|
39
37
|
#
|
40
38
|
# Without auto_perform
|
41
39
|
#
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
40
|
+
# @example
|
41
|
+
#
|
42
|
+
# action = pinch 75, false #=> Pinch the screen from the top right and bottom left corners
|
43
|
+
# action.perform #=> to 25% of its size.
|
46
44
|
#
|
47
45
|
# With driver
|
48
46
|
#
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
47
|
+
# @example
|
48
|
+
# driver = Appium::Driver.new(opts, false).start_driver
|
49
|
+
# pinch 75, true, driver #=> Pinch the screen from the top right and bottom left corners
|
50
|
+
#
|
53
51
|
def pinch(percentage = 25, auto_perform = true, driver = $driver)
|
54
52
|
::Appium::Core::MultiTouch.pinch percentage: percentage, auto_perform: auto_perform, driver: driver
|
55
53
|
end
|
@@ -60,23 +58,24 @@ module Appium
|
|
60
58
|
# @param auto_perform (boolean) Whether to perform the action immediately (default true)
|
61
59
|
# @param driver (Driver) Set a driver to conduct the action. DEfault is global driver($driver)
|
62
60
|
#
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
61
|
+
# @example
|
62
|
+
#
|
63
|
+
# action = zoom 200 #=> Zoom in the screen from the center until it doubles in size.
|
66
64
|
#
|
67
65
|
# Without auto_perform
|
68
66
|
#
|
69
|
-
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
67
|
+
# @example
|
68
|
+
#
|
69
|
+
# action = zoom 200, false #=> Zoom in the screen from the center until it doubles in size.
|
70
|
+
# action.perform #=> to 25% of its size.
|
73
71
|
#
|
74
72
|
# With driver
|
75
73
|
#
|
76
|
-
#
|
77
|
-
#
|
78
|
-
#
|
79
|
-
#
|
74
|
+
# @example
|
75
|
+
#
|
76
|
+
# driver = Appium::Driver.new(opts, false).start_driver
|
77
|
+
# pinch 200, true, driver #=> Zoom in the screen from the center until it doubles in size.
|
78
|
+
#
|
80
79
|
def zoom(percentage = 200, auto_perform = true, driver = $driver)
|
81
80
|
::Appium::Core::MultiTouch.zoom percentage: percentage, auto_perform: auto_perform, driver: driver
|
82
81
|
end
|
@@ -4,28 +4,31 @@ module Appium
|
|
4
4
|
#
|
5
5
|
# Each method returns the object itself, so calls can be chained.
|
6
6
|
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
7
|
+
# @example
|
8
|
+
#
|
9
|
+
# action = TouchAction.new.press(x: 45, y: 100).wait(5).release
|
10
|
+
# action.perform
|
11
|
+
# action = TouchAction.new.swipe(....)
|
12
|
+
# action.perform
|
13
13
|
#
|
14
14
|
# Or each methods can call without `TouchAction.new` as the following.
|
15
15
|
# In this case, `perform` is called automatically.
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
16
|
+
#
|
17
|
+
# @example
|
18
|
+
#
|
19
|
+
# # called `swipe(...).perform` in this method.
|
20
|
+
# swipe(start_x: 75, start_y: 500, offset_x: 75, offset_y: 20, duration: 500)
|
20
21
|
#
|
21
22
|
# If you'd like to perform the chain with an arbitrary driver:
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
23
|
+
#
|
24
|
+
# @example
|
25
|
+
#
|
26
|
+
# driver = Appium::Driver.new(opts, false).start_driver
|
27
|
+
# action = TouchAction.new.press(x: 45, y: 100).wait(5).release
|
28
|
+
# action.perform(@driver)
|
29
|
+
# action = TouchAction.new.swipe(....)
|
30
|
+
# action.perform(@driver)
|
31
|
+
#
|
29
32
|
class TouchAction < ::Appium::Core::TouchAction
|
30
33
|
COMPLEX_ACTIONS = ::Appium::Core::TouchAction::COMPLEX_ACTIONS
|
31
34
|
|
@@ -3,6 +3,11 @@ module Appium
|
|
3
3
|
module Error
|
4
4
|
class CoreError < StandardError; end
|
5
5
|
|
6
|
+
# Capability related errors
|
7
|
+
class NoCapabilityError < CoreError; end
|
8
|
+
class CapabilityStructureError < CoreError; end
|
9
|
+
|
10
|
+
# Appium related errors
|
6
11
|
class NotSupportedAppiumServer < CoreError; end
|
7
12
|
class NoSuchElementError < CoreError; end
|
8
13
|
|
data/lib/appium_lib/core/core.rb
CHANGED
@@ -31,6 +31,34 @@ module Appium
|
|
31
31
|
end
|
32
32
|
|
33
33
|
module Core
|
34
|
+
# Creates a new global driver and extend particular methods to `target`
|
35
|
+
# @param [Class] target Extend particular methods to this target.
|
36
|
+
# @param [Hash] opts A options include capabilities for the Appium Server and for the client.
|
37
|
+
#
|
38
|
+
# @example
|
39
|
+
#
|
40
|
+
# require 'rubygems'
|
41
|
+
# require 'appium_lib'
|
42
|
+
#
|
43
|
+
# # Start iOS driver
|
44
|
+
# opts = {
|
45
|
+
# caps: {
|
46
|
+
# platformName: :ios,
|
47
|
+
# app: '/path/to/MyiOS.app'
|
48
|
+
# },
|
49
|
+
# appium_lib: {
|
50
|
+
# server_url: "http://custom-host:8080/wd/hub.com",
|
51
|
+
# export_session: false,
|
52
|
+
# port: 8080,
|
53
|
+
# wait: 0,
|
54
|
+
# wait_timeout: 20,
|
55
|
+
# wait_interval: 0.3,
|
56
|
+
# listener: nil,
|
57
|
+
# }
|
58
|
+
# }
|
59
|
+
# @core_driver = Appium::Core.for(self, opts) # create a core driver with `opts` and extend methods into `self`
|
60
|
+
# @core_driver.start_driver(server_url: server_url, http_client_ops: http_client_ops) # start driver
|
61
|
+
#
|
34
62
|
def self.for(*args)
|
35
63
|
Core::Driver.for(*args)
|
36
64
|
end
|
@@ -2,36 +2,53 @@ module Appium
|
|
2
2
|
module Core
|
3
3
|
class Driver
|
4
4
|
# Selenium webdriver capabilities
|
5
|
+
# @return [Core::Base::Capabilities]
|
5
6
|
attr_reader :caps
|
6
|
-
|
7
|
+
|
8
|
+
# Return http client called in start_driver()
|
9
|
+
# @return [Appium::Core::Base::Http::Default] the http client
|
10
|
+
attr_reader :http_client
|
11
|
+
|
12
|
+
# Device type to request from the appium server
|
13
|
+
attr_reader :device
|
14
|
+
|
15
|
+
# Automation name sent to appium server or received from server
|
16
|
+
# If automation_name is nil, it is not set both client side and server side.
|
17
|
+
# @return [Hash]
|
18
|
+
attr_reader :automation_name
|
19
|
+
|
20
|
+
# Custom URL for the selenium server. If set this attribute, ruby_lib try to handshake to the custom url.
|
21
|
+
# @return [String]
|
7
22
|
attr_reader :custom_url
|
23
|
+
|
8
24
|
# Export session id to textfile in /tmp for 3rd party tools
|
25
|
+
# @return [Boolean]
|
9
26
|
attr_reader :export_session
|
27
|
+
|
10
28
|
# Default wait time for elements to appear
|
11
29
|
# Returns the default client side wait.
|
12
30
|
# This value is independent of what the server is using
|
31
|
+
# Provide Appium::Drive like { appium_lib: { wait: 20 } }
|
13
32
|
# @return [Integer]
|
14
33
|
attr_reader :default_wait
|
34
|
+
|
15
35
|
# Appium's server port
|
36
|
+
# Provide Appium::Drive like { appium_lib: { port: 8080 } }
|
37
|
+
# @return [Integer]
|
16
38
|
attr_reader :port
|
17
|
-
|
18
|
-
attr_reader :device
|
19
|
-
# Automation name sent to appium server or received from server
|
20
|
-
# If automation_name is nil, it is not set both client side and server side.
|
21
|
-
attr_reader :automation_name
|
39
|
+
|
22
40
|
# Return a time wait timeout
|
23
41
|
# Wait time for ::Appium::Common.wait or ::Appium::Common.wait_true.
|
24
42
|
# Provide Appium::Drive like { appium_lib: { wait_timeout: 20 } }
|
25
43
|
# @return [Integer]
|
26
44
|
attr_reader :wait_timeout
|
45
|
+
|
27
46
|
# Return a time wait timeout
|
28
47
|
# Wait interval time for ::Appium::Common.wait or ::Appium::Common.wait_true.
|
29
48
|
# Provide Appium::Drive like { appium_lib: { wait_interval: 20 } }
|
30
49
|
# @return [Integer]
|
31
50
|
attr_reader :wait_interval
|
32
|
-
|
33
|
-
# @return [Appium::Core::Base::Http::Default] the http client
|
34
|
-
attr_reader :http_client
|
51
|
+
|
35
52
|
# instance of AbstractEventListener for logging support
|
36
53
|
attr_reader :listener
|
37
54
|
|
@@ -54,6 +71,8 @@ module Appium
|
|
54
71
|
# @private
|
55
72
|
def initialize(target, opts = {})
|
56
73
|
opts = Appium.symbolize_keys opts
|
74
|
+
validate_keys(opts)
|
75
|
+
|
57
76
|
@caps = get_caps(opts)
|
58
77
|
|
59
78
|
set_appium_lib_specific_values(get_appium_lib_opts(opts))
|
@@ -69,8 +88,14 @@ module Appium
|
|
69
88
|
# Creates a new global driver and quits the old one if it exists.
|
70
89
|
# You can customise http_client as the following
|
71
90
|
#
|
91
|
+
# @param [String] server_url Custom server url to send to requests. Default is "http://127.0.0.1:4723/wd/hub".
|
92
|
+
# @option http_client_ops [Hash] :http_client Custom HTTP Client
|
93
|
+
# @option http_client_ops [Hash] :open_timeout Custom open timeout for http client.
|
94
|
+
# @option http_client_ops [Hash] :read_timeout Custom read timeout for http client.
|
95
|
+
# @return [Selenium::WebDriver] the new global driver
|
96
|
+
#
|
72
97
|
# @example
|
73
|
-
#
|
98
|
+
#
|
74
99
|
# require 'rubygems'
|
75
100
|
# require 'appium_lib'
|
76
101
|
#
|
@@ -83,17 +108,20 @@ module Appium
|
|
83
108
|
# app: '/path/to/MyiOS.app'
|
84
109
|
# },
|
85
110
|
# appium_lib: {
|
86
|
-
#
|
111
|
+
# server_url: "http://custom-host:8080/wd/hub.com",
|
112
|
+
# export_session: false,
|
113
|
+
# port: 8080,
|
114
|
+
# wait: 0,
|
115
|
+
# wait_timeout: 20,
|
116
|
+
# wait_interval: 0.3,
|
117
|
+
# listener: nil,
|
87
118
|
# }
|
88
119
|
# }
|
89
|
-
# Appium::Driver.new(opts).start_driver
|
120
|
+
# @driver = Appium::Driver.new(opts).start_driver
|
90
121
|
#
|
91
|
-
|
92
|
-
# @option http_client_ops [Hash] :open_timeout Custom open timeout for http client.
|
93
|
-
# @option http_client_ops [Hash] :read_timeout Custom read timeout for http client.
|
94
|
-
# @return [Selenium::WebDriver] the new global driver
|
95
|
-
def start_driver(server_url:,
|
122
|
+
def start_driver(server_url: nil,
|
96
123
|
http_client_ops: { http_client: nil, open_timeout: 999_999, read_timeout: 999_999 })
|
124
|
+
server_url = server_url ? server_url : "http://127.0.0.1:#{@port}/wd/hub"
|
97
125
|
|
98
126
|
# open_timeout and read_timeout are explicit wait.
|
99
127
|
open_timeout = http_client_ops.delete(:open_timeout)
|
@@ -134,23 +162,24 @@ module Appium
|
|
134
162
|
end
|
135
163
|
|
136
164
|
# Returns the server's version info
|
165
|
+
# @return [Hash]
|
137
166
|
#
|
138
|
-
#
|
139
|
-
#
|
140
|
-
#
|
141
|
-
#
|
142
|
-
# "
|
167
|
+
# @example
|
168
|
+
#
|
169
|
+
# @driver.appium_server_version
|
170
|
+
# {
|
171
|
+
# "build" => {
|
172
|
+
# "version" => "0.18.1",
|
173
|
+
# "revision" => "d242ebcfd92046a974347ccc3a28f0e898595198"
|
174
|
+
# }
|
143
175
|
# }
|
144
|
-
# }
|
145
|
-
# ```
|
146
176
|
#
|
147
177
|
# Returns blank hash for Selenium Grid since `remote_status` gets 500 error
|
148
178
|
#
|
149
|
-
#
|
150
|
-
#
|
151
|
-
#
|
179
|
+
# @example
|
180
|
+
#
|
181
|
+
# @driver.appium_server_version #=> {}
|
152
182
|
#
|
153
|
-
# @return [Hash]
|
154
183
|
def appium_server_version
|
155
184
|
@driver.remote_status
|
156
185
|
rescue Selenium::WebDriver::Error::ServerError => e
|
@@ -161,6 +190,11 @@ module Appium
|
|
161
190
|
|
162
191
|
# Return the platform version as an array of integers
|
163
192
|
# @return [Array<Integer>]
|
193
|
+
#
|
194
|
+
# @example
|
195
|
+
#
|
196
|
+
# @driver.platform_version #=> [10.1.1]
|
197
|
+
#
|
164
198
|
def platform_version
|
165
199
|
p_version = @driver.capabilities['platformVersion']
|
166
200
|
p_version.split('.').map(&:to_i)
|
@@ -168,10 +202,13 @@ module Appium
|
|
168
202
|
|
169
203
|
# Takes a png screenshot and saves to the target path.
|
170
204
|
#
|
171
|
-
# Example: screenshot '/tmp/hi.png'
|
172
|
-
#
|
173
205
|
# @param png_save_path [String] the full path to save the png
|
174
206
|
# @return [nil]
|
207
|
+
#
|
208
|
+
# @example
|
209
|
+
#
|
210
|
+
# @driver.screenshot '/tmp/hi.png' #=> nil
|
211
|
+
#
|
175
212
|
def screenshot(png_save_path)
|
176
213
|
@driver.save_screenshot png_save_path
|
177
214
|
nil
|
@@ -212,6 +249,28 @@ module Appium
|
|
212
249
|
target
|
213
250
|
end
|
214
251
|
|
252
|
+
# @private
|
253
|
+
def validate_keys(opts)
|
254
|
+
flatten_ops = flatten_hash_keys(opts)
|
255
|
+
|
256
|
+
raise Error::NoCapabilityError unless opts.member?(:caps)
|
257
|
+
if !opts.member?(:appium_lib) && flatten_ops.member?(:appium_lib)
|
258
|
+
raise Error::CapabilityStructureError, 'Please check the value of appium_lib in the capability'
|
259
|
+
end
|
260
|
+
|
261
|
+
true
|
262
|
+
end
|
263
|
+
|
264
|
+
# @private
|
265
|
+
def flatten_hash_keys(hash, flatten_keys_result = [])
|
266
|
+
hash.each do |key, value|
|
267
|
+
flatten_keys_result << key
|
268
|
+
flatten_hash_keys(value, flatten_keys_result) if value.is_a?(Hash)
|
269
|
+
end
|
270
|
+
|
271
|
+
flatten_keys_result
|
272
|
+
end
|
273
|
+
|
215
274
|
# @private
|
216
275
|
def get_caps(opts)
|
217
276
|
Core::Base::Capabilities.create_capabilities(opts[:caps] || {})
|
@@ -269,6 +328,14 @@ module Appium
|
|
269
328
|
return unless @automation_name.nil?
|
270
329
|
@automation_name = @driver.capabilities['automationName']
|
271
330
|
end
|
272
|
-
|
273
|
-
|
331
|
+
|
332
|
+
# @private
|
333
|
+
def write_session_id(session_id)
|
334
|
+
File.open('/tmp/appium_lib_session', 'w') { |f| f.puts session_id }
|
335
|
+
rescue IOError => e
|
336
|
+
::Appium::Logger.warn e
|
337
|
+
nil
|
338
|
+
end
|
339
|
+
end # class Driver
|
340
|
+
end # module Core
|
274
341
|
end # module Appium
|