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.
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