appium_lib 9.6.1 → 9.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -2
  3. data/CHANGELOG.md +43 -0
  4. data/Rakefile +1 -1
  5. data/appium_lib.gemspec +1 -1
  6. data/docs/android_docs.md +440 -1295
  7. data/docs/docs.md +10 -103
  8. data/docs/index_paths.md +2 -0
  9. data/docs/ios_docs.md +725 -1674
  10. data/docs/migration.md +17 -0
  11. data/lib/appium_lib.rb +1 -2
  12. data/lib/appium_lib/android/android.rb +20 -0
  13. data/lib/appium_lib/android/{helper.rb → common/helper.rb} +1 -1
  14. data/lib/appium_lib/android/uiautomator2.rb +5 -4
  15. data/lib/appium_lib/android/uiautomator2/bridge.rb +16 -0
  16. data/lib/appium_lib/appium.rb +201 -0
  17. data/lib/appium_lib/common/helper.rb +18 -20
  18. data/lib/appium_lib/common/log.rb +24 -0
  19. data/lib/appium_lib/common/multi_touch.rb +89 -0
  20. data/lib/appium_lib/common/touch_actions.rb +48 -0
  21. data/lib/appium_lib/common/wait.rb +10 -49
  22. data/lib/appium_lib/core/android.rb +4 -0
  23. data/lib/appium_lib/core/android/device.rb +142 -0
  24. data/lib/appium_lib/core/android/search_context.rb +17 -0
  25. data/lib/appium_lib/core/android/uiautomator1/bridge.rb +16 -0
  26. data/lib/appium_lib/core/android/uiautomator2/bridge.rb +16 -0
  27. data/lib/appium_lib/core/android_uiautomator2.rb +4 -0
  28. data/lib/appium_lib/core/common.rb +6 -0
  29. data/lib/appium_lib/core/common/base.rb +8 -0
  30. data/lib/appium_lib/core/common/base/bridge.rb +47 -0
  31. data/lib/appium_lib/core/common/base/capabilities.rb +16 -0
  32. data/lib/appium_lib/core/common/base/command.rb +10 -0
  33. data/lib/appium_lib/core/common/base/driver.rb +40 -0
  34. data/lib/appium_lib/core/common/base/http_default.rb +12 -0
  35. data/lib/appium_lib/core/common/base/search_context.rb +89 -0
  36. data/lib/appium_lib/core/common/base/wait.rb +56 -0
  37. data/lib/appium_lib/{common → core/common}/command.rb +20 -16
  38. data/lib/appium_lib/core/common/device.rb +470 -0
  39. data/lib/appium_lib/core/common/error.rb +13 -0
  40. data/lib/appium_lib/core/common/log.rb +30 -0
  41. data/lib/appium_lib/{logger.rb → core/common/logger.rb} +2 -0
  42. data/lib/appium_lib/core/core.rb +38 -0
  43. data/lib/appium_lib/core/device/multi_touch.rb +213 -0
  44. data/lib/appium_lib/core/device/touch_actions.rb +206 -0
  45. data/lib/appium_lib/core/driver.rb +274 -0
  46. data/lib/appium_lib/core/ios.rb +6 -0
  47. data/lib/appium_lib/core/ios/device.rb +44 -0
  48. data/lib/appium_lib/core/ios/search_context.rb +27 -0
  49. data/lib/appium_lib/core/ios/uiautomation/bridge.rb +17 -0
  50. data/lib/appium_lib/core/ios/uiautomation/patch.rb +20 -0
  51. data/lib/appium_lib/core/ios/xcuitest/bridge.rb +18 -0
  52. data/lib/appium_lib/{ios → core/ios}/xcuitest/device.rb +5 -5
  53. data/lib/appium_lib/{ios → core/ios}/xcuitest/search_context.rb +13 -9
  54. data/lib/appium_lib/core/ios_xcuitest.rb +7 -0
  55. data/lib/appium_lib/core/patch.rb +56 -0
  56. data/lib/appium_lib/driver.rb +174 -446
  57. data/lib/appium_lib/ios/{errors.rb → common/errors.rb} +0 -0
  58. data/lib/appium_lib/ios/{helper.rb → common/helper.rb} +9 -110
  59. data/lib/appium_lib/ios/ios.rb +20 -0
  60. data/lib/appium_lib/ios/xcuitest.rb +1 -3
  61. data/lib/appium_lib/ios/xcuitest/bridge.rb +19 -0
  62. data/lib/appium_lib/ios/xcuitest/command.rb +4 -1
  63. data/lib/appium_lib/ios/xcuitest/{gestures.rb → command/gestures.rb} +1 -1
  64. data/lib/appium_lib/ios/xcuitest/element.rb +1 -18
  65. data/lib/appium_lib/ios/xcuitest/helper.rb +0 -6
  66. data/lib/appium_lib/sauce_labs.rb +29 -0
  67. data/lib/appium_lib/version.rb +5 -0
  68. data/release_notes.md +8 -0
  69. metadata +50 -25
  70. data/lib/appium_lib/android/client_xpath.rb +0 -51
  71. data/lib/appium_lib/android/device.rb +0 -39
  72. data/lib/appium_lib/android/mobile_methods.rb +0 -15
  73. data/lib/appium_lib/android/patch.rb +0 -16
  74. data/lib/appium_lib/capabilities.rb +0 -13
  75. data/lib/appium_lib/common/element/window.rb +0 -10
  76. data/lib/appium_lib/common/error.rb +0 -8
  77. data/lib/appium_lib/common/patch.rb +0 -190
  78. data/lib/appium_lib/common/search_context.rb +0 -10
  79. data/lib/appium_lib/common/version.rb +0 -5
  80. data/lib/appium_lib/device/device.rb +0 -611
  81. data/lib/appium_lib/device/multi_touch.rb +0 -225
  82. data/lib/appium_lib/device/touch_actions.rb +0 -230
  83. data/lib/appium_lib/ios/mobile_methods.rb +0 -25
  84. data/lib/appium_lib/ios/patch.rb +0 -22
@@ -0,0 +1,48 @@
1
+ module Appium
2
+ # Perform a series of gestures, one after another. Gestures are chained
3
+ # together and only performed when `perform()` is called. Default is conducted by global driver.
4
+ #
5
+ # Each method returns the object itself, so calls can be chained.
6
+ #
7
+ # ```ruby
8
+ # action = TouchAction.new.press(x: 45, y: 100).wait(5).release
9
+ # action.perform
10
+ # action = TouchAction.new.swipe(....)
11
+ # action.perform
12
+ # ```
13
+ #
14
+ # Or each methods can call without `TouchAction.new` as the following.
15
+ # In this case, `perform` is called automatically.
16
+ # ```ruby
17
+ # # called `swipe(...).perform` in this method.
18
+ # swipe(start_x: 75, start_y: 500, offset_x: 75, offset_y: 20, duration: 500)
19
+ # ```
20
+ #
21
+ # If you'd like to perform the chain with an arbitrary driver:
22
+ # ```ruby
23
+ # driver = Appium::Driver.new(opts, false).start_driver
24
+ # action = TouchAction.new.press(x: 45, y: 100).wait(5).release
25
+ # action.perform(@driver)
26
+ # action = TouchAction.new.swipe(....)
27
+ # action.perform(@driver)
28
+ # ```
29
+ class TouchAction < ::Appium::Core::TouchAction
30
+ COMPLEX_ACTIONS = ::Appium::Core::TouchAction::COMPLEX_ACTIONS
31
+
32
+ class << self
33
+ COMPLEX_ACTIONS.each do |action|
34
+ define_method(action) do |opts|
35
+ auto_perform = opts.delete(:auto_perform) { |_k| true }
36
+ ta = ::Appium::TouchAction.new($driver)
37
+ ta.send(action, opts)
38
+ return ta unless auto_perform
39
+ ta.perform
40
+ end
41
+ end
42
+ end
43
+
44
+ def initialize(driver = $driver)
45
+ super driver
46
+ end
47
+ end # class TouchAction
48
+ end # module Appium
@@ -1,49 +1,10 @@
1
+ require_relative '../core/common/base/wait'
2
+
1
3
  module Appium
2
4
  module Common
3
- class Wait < ::Selenium::WebDriver::Wait
5
+ class Wait < ::Appium::Core::Base::Wait
4
6
  def initialize(opts = {})
5
- valid_keys = [:timeout, :interval, :message, :ignore, :return_if_true]
6
- invalid_keys = []
7
- opts.keys.each { |key| invalid_keys << key unless valid_keys.include?(key) }
8
- # [:one, :two] => :one, :two
9
- raise "Invalid keys #{invalid_keys.to_s[1..-2]}. Valid keys are #{valid_keys.to_s[1..-2]}" unless invalid_keys.empty?
10
-
11
- @timeout = opts.fetch(:timeout, DEFAULT_TIMEOUT)
12
- @interval = opts.fetch(:interval, DEFAULT_INTERVAL)
13
- @message = opts[:message]
14
- @ignored = Array(opts[:ignore] || ::Exception)
15
- @return_if_true = opts[:return_if_true]
16
-
17
- super(timeout: @timeout, interval: @interval, message: @message, ignore: @ignored)
18
- end
19
-
20
- # Wait code from the selenium Ruby gem
21
- # https://github.com/SeleniumHQ/selenium/blob/cf501dda3f0ed12233de51ce8170c0e8090f0c20/rb/lib/selenium/webdriver/common/wait.rb
22
- # @override
23
- def until
24
- end_time = Time.now + @timeout
25
- last_error = nil
26
-
27
- until Time.now > end_time
28
- begin
29
- return yield unless @return_if_true
30
-
31
- result = yield
32
- return result if result
33
- rescue ::Errno::ECONNREFUSED => e
34
- raise e
35
- rescue *@ignored => last_error # rubocop:disable Lint/HandleExceptions
36
- # swallowed
37
- end
38
-
39
- sleep @interval
40
- end
41
-
42
- msg = @message ? @message.dup : "timed out after #{@timeout} seconds"
43
-
44
- msg << " (#{last_error.message})" if last_error
45
-
46
- raise Selenium::WebDriver::Error::TimeOutError, msg
7
+ super(opts)
47
8
  end
48
9
  end
49
10
 
@@ -73,8 +34,8 @@ module Appium
73
34
  def wait_true(opts = {})
74
35
  opts = _process_wait_opts(opts).merge(return_if_true: true)
75
36
 
76
- opts[:timeout] ||= @appium_wait_timeout
77
- opts[:interval] ||= @appium_wait_interval
37
+ opts[:timeout] ||= @core.wait_timeout
38
+ opts[:interval] ||= @core.wait_interval
78
39
 
79
40
  wait = ::Appium::Common::Wait.new opts
80
41
  wait.until { yield }
@@ -96,11 +57,11 @@ module Appium
96
57
  def wait(opts = {})
97
58
  opts = _process_wait_opts(opts).merge(return_if_true: false)
98
59
 
99
- opts[:timeout] ||= @appium_wait_timeout
100
- opts[:interval] ||= @appium_wait_interval
60
+ opts[:timeout] ||= @core.wait_timeout
61
+ opts[:interval] ||= @core.wait_interval
101
62
 
102
63
  wait = ::Appium::Common::Wait.new opts
103
64
  wait.until { yield }
104
65
  end
105
- end # module Common
106
- end # module Appium
66
+ end
67
+ end
@@ -0,0 +1,4 @@
1
+ # loaded in common/driver.rb
2
+ require_relative 'android/search_context'
3
+ require_relative 'android/device'
4
+ require_relative 'android/uiautomator1/bridge'
@@ -0,0 +1,142 @@
1
+ module Appium
2
+ module Android
3
+ module Device
4
+ extend Forwardable
5
+
6
+ # @!method background_app
7
+ # Backgrounds the app for a set number of seconds.
8
+ # This is a blocking application
9
+ # @param [Integer] seconds How many seconds to background the app for.
10
+ #
11
+ # ```ruby
12
+ # background_app
13
+ # background_app(5)
14
+ # background_app(-1) #=> the app never come back. https://github.com/appium/appium/issues/7741
15
+ # ```
16
+
17
+ # @!method hide_keyboard
18
+ # Hide the onscreen keyboard
19
+ # @param [String] close_key The name of the key which closes the keyboard.
20
+ # Defaults to 'Done' for iOS(except for XCUITest).
21
+ # @param [Symbol] strategy The symbol of the strategy which closes the keyboard.
22
+ # XCUITest ignore this argument.
23
+ # Default for iOS is `:pressKey`. Default for Android is `:tapOutside`.
24
+ # ```ruby
25
+ # hide_keyboard # Close a keyboard with the 'Done' button
26
+ # hide_keyboard('Finished') # Close a keyboard with the 'Finished' button
27
+ # hide_keyboard(nil, :tapOutside) # Close a keyboard with tapping out side of keyboard
28
+ # ```
29
+
30
+ # @!method end_coverage
31
+ # Android only; Ends the test coverage and writes the results to the given path on device.
32
+ # @param [String] path Path on the device to write too.
33
+ # @param [String] intent Intent to broadcast when ending coverage.
34
+
35
+ # @!method start_activity
36
+ # Start a new activity within the current app or launch a new app and start the target activity.
37
+ #
38
+ # Android only.
39
+ # @option [String] The package owning the activity [required]
40
+ # @option [String] The target activity [required]
41
+ # @option opts [String] The package to start before the target package [optional]
42
+ # @option opts [String] The activity to start before the target activity [optional]
43
+ #
44
+ # ```ruby
45
+ # start_activity app_package: 'io.appium.android.apis',
46
+ # app_activity: '.accessibility.AccessibilityNodeProviderActivity'
47
+ # ```
48
+
49
+ # @!method set_network_connection
50
+ # Set the device network connection mode
51
+ # @param [String] path Bit mask that represent the network mode
52
+ #
53
+ # Value (Alias) | Data | Wifi | Airplane Mode
54
+ # -------------------------------------------------
55
+ # 1 (Airplane Mode) | 0 | 0 | 1
56
+ # 6 (All network on) | 1 | 1 | 0
57
+ # 4 (Data only) | 1 | 0 | 0
58
+ # 2 (Wifi only) | 0 | 1 | 0
59
+ # 0 (None) | 0 | 0 | 0
60
+ #
61
+
62
+ # @!method get_performance_data_types
63
+ # Get the information type of the system state which is supported to read such as
64
+ # cpu, memory, network, battery via adb commands.
65
+ # https://github.com/appium/appium-base-driver/blob/be29aec2318316d12b5c3295e924a5ba8f09b0fb/lib/mjsonwp/routes.js#L300
66
+ #
67
+ # ```ruby
68
+ # get_performance_data_types #=> ["cpuinfo", "batteryinfo", "networkinfo", "memoryinfo"]
69
+ # ```
70
+
71
+ # @!method get_performance_data
72
+ # Get the resource usage information of the application.
73
+ # https://github.com/appium/appium-base-driver/blob/be29aec2318316d12b5c3295e924a5ba8f09b0fb/lib/mjsonwp/routes.js#L303
74
+ # @param [String] package_name Package name
75
+ # @param [String] data_type Data type get with `get_performance_data_types`
76
+ # @param [String] data_read_timeout Command timeout. Default is 2.
77
+ #
78
+ # ```ruby
79
+ # get_performance_data package_name: package_name, data_type: data_type, data_read_timeout: 2
80
+ # ```
81
+ class << self
82
+ def extended(_mod)
83
+ Appium::Core::Device.extend_webdriver_with_forwardable
84
+
85
+ # Android
86
+ Appium::Core::Device.add_endpoint_method(:start_activity) do
87
+ def start_activity(opts)
88
+ raise 'opts must be a hash' unless opts.is_a? Hash
89
+ app_package = opts[:app_package]
90
+ raise 'app_package is required' unless app_package
91
+ app_activity = opts[:app_activity]
92
+ raise 'app_activity is required' unless app_activity
93
+ app_wait_package = opts.fetch(:app_wait_package, '')
94
+ app_wait_activity = opts.fetch(:app_wait_activity, '')
95
+
96
+ unknown_opts = opts.keys - [:app_package, :app_activity, :app_wait_package, :app_wait_activity]
97
+ raise "Unknown options #{unknown_opts}" unless unknown_opts.empty?
98
+
99
+ execute :start_activity, {}, appPackage: app_package,
100
+ appActivity: app_activity,
101
+ appWaitPackage: app_wait_package,
102
+ appWaitActivity: app_wait_activity
103
+ end
104
+ end
105
+
106
+ # Android, Override
107
+ Appium::Core::Device.add_endpoint_method(:hide_keyboard) do
108
+ def hide_keyboard(close_key = nil, strategy = nil)
109
+ option = {}
110
+
111
+ option[:key] = close_key if close_key
112
+ option[:strategy] = strategy || :tapOutside # default to pressKey
113
+
114
+ execute :hide_keyboard, {}, option
115
+ end
116
+ end
117
+
118
+ # TODO: TEST ME
119
+ Appium::Core::Device.add_endpoint_method(:end_coverage) do
120
+ def end_coverage(path, intent)
121
+ execute :end_coverage, {}, path: path, intent: intent
122
+ end
123
+ end
124
+
125
+ Appium::Core::Device.add_endpoint_method(:set_network_connection) do
126
+ def set_network_connection(mode)
127
+ execute :set_network_connection, {}, type: mode
128
+ end
129
+ end
130
+
131
+ Appium::Core::Device.add_endpoint_method(:get_performance_data) do
132
+ def get_performance_data(package_name:, data_type:, data_read_timeout: 1000)
133
+ execute :get_performance_data, {}, packageName: package_name,
134
+ dataType: data_type,
135
+ dataReadTimeout: data_read_timeout
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end # module Device
141
+ end # module Android
142
+ end # module Appium
@@ -0,0 +1,17 @@
1
+ module Appium
2
+ module Core
3
+ module Android
4
+ module SearchContext
5
+ # @!method uiautomator_find
6
+ # find_element/s can be used with a [UISelector](http://developer.android.com/tools/help/uiautomator/UiSelector.html).
7
+ #
8
+ # ```ruby
9
+ # find_elements :uiautomator, 'new UiSelector().clickable(true)'
10
+ # ```
11
+ def self.extend
12
+ ::Appium::Core::Base::SearchContext.add_finders(uiautomator: '-android uiautomator')
13
+ end
14
+ end # class << self
15
+ end # module Ios
16
+ end # module Core
17
+ end # module Appium
@@ -0,0 +1,16 @@
1
+ require_relative '../../android'
2
+
3
+ module Appium
4
+ module Core
5
+ module Android
6
+ module Uiautomator1
7
+ module Bridge
8
+ def self.for(target)
9
+ target.extend Appium::Android::Device
10
+ ::Appium::Core::Android::SearchContext.extend
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ require_relative '../../android_uiautomator2'
2
+
3
+ module Appium
4
+ module Core
5
+ module Android
6
+ module Uiautomator2
7
+ module Bridge
8
+ def self.for(target)
9
+ target.extend Appium::Android::Device
10
+ ::Appium::Core::Android::SearchContext.extend
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,4 @@
1
+ # loaded in common/driver.rb
2
+ require_relative 'android/search_context'
3
+ require_relative 'android/device'
4
+ require_relative 'android/uiautomator2/bridge'
@@ -0,0 +1,6 @@
1
+ require_relative 'common/logger'
2
+ require_relative 'common/error'
3
+ require_relative 'common/log'
4
+ require_relative 'common/command'
5
+ require_relative 'common/device'
6
+ require_relative 'common/base'
@@ -0,0 +1,8 @@
1
+ # The following files have selenium-webdriver related stuff.
2
+ require_relative 'base/driver'
3
+ require_relative 'base/bridge'
4
+ require_relative 'base/capabilities'
5
+ require_relative 'base/http_default'
6
+ require_relative 'base/search_context'
7
+ require_relative 'base/command'
8
+ require_relative 'base/wait'
@@ -0,0 +1,47 @@
1
+ module Appium
2
+ module Core
3
+ class Base
4
+ class Bridge < ::Selenium::WebDriver::Remote::Bridge
5
+ def self.handshake(**opts)
6
+ desired_capabilities = opts.delete(:desired_capabilities)
7
+
8
+ if desired_capabilities.is_a?(Symbol)
9
+ unless Remote::Capabilities.respond_to?(desired_capabilities)
10
+ raise Error::WebDriverError, "invalid desired capability: #{desired_capabilities.inspect}"
11
+ end
12
+ desired_capabilities = Remote::Capabilities.__send__(desired_capabilities)
13
+ end
14
+
15
+ bridge = new(opts)
16
+ capabilities = bridge.create_session(desired_capabilities)
17
+
18
+ case bridge.dialect
19
+ when :oss
20
+ CoreBridgeOSS.new(capabilities, bridge.session_id, opts)
21
+ when :w3c
22
+ CoreBridgeW3C.new(capabilities, bridge.session_id, opts)
23
+ else
24
+ raise CoreError, 'cannot understand dialect'
25
+ end
26
+ end
27
+ end # class Bridge
28
+
29
+ class CoreBridgeOSS < ::Selenium::WebDriver::Remote::OSS::Bridge
30
+ def commands(command)
31
+ ::Appium::Core::Commands::COMMANDS_EXTEND_OSS[command]
32
+ end
33
+ end # class CoreBridgeOSS
34
+
35
+ class CoreBridgeW3C < ::Selenium::WebDriver::Remote::W3C::Bridge
36
+ def commands(command)
37
+ case command
38
+ when :status, :is_element_displayed
39
+ ::Appium::Core::Commands::COMMANDS_EXTEND_OSS[command]
40
+ else
41
+ ::Appium::Core::Commands::COMMANDS_EXTEND_W3C[command]
42
+ end
43
+ end
44
+ end # class CoreBridgeW3C
45
+ end # class Base
46
+ end # module Core
47
+ end # module Appium
@@ -0,0 +1,16 @@
1
+ module Appium
2
+ module Core
3
+ class Base
4
+ module Capabilities
5
+ # @private
6
+ # @param [Hash] opts_caps Capabilities for Appium server. All capability keys are converted to lowerCamelCase when
7
+ # this client sends capabilities to Appium server as JSON format.
8
+ # @return [::Selenium::WebDriver::Remote::W3C::Capabilities] Return instance of Appium::Core::Base::Capabilities
9
+ # inherited ::Selenium::WebDriver::Remote::W3C::Capabilities
10
+ def self.create_capabilities(opts_caps = {})
11
+ ::Selenium::WebDriver::Remote::W3C::Capabilities.new(opts_caps)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,10 @@
1
+ module Appium
2
+ module Core
3
+ class Base
4
+ module Commands
5
+ OSS = ::Selenium::WebDriver::Remote::OSS::Bridge::COMMANDS.freeze
6
+ W3C = ::Selenium::WebDriver::Remote::W3C::Bridge::COMMANDS.freeze
7
+ end # module Commands
8
+ end # module Base
9
+ end # module Core
10
+ end # module Appium
@@ -0,0 +1,40 @@
1
+ require_relative 'search_context'
2
+
3
+ module Appium
4
+ module Core
5
+ class Base
6
+ class Driver < ::Selenium::WebDriver::Driver
7
+ include ::Selenium::WebDriver::DriverExtensions::UploadsFiles
8
+ include ::Selenium::WebDriver::DriverExtensions::TakesScreenshot
9
+ include ::Selenium::WebDriver::DriverExtensions::HasSessionId
10
+ include ::Selenium::WebDriver::DriverExtensions::Rotatable
11
+ include ::Selenium::WebDriver::DriverExtensions::HasRemoteStatus
12
+ include ::Selenium::WebDriver::DriverExtensions::HasWebStorage
13
+
14
+ include ::Appium::Core::Base::SearchContext
15
+
16
+ def initialize(opts = {})
17
+ listener = opts.delete(:listener)
18
+ @bridge = ::Appium::Core::Base::Bridge.handshake(opts)
19
+ if @bridge.dialect == :oss
20
+ extend ::Selenium::WebDriver::DriverExtensions::HasTouchScreen
21
+ extend ::Selenium::WebDriver::DriverExtensions::HasLocation
22
+ extend ::Selenium::WebDriver::DriverExtensions::HasNetworkConnection
23
+ end
24
+ super(@bridge, listener: listener)
25
+ end
26
+
27
+ # Get the device window's size.
28
+ # @return [Selenium::WebDriver::Dimension]
29
+ #
30
+ # @example
31
+ # size = @driver.window_size
32
+ # size.width #=> Integer
33
+ # size.height #=> Integer
34
+ def window_size
35
+ manage.window.size
36
+ end
37
+ end # class Driver
38
+ end # class Base
39
+ end # module Core
40
+ end # module Appium