calabash 1.2.1 → 1.9.9.pre1

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 (137) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +39 -0
  3. data/LICENSE +204 -21
  4. data/README.md +36 -6
  5. data/VERSIONING.md +16 -0
  6. data/bin/calabash +95 -0
  7. data/lib/calabash.rb +185 -1
  8. data/lib/calabash/android.rb +64 -0
  9. data/lib/calabash/android/adb.rb +277 -0
  10. data/lib/calabash/android/application.rb +110 -0
  11. data/lib/calabash/android/build.rb +12 -0
  12. data/lib/calabash/android/build/application.rb +13 -0
  13. data/lib/calabash/android/build/build_error.rb +11 -0
  14. data/lib/calabash/android/build/builder.rb +119 -0
  15. data/lib/calabash/android/build/java_keystore.rb +177 -0
  16. data/lib/calabash/android/build/resigner.rb +56 -0
  17. data/lib/calabash/android/build/test_server.rb +27 -0
  18. data/lib/calabash/android/console_helpers.rb +44 -0
  19. data/lib/calabash/android/cucumber.rb +3 -0
  20. data/lib/calabash/android/device.rb +965 -0
  21. data/lib/calabash/android/environment.rb +470 -0
  22. data/lib/calabash/android/gestures.rb +369 -0
  23. data/lib/calabash/android/interactions.rb +45 -0
  24. data/lib/calabash/android/lib/.irbrc +55 -0
  25. data/lib/calabash/android/lib/AndroidManifest.xml +51 -0
  26. data/lib/calabash/android/lib/TestServer.apk +0 -0
  27. data/lib/calabash/android/lib/calmd5/arm64-v8a/calmd5 +0 -0
  28. data/lib/calabash/android/lib/calmd5/arm64-v8a/calmd5-pie +0 -0
  29. data/lib/calabash/android/lib/calmd5/armeabi-v7a/calmd5 +0 -0
  30. data/lib/calabash/android/lib/calmd5/armeabi-v7a/calmd5-pie +0 -0
  31. data/lib/calabash/android/lib/calmd5/armeabi/calmd5 +0 -0
  32. data/lib/calabash/android/lib/calmd5/armeabi/calmd5-pie +0 -0
  33. data/lib/calabash/android/lib/calmd5/mips/calmd5 +0 -0
  34. data/lib/calabash/android/lib/calmd5/mips/calmd5-pie +0 -0
  35. data/lib/calabash/android/lib/calmd5/mips64/calmd5 +0 -0
  36. data/lib/calabash/android/lib/calmd5/mips64/calmd5-pie +0 -0
  37. data/lib/calabash/android/lib/calmd5/x86/calmd5 +0 -0
  38. data/lib/calabash/android/lib/calmd5/x86/calmd5-pie +0 -0
  39. data/lib/calabash/android/lib/calmd5/x86_64/calmd5 +0 -0
  40. data/lib/calabash/android/lib/calmd5/x86_64/calmd5-pie +0 -0
  41. data/lib/calabash/android/lib/screenshot_taker.jar +0 -0
  42. data/lib/calabash/android/life_cycle.rb +37 -0
  43. data/lib/calabash/android/orientation.rb +30 -0
  44. data/lib/calabash/android/physical_buttons.rb +39 -0
  45. data/lib/calabash/android/screenshot.rb +9 -0
  46. data/lib/calabash/android/scroll.rb +5 -0
  47. data/lib/calabash/android/server.rb +10 -0
  48. data/lib/calabash/android/text.rb +54 -0
  49. data/lib/calabash/application.rb +74 -0
  50. data/lib/calabash/cli.rb +12 -0
  51. data/lib/calabash/cli/build.rb +33 -0
  52. data/lib/calabash/cli/console.rb +90 -0
  53. data/lib/calabash/cli/generate.rb +110 -0
  54. data/lib/calabash/cli/helpers.rb +130 -0
  55. data/lib/calabash/cli/resign.rb +33 -0
  56. data/lib/calabash/cli/run.rb +99 -0
  57. data/lib/calabash/cli/setup_keystore.rb +39 -0
  58. data/lib/calabash/color.rb +32 -0
  59. data/lib/calabash/console_helpers.rb +90 -0
  60. data/lib/calabash/defaults.rb +56 -0
  61. data/lib/calabash/device.rb +401 -0
  62. data/lib/calabash/environment.rb +75 -0
  63. data/lib/calabash/gestures.rb +384 -0
  64. data/lib/calabash/http.rb +8 -0
  65. data/lib/calabash/http/error.rb +15 -0
  66. data/lib/calabash/http/request.rb +42 -0
  67. data/lib/calabash/http/retriable_client.rb +156 -0
  68. data/lib/calabash/interactions.rb +105 -0
  69. data/lib/calabash/ios.rb +37 -0
  70. data/lib/calabash/ios/application.rb +119 -0
  71. data/lib/calabash/ios/conditions.rb +79 -0
  72. data/lib/calabash/ios/console_helpers.rb +72 -0
  73. data/lib/calabash/ios/device.rb +24 -0
  74. data/lib/calabash/ios/device/device_implementation.rb +779 -0
  75. data/lib/calabash/ios/device/gestures_mixin.rb +167 -0
  76. data/lib/calabash/ios/device/keyboard_mixin.rb +133 -0
  77. data/lib/calabash/ios/device/physical_device_mixin.rb +266 -0
  78. data/lib/calabash/ios/device/rotation_mixin.rb +124 -0
  79. data/lib/calabash/ios/device/routes/backdoor_route_mixin.rb +86 -0
  80. data/lib/calabash/ios/device/routes/condition_route_mixin.rb +62 -0
  81. data/lib/calabash/ios/device/routes/error.rb +8 -0
  82. data/lib/calabash/ios/device/routes/handle_route_mixin.rb +102 -0
  83. data/lib/calabash/ios/device/routes/map_route_mixin.rb +38 -0
  84. data/lib/calabash/ios/device/routes/playback_route_mixin.rb +70 -0
  85. data/lib/calabash/ios/device/routes/response_parser.rb +48 -0
  86. data/lib/calabash/ios/device/routes/uia_route_mixin.rb +238 -0
  87. data/lib/calabash/ios/device/runtime_attributes.rb +184 -0
  88. data/lib/calabash/ios/device/status_bar_mixin.rb +17 -0
  89. data/lib/calabash/ios/device/text_mixin.rb +19 -0
  90. data/lib/calabash/ios/device/uia_keyboard_mixin.rb +188 -0
  91. data/lib/calabash/ios/device/uia_mixin.rb +12 -0
  92. data/lib/calabash/ios/environment.rb +41 -0
  93. data/lib/calabash/ios/interactions.rb +10 -0
  94. data/lib/calabash/ios/lib/.irbrc +55 -0
  95. data/lib/calabash/ios/lib/recordings/rotate_left_home_down_ipad.base64 +2 -0
  96. data/lib/calabash/ios/lib/recordings/rotate_left_home_down_iphone.base64 +2 -0
  97. data/lib/calabash/ios/lib/recordings/rotate_left_home_left_ipad.base64 +2 -0
  98. data/lib/calabash/ios/lib/recordings/rotate_left_home_left_iphone.base64 +2 -0
  99. data/lib/calabash/ios/lib/recordings/rotate_left_home_right_ipad.base64 +2 -0
  100. data/lib/calabash/ios/lib/recordings/rotate_left_home_right_iphone.base64 +2 -0
  101. data/lib/calabash/ios/lib/recordings/rotate_left_home_up_ipad.base64 +2 -0
  102. data/lib/calabash/ios/lib/recordings/rotate_left_home_up_iphone.base64 +2 -0
  103. data/lib/calabash/ios/lib/recordings/rotate_right_home_down_ipad.base64 +2 -0
  104. data/lib/calabash/ios/lib/recordings/rotate_right_home_down_iphone.base64 +2 -0
  105. data/lib/calabash/ios/lib/recordings/rotate_right_home_left_ipad.base64 +2 -0
  106. data/lib/calabash/ios/lib/recordings/rotate_right_home_left_iphone.base64 +2 -0
  107. data/lib/calabash/ios/lib/recordings/rotate_right_home_right_ipad.base64 +2 -0
  108. data/lib/calabash/ios/lib/recordings/rotate_right_home_right_iphone.base64 +2 -0
  109. data/lib/calabash/ios/lib/recordings/rotate_right_home_up_ipad.base64 +2 -0
  110. data/lib/calabash/ios/lib/recordings/rotate_right_home_up_iphone.base64 +2 -0
  111. data/lib/calabash/ios/orientation.rb +117 -0
  112. data/lib/calabash/ios/scroll.rb +504 -0
  113. data/lib/calabash/ios/server.rb +73 -0
  114. data/lib/calabash/ios/text.rb +248 -0
  115. data/lib/calabash/ios/uia.rb +24 -0
  116. data/lib/calabash/lib/skeleton/config/cucumber.yml +6 -0
  117. data/lib/calabash/lib/skeleton/features/sample.feature +5 -0
  118. data/lib/calabash/lib/skeleton/features/step_definitions/calabash_steps.rb +29 -0
  119. data/lib/calabash/lib/skeleton/features/support/env.rb +54 -0
  120. data/lib/calabash/lib/skeleton/features/support/hooks.rb +83 -0
  121. data/lib/calabash/life_cycle.rb +111 -0
  122. data/lib/calabash/location.rb +51 -0
  123. data/lib/calabash/logger.rb +87 -0
  124. data/lib/calabash/orientation.rb +84 -0
  125. data/lib/calabash/page.rb +35 -0
  126. data/lib/calabash/patch.rb +14 -0
  127. data/lib/calabash/patch/array.rb +16 -0
  128. data/lib/calabash/patch/run_loop.rb +90 -0
  129. data/lib/calabash/query.rb +160 -0
  130. data/lib/calabash/query_result.rb +85 -0
  131. data/lib/calabash/screenshot.rb +89 -0
  132. data/lib/calabash/server.rb +16 -0
  133. data/lib/calabash/text.rb +76 -0
  134. data/lib/calabash/utility.rb +58 -0
  135. data/lib/calabash/version.rb +3 -1
  136. data/lib/calabash/wait.rb +474 -0
  137. metadata +462 -24
@@ -0,0 +1,17 @@
1
+ module Calabash
2
+ module IOS
3
+ # @!visibility private
4
+ module StatusBarMixin
5
+
6
+ # Returns the home button position relative to the status bar.
7
+ #
8
+ # @note This method works even if a status bar is not visible.
9
+ #
10
+ # @return [String] Returns the device orientation as one of
11
+ # `{'down' | 'up' | 'left' | 'right'}`.
12
+ def status_bar_orientation
13
+ map_route(nil, :orientation, :status_bar).first
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ module Calabash
2
+ module IOS
3
+ # @!visibility private
4
+ module TextMixin
5
+
6
+ def enter_text(text)
7
+ wait_for_keyboard(Calabash::Wait.default_options[:timeout])
8
+ existing_text = text_from_keyboard_first_responder
9
+ options = { existing_text: existing_text }
10
+ uia_type_string(text, options)
11
+ end
12
+
13
+ def _enter_text_in(query, text)
14
+ _tap(query)
15
+ enter_text(text)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,188 @@
1
+ module Calabash
2
+ module IOS
3
+
4
+ # @!visibility private
5
+ module UIAKeyboardMixin
6
+
7
+ # @param [Hash] options Control behavior of this method.
8
+ # @option options [String] :existing_text ('') Text that exists in the
9
+ # view before this method is called. Passing this option ensures that
10
+ # the existing text is _appended_ rather than cleared and helps the
11
+ # underlying JavaScript handle various bugs in UIAutomation's
12
+ # typeString JavaScript API.
13
+ # @option options [Boolean] :escape_backslashes (true) When try, this
14
+ # method escapes '\' characters in the `string` before sending the
15
+ # string over UIA. The only time you don't want to escape the '\'
16
+ # character is when you are trying to send a single character like '\n'
17
+ # or '\d'.
18
+ def uia_type_string(string, options={})
19
+ default_options =
20
+ {
21
+ existing_text: '',
22
+ escape_backslashes: true
23
+ }
24
+ merged_options = default_options.merge(options)
25
+
26
+ if merged_options[:escape_backslashes]
27
+ string_to_type = UIATypeStringHandler.escape_backslashes_in_string(string)
28
+ else
29
+ string_to_type = string.dup
30
+ end
31
+
32
+ existing_text = merged_options[:existing_text]
33
+
34
+ result = uia_serialize_and_call(:typeString, string_to_type, existing_text)
35
+
36
+ handler = uia_type_string_handler(string,
37
+ string_to_type,
38
+ existing_text,
39
+ result,
40
+ logger)
41
+ handler.handle_result
42
+ end
43
+
44
+ private
45
+
46
+ def uia_type_string_handler(string, escaped_string, existing_text, result, logger)
47
+ UIATypeStringHandler.new(string,
48
+ escaped_string,
49
+ existing_text,
50
+ result,
51
+ logger)
52
+ end
53
+
54
+ # @!visibility private
55
+ class UIATypeStringHandler
56
+
57
+ attr_reader :string, :escaped_string, :existing_text, :result, :logger
58
+
59
+ # The result returned should be a Hash.
60
+ #
61
+ # The result should have these keys. The 'value' key may or may not
62
+ # exist. The range of the 'value' key is not well understood; it varies
63
+ # depending on the context in which you are typing.
64
+ #
65
+ # :status => 'success' or 'error'
66
+ # :value => A hash of the view that was typed in, :nil', or nil.
67
+ # :index => This value is not important; ignore it.
68
+ def initialize(string, escaped_string, existing_text, result, logger)
69
+ @string = string
70
+ @escaped_string = escaped_string
71
+ @existing_text = existing_text
72
+ @result = result
73
+ @logger = logger
74
+ end
75
+
76
+ def self.escape_backslashes_in_string(string)
77
+ return string if string.index(/\\/)
78
+
79
+ escaped_string = string.dup
80
+
81
+ indexes = escaped_string.enum_for(:scan, /\\/).map { Regexp.last_match.begin(0) }
82
+ indexes.reverse.each { |idx| escaped_string = escaped_string.insert(idx, '\\') }
83
+
84
+ escaped_string
85
+ end
86
+
87
+ # Valid values: 'success' or 'error'
88
+ def status
89
+ result['status']
90
+ end
91
+
92
+ # A Hash of the view that was typed in or :nil. Other values are
93
+ # possible, but we don't have an enumeration of the possible values.
94
+ def value
95
+ result['value']
96
+ end
97
+
98
+ def log(message)
99
+ logger.log(Color.blue(message), :info)
100
+ end
101
+
102
+ def log_preamble
103
+ log('When typing:')
104
+ log(" raw string: #{string}")
105
+ log(" escaped: #{escaped_string}")
106
+ log("existing text: #{existing_text}")
107
+ end
108
+
109
+ def log_epilogue
110
+ log(" result: #{result}")
111
+ log('')
112
+ log('Please report this!')
113
+ log('https://github.com/calabash/calabash-ios/issues/374')
114
+ end
115
+
116
+ def handle_result
117
+ the_status = status
118
+ if the_status == 'error'
119
+ handle_error
120
+ elsif the_status == 'success'
121
+ handle_success
122
+ elsif result.is_a? Hash
123
+ if ['label', 'hit-point', 'el', 'rect'].all? { |key| result.has_key?(key) }
124
+ result
125
+ else
126
+ handle_unknown_status
127
+ end
128
+ else
129
+ handle_unknown_status
130
+ end
131
+ end
132
+
133
+ def handle_error
134
+ log_preamble
135
+ if result.has_key? 'value'
136
+ raise "Could not type '#{string}' - UIAutomation returned an error: '#{result['error']}'"
137
+ else
138
+ raise "Could not type '#{string}' - UIAutomation returned '#{result}'"
139
+ end
140
+ end
141
+
142
+ # When 'status' == 'success', we can get a variety of valid 'values'
143
+ #
144
+ # For example, typing on UIWebViews returns['value'] => ':nil'.
145
+ #
146
+ # The expected value is a Hash representation of the view that was
147
+ # typed in.
148
+ #
149
+ # We are interested in loggin situations where:
150
+ #
151
+ # 1. The 'value' key is not present in the result.
152
+ # 2. The 'value' key has a nil value.
153
+ def handle_success
154
+ the_value = value
155
+ if the_value.is_a? Hash
156
+ the_value
157
+ elsif the_value == ':nil'
158
+ true
159
+ else
160
+ handle_success_with_incident
161
+ end
162
+ end
163
+
164
+ def handle_success_with_incident
165
+ log_preamble
166
+ if value.nil?
167
+ if result.has_key? 'value'
168
+ log("received a 'success' response with no key for 'value'")
169
+ else
170
+ log("received a 'success' response with a 'nil' for key 'value'")
171
+ end
172
+ else
173
+ log("received a 'success' response with an unknown value for key 'value' => '#{value}'")
174
+ end
175
+ log_epilogue
176
+ false
177
+ end
178
+
179
+ def handle_unknown_status
180
+ log_preamble
181
+ log("receive response with an unknown value for 'status' key: '#{status}'")
182
+ log_epilogue
183
+ false
184
+ end
185
+ end
186
+ end
187
+ end
188
+ end
@@ -0,0 +1,12 @@
1
+ module Calabash
2
+ module IOS
3
+
4
+ # !@visibility private
5
+ module UIAMixin
6
+
7
+ def evaluate_uia(script)
8
+ uia_route(script)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,41 @@
1
+ module Calabash
2
+ module IOS
3
+
4
+ # Constants that describe the iOS test environment.
5
+ class Environment < Calabash::Environment
6
+
7
+ # A URI that points to the embedded Calabash server in the app under test.
8
+ #
9
+ # The default value is 'http://localhost:37265'.
10
+ #
11
+ # You can control the value of this variable by setting the `CAL_ENDPOINT`
12
+ # variable.
13
+ #
14
+ # @todo Maybe rename this to CAL_SERVER_URL or CAL_SERVER?
15
+ DEVICE_ENDPOINT = URI.parse((variable('CAL_ENDPOINT') || 'http://localhost:37265'))
16
+
17
+ # The strategy use when interacting with UIAutomation. Calabash iOS
18
+ # supports 3 strategies:
19
+ #
20
+ # 1. preferences: Fast, but only works on simulators and on devices < 8.0.
21
+ # 2. shared: Fast, but has limited functionality. For example, you
22
+ # can't send apps to the background.
23
+ # 3. host: Slow, but the only option for devices >= 8.0.
24
+ #
25
+ # Calabash and run-loop will work together to figure out the fastest,
26
+ # most feature complete strategy to use at runtime.
27
+ #
28
+ # This is an advanced feature. Don't set this variable unless you know
29
+ # what you are doing.
30
+ UIA_STRATEGY = lambda do
31
+ strategy = variable('CAL_UIA_STRATEGY')
32
+ if strategy
33
+ strategy.to_sym
34
+ else
35
+ nil
36
+ end
37
+ end.call
38
+ end
39
+ end
40
+ end
41
+
@@ -0,0 +1,10 @@
1
+ module Calabash
2
+ module IOS
3
+ module Interactions
4
+ # @!visibility private
5
+ def _evaluate_javascript_in(query, javascript)
6
+ query(query, calabashStringByEvaluatingJavaScript: javascript)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,55 @@
1
+ begin
2
+ require 'irb/completion'
3
+ require 'irb/ext/save-history'
4
+
5
+ begin
6
+ require 'awesome_print'
7
+ rescue LoadError => e
8
+ msg = ["Caught a LoadError: could not load 'awesome_print'",
9
+ "#{e}",
10
+ '',
11
+ 'Use bundler (recommended) or uninstall awesome_print.',
12
+ '',
13
+ '# Use bundler (recommended)',
14
+ '$ bundle update',
15
+ '$ bundle exec calabash console [path to apk]',
16
+ '',
17
+ '# Uninstall',
18
+ '$ gem update --system',
19
+ '$ gem uninstall -Vax --force --no-abort-on-dependent awesome_print']
20
+ puts msg
21
+ exit(1)
22
+ end
23
+
24
+ AwesomePrint.irb!
25
+
26
+ ARGV.concat [ '--readline',
27
+ '--prompt-mode',
28
+ 'simple']
29
+
30
+ # 50 entries in the list
31
+ IRB.conf[:SAVE_HISTORY] = 50
32
+
33
+ # Store results in home directory with specified file name
34
+ IRB.conf[:HISTORY_FILE] = '.irb-history'
35
+
36
+ require 'calabash/ios'
37
+
38
+ extend Calabash::IOS
39
+ extend Calabash::ConsoleHelpers
40
+
41
+ Calabash::Application.default = Calabash::IOS::Application.default_from_environment
42
+
43
+ identifier = Calabash::IOS::Device.default_identifier_for_application(Calabash::Application.default)
44
+ server = Calabash::IOS::Server.default
45
+
46
+ Calabash::Device.default = Calabash::IOS::Device.new(identifier, server)
47
+
48
+ Calabash.new_embed_method!(lambda {|*_| Calabash::Logger.info 'Embed is not available in the console.'})
49
+ Calabash::Screenshot.screenshot_directory_prefix = 'console_'
50
+ rescue Exception => e
51
+ puts 'Unable to start console:'
52
+ puts "#{e.class}: #{e.message}"
53
+ puts "#{e.backtrace.join("\n")}"
54
+ exit(1)
55
+ end
@@ -0,0 +1,2 @@
1
+ YnBsaXN0MDChAdMCBAYDBQdURGF0YUQDAAAAoFRUaW1lEwAAAbhNBUVUVFR5cGUQ
2
+ MggKERYcISovAAAAAAAAAQEAAAAAAAAACAAAAAAAAAAAAAAAAAAAADE=
@@ -0,0 +1,2 @@
1
+ YnBsaXN0MDChAdMCBAYDBQdURGF0YUQDAAAAoFRUaW1lEwAAAbhNBUVUVFR5cGUQ
2
+ MggKERYcISovAAAAAAAAAQEAAAAAAAAACAAAAAAAAAAAAAAAAAAAADE=
@@ -0,0 +1,2 @@
1
+ YnBsaXN0MDChAdMCBAYDBQdURGF0YUQBAAAAoFRUaW1lEwAAAbCIbyvaVFR5cGUQ
2
+ MggKERYcISovAAAAAAAAAQEAAAAAAAAACAAAAAAAAAAAAAAAAAAAADE=
@@ -0,0 +1,2 @@
1
+ YnBsaXN0MDChAdMCBAYDBQdURGF0YUQBAAAAoFRUaW1lEwAAAbCIbyvaVFR5cGUQ
2
+ MggKERYcISovAAAAAAAAAQEAAAAAAAAACAAAAAAAAAAAAAAAAAAAADE=
@@ -0,0 +1,2 @@
1
+ YnBsaXN0MDChAdMCBAYDBQdURGF0YUQCAAAAoFRUaW1lEwAAAbpMnOcWVFR5cGUQ
2
+ MggKERYcISovAAAAAAAAAQEAAAAAAAAACAAAAAAAAAAAAAAAAAAAADE=
@@ -0,0 +1,2 @@
1
+ YnBsaXN0MDChAdMCBAYDBQdURGF0YUQCAAAAoFRUaW1lEwAAAbpMnOcWVFR5cGUQ
2
+ MggKERYcISovAAAAAAAAAQEAAAAAAAAACAAAAAAAAAAAAAAAAAAAADE=
@@ -0,0 +1,2 @@
1
+ YnBsaXN0MDChAdMCBAYDBQdURGF0YUQEAAAAoFRUaW1lEwAAAa01e7C+VFR5cGUQ
2
+ MggKERYcISovAAAAAAAAAQEAAAAAAAAACAAAAAAAAAAAAAAAAAAAADE=
@@ -0,0 +1,2 @@
1
+ YnBsaXN0MDChAdMCBAYDBQdURGF0YUQEAAAAoFRUaW1lEwAAAa01e7C+VFR5cGUQ
2
+ MggKERYcISovAAAAAAAAAQEAAAAAAAAACAAAAAAAAAAAAAAAAAAAADE=
@@ -0,0 +1,2 @@
1
+ YnBsaXN0MDChAdMCBAYDBQdURGF0YUQEAAAAoFRUaW1lEwAAAaVlqJreVFR5cGUQ
2
+ MggKERYcISovAAAAAAAAAQEAAAAAAAAACAAAAAAAAAAAAAAAAAAAADE=
@@ -0,0 +1,2 @@
1
+ YnBsaXN0MDChAdMCBAYDBQdURGF0YUQEAAAAoFRUaW1lEwAAAaVlqJreVFR5cGUQ
2
+ MggKERYcISovAAAAAAAAAQEAAAAAAAAACAAAAAAAAAAAAAAAAAAAADE=
@@ -0,0 +1,2 @@
1
+ YnBsaXN0MDChAdMCBAYDBQdURGF0YUQCAAAAoFRUaW1lEwAAAaoeCDODVFR5cGUQ
2
+ MggKERYcISovAAAAAAAAAQEAAAAAAAAACAAAAAAAAAAAAAAAAAAAADE=
@@ -0,0 +1,2 @@
1
+ YnBsaXN0MDChAdMCBAYDBQdURGF0YUQCAAAAoFRUaW1lEwAAAaoeCDODVFR5cGUQ
2
+ MggKERYcISovAAAAAAAAAQEAAAAAAAAACAAAAAAAAAAAAAAAAAAAADE=
@@ -0,0 +1,2 @@
1
+ YnBsaXN0MDChAdMCBAYDBQdURGF0YUQBAAAAoFRUaW1lEwAAAcBXpQXHVFR5cGUQ
2
+ MggKERYcISovAAAAAAAAAQEAAAAAAAAACAAAAAAAAAAAAAAAAAAAADE=
@@ -0,0 +1,2 @@
1
+ YnBsaXN0MDChAdMCBAYDBQdURGF0YUQBAAAAoFRUaW1lEwAAAcBXpQXHVFR5cGUQ
2
+ MggKERYcISovAAAAAAAAAQEAAAAAAAAACAAAAAAAAAAAAAAAAAAAADE=
@@ -0,0 +1,2 @@
1
+ YnBsaXN0MDChAdMCBAYDBQdURGF0YUQDAAAAoFRUaW1lEwAAAbyCAvDjVFR5cGUQ
2
+ MggKERYcISovAAAAAAAAAQEAAAAAAAAACAAAAAAAAAAAAAAAAAAAADE=
@@ -0,0 +1,2 @@
1
+ YnBsaXN0MDChAdMCBAYDBQdURGF0YUQDAAAAoFRUaW1lEwAAAbyCAvDjVFR5cGUQ
2
+ MggKERYcISovAAAAAAAAAQEAAAAAAAAACAAAAAAAAAAAAAAAAAAAADE=
@@ -0,0 +1,117 @@
1
+ module Calabash
2
+ module IOS
3
+
4
+ # On iOS, the presenting view controller must respond to rotation events.
5
+ # If the presenting view controller does not respond to rotation events,
6
+ # then no rotation will be performed.
7
+ module Orientation
8
+
9
+ # Returns the home button position relative to the status bar.
10
+ #
11
+ # @note This method works even if a status bar is not visible.
12
+ #
13
+ # @return [String] Returns the device orientation as one of
14
+ # `{'down' | 'up' | 'left' | 'right'}`.
15
+ def status_bar_orientation
16
+ Device.default.status_bar_orientation
17
+ end
18
+
19
+ # Rotates the device in the direction indicated by `direction`.
20
+ #
21
+ # @example
22
+ # > rotate('left')
23
+ # > rotate('right')
24
+ #
25
+ # @note
26
+ # The presenting view controller must respond to rotation events.
27
+ # If the presenting view controller does not respond to rotation events,
28
+ # then no rotation will be performed.
29
+ #
30
+ # @param [String] direction The direction in which to rotate.
31
+ # Valid arguments are :left and :right
32
+ #
33
+ # @raise [ArgumentError] If an invalid direction is given.
34
+ # @return [String] The position of the home button relative to the status
35
+ # bar after the rotation. Can be one of 'down', 'left', 'right', 'up'.
36
+ def rotate(direction)
37
+ unless direction == 'left' || direction == 'right'
38
+ raise ArgumentError, "Expected '#{direction}' to be 'left' or 'right'"
39
+ end
40
+
41
+ Device.default.rotate(direction.to_sym)
42
+ wait_for_animations
43
+ status_bar_orientation
44
+ end
45
+
46
+ # Rotates the home button to a position relative to the status bar.
47
+ #
48
+ # @example portrait
49
+ # rotate_home_button_to 'down'
50
+ # rotate_home_button_to 'bottom'
51
+ #
52
+ # @example upside down
53
+ # rotate_home_button_to 'top'
54
+ # rotate_home_button_to 'up'
55
+ #
56
+ # @example landscape with left home button AKA: _right_ landscape
57
+ # rotate_home_button_to 'left'
58
+ #
59
+ # @example landscape with right home button AKA: _left_ landscape
60
+ # rotate_home_button_to 'right'
61
+ #
62
+ # @note Refer to Apple's documentation for clarification about left vs.
63
+ # right landscape orientations.
64
+ #
65
+ # @note
66
+ # The presenting view controller must respond to rotation events.
67
+ # If the presenting view controller does not respond to rotation events,
68
+ # then no rotation will be performed.
69
+ #
70
+ # @raise [ArgumentError] If an invalid position is given.
71
+ #
72
+ # @return [String] The position of the home button relative to the status
73
+ # bar after the rotation. Can be one of 'down', 'left', 'right', 'up'.
74
+ def rotate_home_button_to(position)
75
+ valid_positions = ['down', 'bottom', 'top', 'up', 'left', 'right']
76
+ unless valid_positions.include?(position)
77
+ raise ArgumentError,
78
+ "Expected '#{position}' to be one of #{valid_positions.join(', ')}"
79
+ end
80
+
81
+ canonical_position = position
82
+ canonical_position = 'down' if position == 'bottom'
83
+ canonical_position = 'up' if position == 'top'
84
+
85
+ Calabash::Device.default.rotate_home_button_to(canonical_position)
86
+ end
87
+
88
+ # @!visibility private
89
+ def _set_orientation_landscape
90
+ orientation = status_bar_orientation
91
+ return orientation if landscape?
92
+
93
+ rotate_home_button_to 'right'
94
+ end
95
+
96
+ # @!visibility private
97
+ def _set_orientation_portrait
98
+ orientation = status_bar_orientation
99
+ return orientation if portrait?
100
+
101
+ rotate_home_button_to 'down'
102
+ end
103
+
104
+ # @!visibility private
105
+ def _portrait?
106
+ orientation = status_bar_orientation
107
+ orientation.eql?('up') || orientation.eql?('down')
108
+ end
109
+
110
+ # @!visibility private
111
+ def _landscape?
112
+ orientation = status_bar_orientation
113
+ orientation.eql?('right') || orientation.eql?('left')
114
+ end
115
+ end
116
+ end
117
+ end