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.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +39 -0
- data/LICENSE +204 -21
- data/README.md +36 -6
- data/VERSIONING.md +16 -0
- data/bin/calabash +95 -0
- data/lib/calabash.rb +185 -1
- data/lib/calabash/android.rb +64 -0
- data/lib/calabash/android/adb.rb +277 -0
- data/lib/calabash/android/application.rb +110 -0
- data/lib/calabash/android/build.rb +12 -0
- data/lib/calabash/android/build/application.rb +13 -0
- data/lib/calabash/android/build/build_error.rb +11 -0
- data/lib/calabash/android/build/builder.rb +119 -0
- data/lib/calabash/android/build/java_keystore.rb +177 -0
- data/lib/calabash/android/build/resigner.rb +56 -0
- data/lib/calabash/android/build/test_server.rb +27 -0
- data/lib/calabash/android/console_helpers.rb +44 -0
- data/lib/calabash/android/cucumber.rb +3 -0
- data/lib/calabash/android/device.rb +965 -0
- data/lib/calabash/android/environment.rb +470 -0
- data/lib/calabash/android/gestures.rb +369 -0
- data/lib/calabash/android/interactions.rb +45 -0
- data/lib/calabash/android/lib/.irbrc +55 -0
- data/lib/calabash/android/lib/AndroidManifest.xml +51 -0
- data/lib/calabash/android/lib/TestServer.apk +0 -0
- data/lib/calabash/android/lib/calmd5/arm64-v8a/calmd5 +0 -0
- data/lib/calabash/android/lib/calmd5/arm64-v8a/calmd5-pie +0 -0
- data/lib/calabash/android/lib/calmd5/armeabi-v7a/calmd5 +0 -0
- data/lib/calabash/android/lib/calmd5/armeabi-v7a/calmd5-pie +0 -0
- data/lib/calabash/android/lib/calmd5/armeabi/calmd5 +0 -0
- data/lib/calabash/android/lib/calmd5/armeabi/calmd5-pie +0 -0
- data/lib/calabash/android/lib/calmd5/mips/calmd5 +0 -0
- data/lib/calabash/android/lib/calmd5/mips/calmd5-pie +0 -0
- data/lib/calabash/android/lib/calmd5/mips64/calmd5 +0 -0
- data/lib/calabash/android/lib/calmd5/mips64/calmd5-pie +0 -0
- data/lib/calabash/android/lib/calmd5/x86/calmd5 +0 -0
- data/lib/calabash/android/lib/calmd5/x86/calmd5-pie +0 -0
- data/lib/calabash/android/lib/calmd5/x86_64/calmd5 +0 -0
- data/lib/calabash/android/lib/calmd5/x86_64/calmd5-pie +0 -0
- data/lib/calabash/android/lib/screenshot_taker.jar +0 -0
- data/lib/calabash/android/life_cycle.rb +37 -0
- data/lib/calabash/android/orientation.rb +30 -0
- data/lib/calabash/android/physical_buttons.rb +39 -0
- data/lib/calabash/android/screenshot.rb +9 -0
- data/lib/calabash/android/scroll.rb +5 -0
- data/lib/calabash/android/server.rb +10 -0
- data/lib/calabash/android/text.rb +54 -0
- data/lib/calabash/application.rb +74 -0
- data/lib/calabash/cli.rb +12 -0
- data/lib/calabash/cli/build.rb +33 -0
- data/lib/calabash/cli/console.rb +90 -0
- data/lib/calabash/cli/generate.rb +110 -0
- data/lib/calabash/cli/helpers.rb +130 -0
- data/lib/calabash/cli/resign.rb +33 -0
- data/lib/calabash/cli/run.rb +99 -0
- data/lib/calabash/cli/setup_keystore.rb +39 -0
- data/lib/calabash/color.rb +32 -0
- data/lib/calabash/console_helpers.rb +90 -0
- data/lib/calabash/defaults.rb +56 -0
- data/lib/calabash/device.rb +401 -0
- data/lib/calabash/environment.rb +75 -0
- data/lib/calabash/gestures.rb +384 -0
- data/lib/calabash/http.rb +8 -0
- data/lib/calabash/http/error.rb +15 -0
- data/lib/calabash/http/request.rb +42 -0
- data/lib/calabash/http/retriable_client.rb +156 -0
- data/lib/calabash/interactions.rb +105 -0
- data/lib/calabash/ios.rb +37 -0
- data/lib/calabash/ios/application.rb +119 -0
- data/lib/calabash/ios/conditions.rb +79 -0
- data/lib/calabash/ios/console_helpers.rb +72 -0
- data/lib/calabash/ios/device.rb +24 -0
- data/lib/calabash/ios/device/device_implementation.rb +779 -0
- data/lib/calabash/ios/device/gestures_mixin.rb +167 -0
- data/lib/calabash/ios/device/keyboard_mixin.rb +133 -0
- data/lib/calabash/ios/device/physical_device_mixin.rb +266 -0
- data/lib/calabash/ios/device/rotation_mixin.rb +124 -0
- data/lib/calabash/ios/device/routes/backdoor_route_mixin.rb +86 -0
- data/lib/calabash/ios/device/routes/condition_route_mixin.rb +62 -0
- data/lib/calabash/ios/device/routes/error.rb +8 -0
- data/lib/calabash/ios/device/routes/handle_route_mixin.rb +102 -0
- data/lib/calabash/ios/device/routes/map_route_mixin.rb +38 -0
- data/lib/calabash/ios/device/routes/playback_route_mixin.rb +70 -0
- data/lib/calabash/ios/device/routes/response_parser.rb +48 -0
- data/lib/calabash/ios/device/routes/uia_route_mixin.rb +238 -0
- data/lib/calabash/ios/device/runtime_attributes.rb +184 -0
- data/lib/calabash/ios/device/status_bar_mixin.rb +17 -0
- data/lib/calabash/ios/device/text_mixin.rb +19 -0
- data/lib/calabash/ios/device/uia_keyboard_mixin.rb +188 -0
- data/lib/calabash/ios/device/uia_mixin.rb +12 -0
- data/lib/calabash/ios/environment.rb +41 -0
- data/lib/calabash/ios/interactions.rb +10 -0
- data/lib/calabash/ios/lib/.irbrc +55 -0
- data/lib/calabash/ios/lib/recordings/rotate_left_home_down_ipad.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_left_home_down_iphone.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_left_home_left_ipad.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_left_home_left_iphone.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_left_home_right_ipad.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_left_home_right_iphone.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_left_home_up_ipad.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_left_home_up_iphone.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_right_home_down_ipad.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_right_home_down_iphone.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_right_home_left_ipad.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_right_home_left_iphone.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_right_home_right_ipad.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_right_home_right_iphone.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_right_home_up_ipad.base64 +2 -0
- data/lib/calabash/ios/lib/recordings/rotate_right_home_up_iphone.base64 +2 -0
- data/lib/calabash/ios/orientation.rb +117 -0
- data/lib/calabash/ios/scroll.rb +504 -0
- data/lib/calabash/ios/server.rb +73 -0
- data/lib/calabash/ios/text.rb +248 -0
- data/lib/calabash/ios/uia.rb +24 -0
- data/lib/calabash/lib/skeleton/config/cucumber.yml +6 -0
- data/lib/calabash/lib/skeleton/features/sample.feature +5 -0
- data/lib/calabash/lib/skeleton/features/step_definitions/calabash_steps.rb +29 -0
- data/lib/calabash/lib/skeleton/features/support/env.rb +54 -0
- data/lib/calabash/lib/skeleton/features/support/hooks.rb +83 -0
- data/lib/calabash/life_cycle.rb +111 -0
- data/lib/calabash/location.rb +51 -0
- data/lib/calabash/logger.rb +87 -0
- data/lib/calabash/orientation.rb +84 -0
- data/lib/calabash/page.rb +35 -0
- data/lib/calabash/patch.rb +14 -0
- data/lib/calabash/patch/array.rb +16 -0
- data/lib/calabash/patch/run_loop.rb +90 -0
- data/lib/calabash/query.rb +160 -0
- data/lib/calabash/query_result.rb +85 -0
- data/lib/calabash/screenshot.rb +89 -0
- data/lib/calabash/server.rb +16 -0
- data/lib/calabash/text.rb +76 -0
- data/lib/calabash/utility.rb +58 -0
- data/lib/calabash/version.rb +3 -1
- data/lib/calabash/wait.rb +474 -0
- metadata +462 -24
@@ -0,0 +1,73 @@
|
|
1
|
+
module Calabash
|
2
|
+
module IOS
|
3
|
+
|
4
|
+
# A representation of the embedded Calabash iOS server.
|
5
|
+
class Server < ::Calabash::Server
|
6
|
+
|
7
|
+
# Returns the default server.
|
8
|
+
#
|
9
|
+
# You can set the default server by setting the `CAL_ENDPOINT` environment
|
10
|
+
# variable. If this value is not set, the default server will be
|
11
|
+
# `http://localhost:37265`.
|
12
|
+
#
|
13
|
+
# **IMPORTANT**
|
14
|
+
#
|
15
|
+
# You must include http:// and the port number when setting the
|
16
|
+
# `CAL_ENDPOINT` variable.
|
17
|
+
#
|
18
|
+
# ### Physical Devices
|
19
|
+
#
|
20
|
+
# When targeting a physical device, you _must_ set the `CAL_ENDPOINT`
|
21
|
+
# environment variable. Your device must be on the same network as the
|
22
|
+
# host machine. You can find your device's IP address the Settings.app.
|
23
|
+
#
|
24
|
+
# Settings.app > WiFi > touch the (i)nfo
|
25
|
+
# disclosure button of the network you are
|
26
|
+
# connected to.
|
27
|
+
#
|
28
|
+
# ### Pro Tip: Name your devices.
|
29
|
+
#
|
30
|
+
# The Calabash iOS Server is a Bonjour web service. You can avoid the
|
31
|
+
# hassle of determining a device's IP address by naming your devices. The
|
32
|
+
# names should not have spaces or characters that cannot be displayed
|
33
|
+
# plainly in a URL.
|
34
|
+
#
|
35
|
+
# Suppose you have 3 devices: an iPad Mini Retina, an iPhone 4S, and an
|
36
|
+
# iPhone 6.
|
37
|
+
#
|
38
|
+
# | Device | Name | IP |
|
39
|
+
# |--------|------|----|
|
40
|
+
# | iPad | ipad-mini | CAL_ENDPOINT=http://ipad-mini.local:37265 |
|
41
|
+
# | iPhone 4S | iphone4s | CAL_ENDPOINT=http://iphone4s.local:37265 |
|
42
|
+
# | iPhone 6 | iphone6 | CAL_ENDPOINT=http://iphone6.local:37265 |
|
43
|
+
#
|
44
|
+
# ### Pro Tip: Changing the Calabash server port.
|
45
|
+
#
|
46
|
+
# You can change the port number of the server by adding
|
47
|
+
# `CalabashServerPort` to your app's Info plist.
|
48
|
+
#
|
49
|
+
# CalabashServerPort NSNumber 9999
|
50
|
+
#
|
51
|
+
# ### Pro Tip: Share your wired connection
|
52
|
+
#
|
53
|
+
# https://github.com/calabash/calabash/wiki/iOS:-Improving-Network-Stability
|
54
|
+
#
|
55
|
+
# @return [Calabash::IOS::Server] The Calabash iOS server that is
|
56
|
+
# embedded in your app.
|
57
|
+
def self.default
|
58
|
+
endpoint = Environment::DEVICE_ENDPOINT
|
59
|
+
Server.new(endpoint)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Is this server running on the host machine?
|
63
|
+
#
|
64
|
+
# Apps running on the iOS Simulator are running on localhost.
|
65
|
+
#
|
66
|
+
# @return [Boolean] Returns true if the server hostname resolves to
|
67
|
+
# localhost.
|
68
|
+
def localhost?
|
69
|
+
endpoint.hostname == 'localhost' || endpoint.hostname == '127.0.0.1'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,248 @@
|
|
1
|
+
module Calabash
|
2
|
+
module IOS
|
3
|
+
module Text
|
4
|
+
# @!visibility private
|
5
|
+
def enter_text(text)
|
6
|
+
wait_for_keyboard
|
7
|
+
existing_text = text_from_keyboard_first_responder
|
8
|
+
options = { existing_text: existing_text }
|
9
|
+
Device.default.uia_type_string(text, options)
|
10
|
+
end
|
11
|
+
|
12
|
+
# @!visibility private
|
13
|
+
def _enter_text_in(view, text)
|
14
|
+
tap(view)
|
15
|
+
enter_text(text)
|
16
|
+
end
|
17
|
+
|
18
|
+
# @!visibility private
|
19
|
+
def _clear_text
|
20
|
+
unless view_exists?("* isFirstResponder:1")
|
21
|
+
raise 'Cannot clear text. No view has focus'
|
22
|
+
end
|
23
|
+
|
24
|
+
clear_text_in("* isFirstResponder:1")
|
25
|
+
end
|
26
|
+
|
27
|
+
# @!visibility private
|
28
|
+
def _clear_text_in(view)
|
29
|
+
unless keyboard_visible?
|
30
|
+
tap(view)
|
31
|
+
wait_for_keyboard
|
32
|
+
end
|
33
|
+
|
34
|
+
unless wait_for_view(view)['text'].empty?
|
35
|
+
tap(view)
|
36
|
+
tap("UICalloutBarButton marked:'Select All'")
|
37
|
+
tap_keyboard_delete_key
|
38
|
+
end
|
39
|
+
|
40
|
+
true
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns true if a docked keyboard is visible.
|
44
|
+
#
|
45
|
+
# A docked keyboard is pinned to the bottom of the view.
|
46
|
+
#
|
47
|
+
# Keyboards on the iPhone and iPod are docked.
|
48
|
+
#
|
49
|
+
# @return [Boolean] Returns true if a keyboard is visible and docked.
|
50
|
+
def docked_keyboard_visible?
|
51
|
+
Device.default.docked_keyboard_visible?
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns true if an undocked keyboard is visible.
|
55
|
+
#
|
56
|
+
# A undocked keyboard is floats in the middle of the view.
|
57
|
+
#
|
58
|
+
# @return [Boolean] Returns false if the device is not an iPad; all
|
59
|
+
# keyboards on the iPhone and iPod are docked.
|
60
|
+
def undocked_keyboard_visible?
|
61
|
+
Device.default.undocked_keyboard_visible?
|
62
|
+
end
|
63
|
+
|
64
|
+
# Returns true if a split keyboard is visible.
|
65
|
+
#
|
66
|
+
# A split keyboard is floats in the middle of the view and is split to
|
67
|
+
# allow faster thumb typing
|
68
|
+
#
|
69
|
+
# @return [Boolean] Returns false if the device is not an iPad; all
|
70
|
+
# keyboards on the Phone and iPod are docked and not split.
|
71
|
+
def split_keyboard_visible?
|
72
|
+
Device.default.split_keyboard_visible?
|
73
|
+
end
|
74
|
+
|
75
|
+
# Returns true if there is a visible keyboard.
|
76
|
+
#
|
77
|
+
# @return [Boolean] Returns true if there is a visible keyboard.
|
78
|
+
def keyboard_visible?
|
79
|
+
docked_keyboard_visible? || undocked_keyboard_visible? || split_keyboard_visible?
|
80
|
+
end
|
81
|
+
|
82
|
+
# Waits for a keyboard to appear.
|
83
|
+
#
|
84
|
+
# @see Calabash::Wait.default_options
|
85
|
+
#
|
86
|
+
# @param [Number] timeout How long to wait for the keyboard.
|
87
|
+
# @raise [Calabash::Wait::TimeoutError] Raises error if no keyboard
|
88
|
+
# appears.
|
89
|
+
def wait_for_keyboard(timeout=nil)
|
90
|
+
keyboard_timeout = keyboard_wait_timeout(timeout)
|
91
|
+
message = "Timed out after #{keyboard_timeout} seconds waiting for the keyboard to appear"
|
92
|
+
wait_for(message, timeout: keyboard_timeout) do
|
93
|
+
keyboard_visible?
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Waits for the keyboard to disappear.
|
98
|
+
#
|
99
|
+
# @see Calabash::Wait.default_options
|
100
|
+
#
|
101
|
+
# @param [Number] timeout How log to wait for the keyboard to disappear.
|
102
|
+
# @raise [Calabash::Wait::TimeoutError] Raises error if any keyboard is
|
103
|
+
# visible after the `timeout`.
|
104
|
+
def wait_for_no_keyboard(timeout=nil)
|
105
|
+
keyboard_timeout = keyboard_wait_timeout(timeout)
|
106
|
+
message = "Timed out after #{keyboard_timeout} seconds waiting for the keyboard to disappear"
|
107
|
+
wait_for(message, timeout: keyboard_timeout) do
|
108
|
+
!keyboard_visible?
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# Touches the keyboard action key.
|
113
|
+
#
|
114
|
+
# The action key depends on the keyboard. Some examples include:
|
115
|
+
#
|
116
|
+
# * Return
|
117
|
+
# * Next
|
118
|
+
# * Go
|
119
|
+
# * Join
|
120
|
+
# * Search
|
121
|
+
#
|
122
|
+
# Not all keyboards have an action key. For example, numeric keyboards
|
123
|
+
# do not have an action key.
|
124
|
+
#
|
125
|
+
# @raise [RuntimeError] If the text cannot be typed.
|
126
|
+
# @todo Refactor uia_route to a public API call
|
127
|
+
# @todo Move this documentation to the public method
|
128
|
+
def _tap_current_keyboard_action_key
|
129
|
+
char_sequence = ESCAPED_KEYBOARD_CHARACTERS[:action]
|
130
|
+
Device.default.uia_route("uia.keyboard().typeString('#{char_sequence}')")
|
131
|
+
end
|
132
|
+
|
133
|
+
# Touches the keyboard delete key.
|
134
|
+
#
|
135
|
+
# The 'delete' key difficult to find and touch because its behavior
|
136
|
+
# changes depending on the iOS version and keyboard type. Consider the
|
137
|
+
# following:
|
138
|
+
#
|
139
|
+
# On iOS 6, the 'delete' char code is _not_ \b.
|
140
|
+
# On iOS 7: The Delete char code is \b on non-numeric keyboards.
|
141
|
+
# On numeric keyboards, the delete key is a button on the
|
142
|
+
# the keyboard.
|
143
|
+
#
|
144
|
+
# By default, Calabash uses a raw UIAutomaton JavaScript call to tap the
|
145
|
+
# element named 'Delete'. This works well in English localizations for
|
146
|
+
# most keyboards. If you find that it does not work, use the options
|
147
|
+
# pass either an translation of 'Delete' for your localization or use the
|
148
|
+
# default the escaped keyboard character.
|
149
|
+
#
|
150
|
+
# @example
|
151
|
+
# # Uses UIAutomation to tap the 'Delete' key or button.
|
152
|
+
# tap_keyboard_delete_key
|
153
|
+
#
|
154
|
+
# # Types the \b key.
|
155
|
+
# tap_keyboard_delete_key({:use_escaped_char => true})
|
156
|
+
#
|
157
|
+
# # Types the \d key.
|
158
|
+
# tap_keyboard_delete_key({:use_escaped_char => '\d'})
|
159
|
+
#
|
160
|
+
# # Uses UIAutomation to tap the 'Slet' key or button.
|
161
|
+
# tap_keyboard_delete_key({:delete_key_label => 'Slet'})
|
162
|
+
#
|
163
|
+
# # Don't specify both options! If :use_escape_sequence is truthy,
|
164
|
+
# # Calabash will ignore the :delete_key_label and try to use an
|
165
|
+
# # escaped character sequence.
|
166
|
+
# tap_keyboard_delete_key({:use_escaped_char => true,
|
167
|
+
# :delete_key_label => 'Slet'})
|
168
|
+
#
|
169
|
+
# @param [Hash] options Alternative ways to tap the delete key.
|
170
|
+
# @option options [Boolean, String] :use_escaped_char (false) If true,
|
171
|
+
# delete by typing the \b character. If this value is truthy, but not
|
172
|
+
# 'true', they it is expected to be an alternative escaped character.
|
173
|
+
# @option options [String] :delete_key_label ('Delete') An alternative
|
174
|
+
# localization of 'Delete'.
|
175
|
+
# @todo Need translations of 'Delete' key.
|
176
|
+
def tap_keyboard_delete_key(options = {})
|
177
|
+
default_options =
|
178
|
+
{
|
179
|
+
use_escaped_char: false,
|
180
|
+
delete_key_label: 'Delete'
|
181
|
+
}
|
182
|
+
merged_options = default_options.merge(options)
|
183
|
+
|
184
|
+
use_escape_sequence = merged_options[:use_escaped_char]
|
185
|
+
if use_escape_sequence
|
186
|
+
if use_escape_sequence.to_s == 'true'
|
187
|
+
# Use the default \b
|
188
|
+
char_sequence = ESCAPED_KEYBOARD_CHARACTERS[:delete]
|
189
|
+
else
|
190
|
+
char_sequence = use_escape_sequence
|
191
|
+
end
|
192
|
+
return Device.default.uia_route("uia.keyboard().typeString('#{char_sequence}')")
|
193
|
+
end
|
194
|
+
|
195
|
+
delete_key_label = merged_options[:delete_key_label]
|
196
|
+
uia = "uia.keyboard().elements().firstWithName('#{delete_key_label}').tap()"
|
197
|
+
Device.default.uia_route(uia)
|
198
|
+
end
|
199
|
+
|
200
|
+
# Returns the the text in the first responder.
|
201
|
+
#
|
202
|
+
# The first responder will be the UITextField or UITextView instance
|
203
|
+
# that is associated with the visible keyboard.
|
204
|
+
#
|
205
|
+
# Returns empty string if no textField or textView elements are found to be
|
206
|
+
# the first responder. Otherwise, it will return the text in the
|
207
|
+
# UITextField or UITextField that is associated with the keyboard.
|
208
|
+
#
|
209
|
+
# @raise [RuntimeError] If there is no visible keyboard.
|
210
|
+
def text_from_keyboard_first_responder
|
211
|
+
Device.default.text_from_keyboard_first_responder
|
212
|
+
end
|
213
|
+
|
214
|
+
private
|
215
|
+
|
216
|
+
# @!visibility private
|
217
|
+
# noinspection RubyStringKeysInHashInspection
|
218
|
+
ESCAPED_KEYBOARD_CHARACTERS =
|
219
|
+
{
|
220
|
+
:action => '\n',
|
221
|
+
|
222
|
+
# This works for some combinations of keyboard types and
|
223
|
+
# iOS version. The current solution is use a raw UIA call
|
224
|
+
# to find the 'Delete' key, which may not work in some
|
225
|
+
# situations, for example in non-English environments. The
|
226
|
+
# tap_keyboard_delete_key allows an option to us this escape
|
227
|
+
# sequence.
|
228
|
+
:delete => '\b',
|
229
|
+
|
230
|
+
# These are not supported yet and I am pretty sure that they
|
231
|
+
# cannot be touched by passing an escaped character and instead
|
232
|
+
# the must be found using UIAutomation calls. -jmoody
|
233
|
+
#'Dictation' => nil,
|
234
|
+
#'Shift' => nil,
|
235
|
+
#'International' => nil,
|
236
|
+
#'More' => nil,
|
237
|
+
}
|
238
|
+
|
239
|
+
def keyboard_wait_timeout(timeout)
|
240
|
+
if timeout.nil?
|
241
|
+
Calabash::Gestures::DEFAULT_GESTURE_WAIT_TIMEOUT
|
242
|
+
else
|
243
|
+
timeout
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Calabash
|
2
|
+
module IOS
|
3
|
+
module UIA
|
4
|
+
|
5
|
+
# Evaluates `script` with Apple's UIAutomation API.
|
6
|
+
#
|
7
|
+
def uia(script)
|
8
|
+
Device.default.evaluate_uia(script)
|
9
|
+
end
|
10
|
+
|
11
|
+
def uia_with_target(script)
|
12
|
+
uia("UIATarget.localTarget().#{script}")
|
13
|
+
end
|
14
|
+
|
15
|
+
def uia_with_app(script)
|
16
|
+
uia("UIATarget.localTarget().frontMostApp().#{script}")
|
17
|
+
end
|
18
|
+
|
19
|
+
def uia_with_main_window(script)
|
20
|
+
uia("UIATarget.localTarget().frontMostApp().mainWindow().#{script}")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
Given(/^I have done a specific thing$/) do
|
2
|
+
# Sample step definition
|
3
|
+
# Example: (Given I am logged in)
|
4
|
+
# enter_text("* marked:'username'", USERNAME)
|
5
|
+
# enter_text("* marked:'password'", PASSWORD)
|
6
|
+
# touch("* marked:'login'")
|
7
|
+
# wait_for_view("* text:'Welcome #{USERNAME}'")
|
8
|
+
|
9
|
+
# Remember: any Ruby is allowed in your step definitions
|
10
|
+
did_something = true
|
11
|
+
|
12
|
+
unless did_something
|
13
|
+
fail 'Expected to have done something'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
When(/^I do something$/) do
|
18
|
+
# Sample step definition
|
19
|
+
# Example: When I create a new entry
|
20
|
+
# touch("* marked:'new_entry'")
|
21
|
+
# enter_text("* marked:'entry_title'", 'My Entry')
|
22
|
+
# touch("* marked:'submit'")
|
23
|
+
end
|
24
|
+
|
25
|
+
Then(/^something should happen$/) do
|
26
|
+
# Sample step definition
|
27
|
+
# Example: Then I should see the entry on my home page
|
28
|
+
# wait_for_view("* text:'My Entry'")
|
29
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'calabash'
|
2
|
+
|
3
|
+
platform = Calabash::Environment.variable('PLATFORM')
|
4
|
+
|
5
|
+
case platform
|
6
|
+
when 'android'
|
7
|
+
require 'calabash/android'
|
8
|
+
|
9
|
+
World(Calabash::Android)
|
10
|
+
|
11
|
+
# Setup the default application
|
12
|
+
Calabash::Application.default =
|
13
|
+
Calabash::Android::Application.default_from_environment
|
14
|
+
|
15
|
+
identifier = Calabash::Android::Device.default_serial
|
16
|
+
server = Calabash::Android::Server.default
|
17
|
+
|
18
|
+
# Setup the default device
|
19
|
+
Calabash::Device.default =
|
20
|
+
Calabash::Android::Device.new(identifier, server)
|
21
|
+
when 'ios'
|
22
|
+
require 'calabash/ios'
|
23
|
+
|
24
|
+
World(Calabash::IOS)
|
25
|
+
|
26
|
+
# Setup the default application
|
27
|
+
Calabash::Application.default =
|
28
|
+
Calabash::IOS::Application.default_from_environment
|
29
|
+
|
30
|
+
identifier =
|
31
|
+
Calabash::IOS::Device.default_identifier_for_application(Calabash::Application.default)
|
32
|
+
|
33
|
+
server = Calabash::IOS::Server.default
|
34
|
+
|
35
|
+
# Setup the default device
|
36
|
+
Calabash::Device.default =
|
37
|
+
Calabash::IOS::Device.new(identifier, server)
|
38
|
+
else
|
39
|
+
message = if platform.nil? || platform.empty?
|
40
|
+
'No platform given'
|
41
|
+
else
|
42
|
+
"Invalid platform '#{platform}'. Expected 'android' or 'ios'"
|
43
|
+
end
|
44
|
+
|
45
|
+
failure_messages =
|
46
|
+
[
|
47
|
+
'ERROR! Unable to start the cucumber test:',
|
48
|
+
message,
|
49
|
+
"Use the profile 'android' or 'ios', or run cucumber using $ calabash run"
|
50
|
+
]
|
51
|
+
|
52
|
+
Calabash::Logger.error(failure_messages.join("\n"))
|
53
|
+
exit(1)
|
54
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'calabash'
|
2
|
+
|
3
|
+
Before do |scenario|
|
4
|
+
if scenario.respond_to?(:scenario_outline)
|
5
|
+
scenario = scenario.scenario_outline
|
6
|
+
end
|
7
|
+
|
8
|
+
AppLifeCycle.on_new_scenario(scenario)
|
9
|
+
|
10
|
+
start_app
|
11
|
+
end
|
12
|
+
|
13
|
+
After do
|
14
|
+
stop_app
|
15
|
+
end
|
16
|
+
|
17
|
+
module AppLifeCycle
|
18
|
+
# Since this is a module, the methods in the Cucumber World are not
|
19
|
+
# available inside the scope of this module. We can safely include Calabash
|
20
|
+
# because we will not affect the scope outside this module. The methods are
|
21
|
+
# loaded as class (static) methods.
|
22
|
+
class << self
|
23
|
+
include Calabash
|
24
|
+
end
|
25
|
+
|
26
|
+
DEFAULT_RESET_BETWEEN = #!DEFAULT_RESET_BETWEEN#! # Filled in by calabash gen
|
27
|
+
DEFAULT_RESET_METHOD = #!DEFAULT_RESET_METHOD#! # Filled in by calabash gen
|
28
|
+
|
29
|
+
RESET_BETWEEN = if Calabash::Environment.variable('RESET_BETWEEN')
|
30
|
+
Calabash::Environment.variable('RESET_BETWEEN').downcase.to_sym
|
31
|
+
else
|
32
|
+
DEFAULT_RESET_BETWEEN
|
33
|
+
end
|
34
|
+
|
35
|
+
RESET_METHOD = if Calabash::Environment.variable('RESET_METHOD')
|
36
|
+
Calabash::Environment.variable('RESET_METHOD').downcase.to_sym
|
37
|
+
else
|
38
|
+
DEFAULT_RESET_METHOD
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.on_new_scenario(scenario)
|
42
|
+
# Ensure the app is installed at the beginning of the test,
|
43
|
+
# if we never reset
|
44
|
+
if @last_feature.nil? && RESET_BETWEEN == :never
|
45
|
+
ensure_app_installed
|
46
|
+
end
|
47
|
+
|
48
|
+
if should_reset?(scenario)
|
49
|
+
reset
|
50
|
+
end
|
51
|
+
|
52
|
+
@last_feature = scenario.feature
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def self.should_reset?(scenario)
|
58
|
+
case RESET_BETWEEN
|
59
|
+
when :scenarios
|
60
|
+
true
|
61
|
+
when :features
|
62
|
+
scenario.feature != @last_feature
|
63
|
+
when :never
|
64
|
+
false
|
65
|
+
else
|
66
|
+
raise "Invalid reset between option '#{RESET_BETWEEN}'"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.reset
|
71
|
+
case RESET_METHOD
|
72
|
+
when :reinstall
|
73
|
+
install_app
|
74
|
+
when :clear
|
75
|
+
ensure_app_installed
|
76
|
+
clear_app_data
|
77
|
+
when '', nil
|
78
|
+
raise 'No reset method given'
|
79
|
+
else
|
80
|
+
raise "Invalid reset method '#{RESET_METHOD}'"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|