calabash-cucumber 0.10.0.pre1 → 0.10.0.pre2
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/features/step_definitions/calabash_steps.rb +1 -1
- data/lib/calabash-cucumber/actions/instruments_actions.rb +15 -4
- data/lib/calabash-cucumber/actions/playback_actions.rb +12 -3
- data/lib/calabash-cucumber/connection.rb +3 -0
- data/lib/calabash-cucumber/connection_helpers.rb +4 -0
- data/lib/calabash-cucumber/core.rb +637 -83
- data/lib/calabash-cucumber/date_picker.rb +148 -29
- data/lib/calabash-cucumber/device.rb +160 -3
- data/lib/calabash-cucumber/environment_helpers.rb +91 -46
- data/lib/calabash-cucumber/failure_helpers.rb +40 -0
- data/lib/calabash-cucumber/http_helpers.rb +9 -2
- data/lib/calabash-cucumber/ibase.rb +136 -17
- data/lib/calabash-cucumber/ios7_operations.rb +13 -9
- data/lib/calabash-cucumber/ipad_1x_2x.rb +103 -48
- data/lib/calabash-cucumber/keyboard_helpers.rb +253 -144
- data/lib/calabash-cucumber/keychain_helpers.rb +46 -32
- data/lib/calabash-cucumber/launch/simulator_helper.rb +13 -12
- data/lib/calabash-cucumber/launch/simulator_launcher.rb +111 -78
- data/lib/calabash-cucumber/launcher.rb +265 -25
- data/lib/calabash-cucumber/map.rb +24 -22
- data/lib/calabash-cucumber/operations.rb +4 -160
- data/lib/calabash-cucumber/playback_helpers.rb +26 -0
- data/lib/calabash-cucumber/query_helpers.rb +12 -0
- data/lib/calabash-cucumber/rotation_helpers.rb +64 -8
- data/lib/calabash-cucumber/status_bar_helpers.rb +40 -3
- data/lib/calabash-cucumber/tests_helpers.rb +43 -14
- data/lib/calabash-cucumber/uia.rb +93 -9
- data/lib/calabash-cucumber/utils/logging.rb +30 -16
- data/lib/calabash-cucumber/utils/plist_buddy.rb +18 -19
- data/lib/calabash-cucumber/utils/simulator_accessibility.rb +41 -30
- data/lib/calabash-cucumber/utils/xctools.rb +31 -21
- data/lib/calabash-cucumber/version.rb +98 -2
- data/lib/calabash-cucumber/wait_helpers.rb +257 -77
- data/staticlib/calabash.framework.zip +0 -0
- metadata +64 -231
- data/.gitignore +0 -17
- data/CHANGES.txt +0 -1
- data/Gemfile +0 -4
- data/Rakefile +0 -72
- data/calabash-cucumber.gemspec +0 -36
- data/epl-v10.html +0 -261
- data/lib/calabash-cucumber/resources/cell_swipe_ios4_ipad.base64 +0 -51
- data/lib/calabash-cucumber/resources/cell_swipe_ios4_iphone.base64 +0 -51
- data/lib/calabash-cucumber/resources/cell_swipe_ios5_ipad.base64 +0 -74
- data/lib/calabash-cucumber/resources/cell_swipe_ios5_iphone.base64 +0 -74
- data/lib/calabash-cucumber/resources/double_tap_ios5_ipad.base64 +0 -15
- data/lib/calabash-cucumber/resources/double_tap_ios5_iphone.base64 +0 -15
- data/lib/calabash-cucumber/resources/double_tap_ios6_ipad.base64 +0 -22
- data/lib/calabash-cucumber/resources/double_tap_ios6_iphone.base64 +0 -22
- data/lib/calabash-cucumber/resources/pan_ios5_ipad.base64 +0 -199
- data/lib/calabash-cucumber/resources/pan_ios5_iphone.base64 +0 -199
- data/lib/calabash-cucumber/resources/pan_ios6_ipad.base64 +0 -206
- data/lib/calabash-cucumber/resources/pan_ios6_iphone.base64 +0 -206
- data/lib/calabash-cucumber/resources/pinch_in_ios4_ipad.base64 +0 -104
- data/lib/calabash-cucumber/resources/pinch_in_ios4_iphone.base64 +0 -104
- data/lib/calabash-cucumber/resources/pinch_in_ios5_ipad.base64 +0 -144
- data/lib/calabash-cucumber/resources/pinch_in_ios5_iphone.base64 +0 -144
- data/lib/calabash-cucumber/resources/pinch_in_ios6_ipad.base64 +0 -70
- data/lib/calabash-cucumber/resources/pinch_in_ios6_iphone.base64 +0 -70
- data/lib/calabash-cucumber/resources/pinch_out_ios5_ipad.base64 +0 -207
- data/lib/calabash-cucumber/resources/pinch_out_ios5_iphone.base64 +0 -207
- data/lib/calabash-cucumber/resources/pinch_out_ios6_ipad.base64 +0 -96
- data/lib/calabash-cucumber/resources/pinch_out_ios6_iphone.base64 +0 -96
- data/lib/calabash-cucumber/resources/rotate_left_home_down_ios4_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_down_ios4_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_down_ios5_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_down_ios5_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_left_ios4_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_left_ios4_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_left_ios5_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_left_ios5_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_right_ios4_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_right_ios4_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_right_ios5_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_right_ios5_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_up_ios4_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_up_ios4_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_up_ios5_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_left_home_up_ios5_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_down_ios4_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_down_ios4_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_down_ios5_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_down_ios5_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_left_ios4_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_left_ios4_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_left_ios5_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_left_ios5_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_right_ios4_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_right_ios4_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_right_ios5_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_right_ios5_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_up_ios4_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_up_ios4_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_up_ios5_ipad.base64 +0 -2
- data/lib/calabash-cucumber/resources/rotate_right_home_up_ios5_iphone.base64 +0 -2
- data/lib/calabash-cucumber/resources/swipe_down_ios5_ipad.base64 +0 -18
- data/lib/calabash-cucumber/resources/swipe_down_ios5_iphone.base64 +0 -31
- data/lib/calabash-cucumber/resources/swipe_down_ios6_ipad.base64 +0 -25
- data/lib/calabash-cucumber/resources/swipe_down_ios6_iphone.base64 +0 -25
- data/lib/calabash-cucumber/resources/swipe_left_hard_ios4_ipad.base64 +0 -15
- data/lib/calabash-cucumber/resources/swipe_left_hard_ios4_iphone.base64 +0 -15
- data/lib/calabash-cucumber/resources/swipe_left_ios4_ipad.base64 +0 -18
- data/lib/calabash-cucumber/resources/swipe_left_ios4_iphone.base64 +0 -18
- data/lib/calabash-cucumber/resources/swipe_left_ios5_ipad.base64 +0 -17
- data/lib/calabash-cucumber/resources/swipe_left_ios5_iphone.base64 +0 -34
- data/lib/calabash-cucumber/resources/swipe_left_ios6_ipad.base64 +0 -28
- data/lib/calabash-cucumber/resources/swipe_left_ios6_iphone.base64 +0 -28
- data/lib/calabash-cucumber/resources/swipe_right_hard_ios4_ipad.base64 +0 -17
- data/lib/calabash-cucumber/resources/swipe_right_hard_ios4_iphone.base64 +0 -17
- data/lib/calabash-cucumber/resources/swipe_right_ios4_ipad.base64 +0 -13
- data/lib/calabash-cucumber/resources/swipe_right_ios4_iphone.base64 +0 -13
- data/lib/calabash-cucumber/resources/swipe_right_ios5_ipad.base64 +0 -17
- data/lib/calabash-cucumber/resources/swipe_right_ios5_iphone.base64 +0 -17
- data/lib/calabash-cucumber/resources/swipe_right_ios6_ipad.base64 +0 -25
- data/lib/calabash-cucumber/resources/swipe_right_ios6_iphone.base64 +0 -25
- data/lib/calabash-cucumber/resources/swipe_up_ios5_ipad.base64 +0 -34
- data/lib/calabash-cucumber/resources/swipe_up_ios5_iphone.base64 +0 -28
- data/lib/calabash-cucumber/resources/swipe_up_ios6_ipad.base64 +0 -25
- data/lib/calabash-cucumber/resources/swipe_up_ios6_iphone.base64 +0 -25
- data/lib/calabash-cucumber/resources/touch_done_ios4_ipad.base64 +0 -7
- data/lib/calabash-cucumber/resources/touch_done_ios4_iphone.base64 +0 -9
- data/lib/calabash-cucumber/resources/touch_done_ios5_ipad.base64 +0 -7
- data/lib/calabash-cucumber/resources/touch_done_ios5_iphone.base64 +0 -9
- data/lib/calabash-cucumber/resources/touch_hold_ios5_ipad.base64 +0 -9
- data/lib/calabash-cucumber/resources/touch_hold_ios5_iphone.base64 +0 -9
- data/lib/calabash-cucumber/resources/touch_hold_ios6_ipad.base64 +0 -9
- data/lib/calabash-cucumber/resources/touch_hold_ios6_iphone.base64 +0 -9
- data/lib/calabash-cucumber/resources/touch_ios4_ipad.base64 +0 -9
- data/lib/calabash-cucumber/resources/touch_ios4_iphone.base64 +0 -9
- data/lib/calabash-cucumber/resources/touch_ios5_ipad.base64 +0 -9
- data/lib/calabash-cucumber/resources/touch_ios5_iphone.base64 +0 -9
- data/lib/calabash-cucumber/resources/touch_ios7_ipad.base64 +0 -9
- data/lib/calabash-cucumber/resources/touch_ios7_iphone.base64 +0 -9
- data/lib/calabash-cucumber/resources/wheel_down_ios4_ipad.base64 +0 -159
- data/lib/calabash-cucumber/resources/wheel_down_ios4_iphone.base64 +0 -159
- data/lib/calabash-cucumber/resources/wheel_down_ios5_ipad.base64 +0 -156
- data/lib/calabash-cucumber/resources/wheel_down_ios5_iphone.base64 +0 -156
- data/lib/calabash-cucumber/resources/wheel_up_ios4_ipad.base64 +0 -166
- data/lib/calabash-cucumber/resources/wheel_up_ios4_iphone.base64 +0 -166
- data/lib/calabash-cucumber/resources/wheel_up_ios5_ipad.base64 +0 -156
- data/lib/calabash-cucumber/resources/wheel_up_ios5_iphone.base64 +0 -156
- data/scripts/EmptyAppHack.app/Default-568h@2x.png +0 -0
- data/scripts/EmptyAppHack.app/Default.png +0 -0
- data/scripts/EmptyAppHack.app/Default@2x.png +0 -0
- data/scripts/EmptyAppHack.app/EmptyAppHack +0 -0
- data/scripts/EmptyAppHack.app/Info.plist +0 -0
- data/scripts/EmptyAppHack.app/PkgInfo +0 -1
- data/scripts/EmptyAppHack.app/en.lproj/InfoPlist.strings +0 -0
- data/scripts/com.example.plist +0 -0
- data/scripts/data/.GlobalPreferences.plist +0 -0
- data/scripts/reset_simulator.scpt +0 -0
- data/spec/bin/calabash_ios_sim_spec.rb +0 -24
- data/spec/launcher_spec.rb +0 -166
- data/spec/logging_spec.rb +0 -38
- data/spec/plist_buddy_spec.rb +0 -99
- data/spec/resources/enable-accessibility/6.1/.gitkeep +0 -0
- data/spec/resources/enable-accessibility/7.0.3-64/.gitkeep +0 -0
- data/spec/resources/enable-accessibility/7.0.3/.gitkeep +0 -0
- data/spec/resources/enable-accessibility/7.1-64/.gitkeep +0 -0
- data/spec/resources/enable-accessibility/7.1/.gitkeep +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/Default-568h@2x.png +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/Info.plist +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/LPSimpleExample-cal +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/PkgInfo +0 -1
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/InfoPlist.strings +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPFirstViewController.nib +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPFirstViewController~ipad.nib +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPFourthViewController.nib +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPFourthViewController~ipad.nib +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPSecondViewController.nib +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPSecondViewController~ipad.nib +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPThirdViewController.nib +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPThirdViewController~ipad.nib +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/first.png +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/first@2x.png +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/second.png +0 -0
- data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/second@2x.png +0 -0
- data/spec/resources/plist_buddy/com.example.plist +0 -0
- data/spec/resources/plist_buddy/com.testing.plist +0 -18
- data/spec/simulator_accessibility_spec.rb +0 -206
- data/spec/spec_helper.rb +0 -31
- data/spec/version_spec.rb +0 -13
- data/spec/xctools_spec.rb +0 -58
@@ -9,17 +9,45 @@ require 'cfpropertylist'
|
|
9
9
|
require 'calabash-cucumber/version'
|
10
10
|
require 'calabash-cucumber/utils/logging'
|
11
11
|
|
12
|
-
|
12
|
+
# Used to launch apps for testing in iOS Simulator or on iOS Devices. By default
|
13
|
+
# it uses Apple's `instruments` process to launch your app, but has legacy support
|
14
|
+
# for using `sim_launcher`.
|
15
|
+
#
|
16
|
+
# ### Accessing the current launcher from ruby.
|
17
|
+
#
|
18
|
+
# If you need a reference to the current launcher in your ruby code.
|
19
|
+
# This is usually not required, but might be useful in `support/01_launch.rb`.
|
20
|
+
#
|
21
|
+
# `Calabash::Cucumber::Launcher.launcher`
|
22
|
+
#
|
23
|
+
# ### Attaching to the current launcher in a console
|
24
|
+
#
|
25
|
+
# If Calabash already running and you want to attach to the current launcher,
|
26
|
+
# use `console_attach`. This is useful when a cucumber Scenario has failed and
|
27
|
+
# you want to query the current state of the app.
|
28
|
+
#
|
29
|
+
# * **Pro Tip:** set the `NO_STOP` environmental variable to 1 so calabash does
|
30
|
+
# not exit the simulator when a Scenario fails.
|
13
31
|
class Calabash::Cucumber::Launcher
|
14
32
|
|
15
33
|
include Calabash::Cucumber::Logging
|
16
34
|
include Calabash::Cucumber::SimulatorAccessibility
|
17
35
|
|
36
|
+
# A hash of known privacy settings that calabash can control.
|
18
37
|
KNOWN_PRIVACY_SETTINGS = {:photos => 'kTCCServicePhotos', :calendar => 'kTCCServiceCalendar', :address_book => 'kTCCServiceAddressBook'}
|
19
38
|
|
39
|
+
# noinspection RubyClassVariableUsageInspection
|
40
|
+
|
41
|
+
# @!visibility private
|
20
42
|
@@launcher = nil
|
21
43
|
|
44
|
+
# @!visibility private
|
22
45
|
SERVER_VERSION_NOT_AVAILABLE = '0.0.0'
|
46
|
+
# noinspection RubyClassVariableUsageInspection
|
47
|
+
|
48
|
+
# @!visibility private
|
49
|
+
# Class variable for caching the embedded server version so we only need to
|
50
|
+
# check the server version one time.
|
23
51
|
@@server_version = nil
|
24
52
|
|
25
53
|
attr_accessor :run_loop
|
@@ -28,6 +56,8 @@ class Calabash::Cucumber::Launcher
|
|
28
56
|
attr_accessor :launch_args
|
29
57
|
attr_accessor :simulator_launcher
|
30
58
|
|
59
|
+
# @!visibility private
|
60
|
+
# Generated when calabash cannot launch the app.
|
31
61
|
class StartError < RuntimeError
|
32
62
|
attr_accessor :error
|
33
63
|
|
@@ -35,31 +65,37 @@ class Calabash::Cucumber::Launcher
|
|
35
65
|
self.error= err
|
36
66
|
end
|
37
67
|
|
68
|
+
# @!visibility private
|
38
69
|
def to_s
|
39
70
|
"#{super.to_s}: #{error}"
|
40
71
|
end
|
41
72
|
end
|
42
73
|
|
74
|
+
# @!visibility private
|
75
|
+
# Generated when calabash cannot communicate with the app.
|
43
76
|
class CalabashLauncherTimeoutErr < Timeout::Error
|
44
77
|
end
|
45
78
|
|
46
|
-
|
79
|
+
# @!visibility private
|
47
80
|
def initialize
|
48
81
|
@simulator_launcher = Calabash::Cucumber::SimulatorLauncher.new
|
49
82
|
@@launcher = self
|
50
83
|
end
|
51
84
|
|
85
|
+
# @!visibility private
|
52
86
|
def actions
|
53
87
|
attach if @actions.nil?
|
54
88
|
@actions
|
55
89
|
end
|
56
90
|
|
91
|
+
# @see Calabash::Cucumber::Core#console_attach
|
57
92
|
def self.attach
|
58
93
|
l = launcher
|
59
94
|
return l if l && l.active?
|
60
95
|
l.attach
|
61
96
|
end
|
62
97
|
|
98
|
+
# @see Calabash::Cucumber::Core#console_attach
|
63
99
|
def attach(max_retry=1, timeout=10)
|
64
100
|
if calabash_no_launch?
|
65
101
|
self.actions= Calabash::Cucumber::PlaybackActions.new
|
@@ -95,20 +131,30 @@ class Calabash::Cucumber::Launcher
|
|
95
131
|
self
|
96
132
|
end
|
97
133
|
|
134
|
+
# Are we running using instruments?
|
135
|
+
#
|
136
|
+
# @return {Boolean} true if we're using instruments to launch
|
98
137
|
def self.instruments?
|
99
138
|
l = launcher_if_used
|
100
139
|
return false unless l
|
101
140
|
l.instruments?
|
102
141
|
end
|
103
142
|
|
143
|
+
# Get a reference to the current launcher (instantiates a new one if needed). Usually we use a singleton launcher throughout a test run.
|
144
|
+
# @return {Calabash::Cucumber::Launcher} the current launcher
|
104
145
|
def self.launcher
|
105
146
|
@@launcher ||= Calabash::Cucumber::Launcher.new
|
106
147
|
end
|
107
148
|
|
149
|
+
# Get a reference to the current launcher (does not instantiate a new one if unset).
|
150
|
+
# Usually we use a singleton launcher throughout a test run.
|
151
|
+
# @return {Calabash::Cucumber::Launcher} the current launcher or nil
|
108
152
|
def self.launcher_if_used
|
109
153
|
@@launcher
|
110
154
|
end
|
111
155
|
|
156
|
+
# "Major" component of the current iOS version of the device
|
157
|
+
# @return {String} the "major" component, e.g., "7" for "7.1.1"
|
112
158
|
def ios_major_version
|
113
159
|
# pinging the app will set self.device
|
114
160
|
ping_app if self.device.nil?
|
@@ -117,36 +163,141 @@ class Calabash::Cucumber::Launcher
|
|
117
163
|
device.ios_major_version
|
118
164
|
end
|
119
165
|
|
166
|
+
# the current iOS version of the device
|
167
|
+
# @return {String} the current iOS version of the device
|
120
168
|
def ios_version
|
121
169
|
return nil if device.nil?
|
122
170
|
device.ios_version
|
123
171
|
end
|
124
172
|
|
173
|
+
# @deprecated 0.10.0 Replaced with {#reset_app_sandbox}.
|
174
|
+
# Reset the app sandbox for a device.
|
125
175
|
def reset_app_jail(sdk=nil, path=nil)
|
126
|
-
|
127
|
-
|
176
|
+
# will be deprecated in a future version
|
177
|
+
#_deprecated('0.10.0', 'use reset_app_sandbox instead', :warn)
|
178
|
+
reset_app_sandbox({:sdk => sdk, :path => path})
|
179
|
+
end
|
180
|
+
|
181
|
+
# Resets the app's content and settings by deleting the following directories
|
182
|
+
# from application sandbox:
|
183
|
+
#
|
184
|
+
# * Library
|
185
|
+
# * Documents
|
186
|
+
# * tmp
|
187
|
+
#
|
188
|
+
# @note It is not recommended that you call this method directly. See the
|
189
|
+
# examples below for how use the `RESET_BETWEEN_SCENARIOS` environmental
|
190
|
+
# variable to reset the app sandbox.
|
191
|
+
#
|
192
|
+
# @note This method is only available for the iOS Simulator.
|
193
|
+
#
|
194
|
+
# @note Generates a warning if called when targeting a physical device and
|
195
|
+
# otherwise has no effect.
|
196
|
+
#
|
197
|
+
# @note When testing against the Xamarin Test Cloud, this method is never
|
198
|
+
# called. Use the `RESET_BETWEEN_SCENARIOS` environmental variable.
|
199
|
+
# See the examples.
|
200
|
+
#
|
201
|
+
# @example Use `RESET_BETWEEN_SCENARIOS` to reset the app sandbox before every Scenario.
|
202
|
+
# When testing devices outside the Xamarin Test Cloud this has no effect.
|
203
|
+
#
|
204
|
+
# On the Xamarin Test Cloud, the app sandbox will be reset, but this method
|
205
|
+
# will not be called; the resetting is done via an alternative mechanism.
|
206
|
+
#
|
207
|
+
# When testing simulators, this method will be called.
|
208
|
+
#
|
209
|
+
# Launch cucumber with RESET_BETWEEN_SCENARIOS=1
|
210
|
+
#
|
211
|
+
# $ RESET_BETWEEN_SCENARIOS=1 bundle exec cucumber
|
212
|
+
#
|
213
|
+
# @example Use tags and a Before hook to reset the app sandbox before specific Scenarios.
|
214
|
+
# # in your .feature file
|
215
|
+
#
|
216
|
+
# @reset_app_before_hook
|
217
|
+
# Scenario: some scenario that requires the app be reset
|
218
|
+
#
|
219
|
+
# # in your support/01_launch.rb file
|
220
|
+
# #
|
221
|
+
# # 1. add a Before hook
|
222
|
+
# Before('@reset_app_before_hook') do
|
223
|
+
# ENV['RESET_BETWEEN_SCENARIOS'] = '1'
|
224
|
+
# end
|
225
|
+
#
|
226
|
+
# # 2. after launching, revert the env var value
|
227
|
+
# Before do |scenario|
|
228
|
+
# # launch the app
|
229
|
+
# launcher = Calabash::Cucumber::Launcher.new
|
230
|
+
# unless launcher.calabash_no_launch?
|
231
|
+
# launcher.relaunch
|
232
|
+
# launcher.calabash_notify(self)
|
233
|
+
# end
|
234
|
+
# # disable resetting between Scenarios
|
235
|
+
# ENV['RESET_BETWEEN_SCENARIOS'] = ''
|
236
|
+
# end
|
237
|
+
#
|
238
|
+
# @param [Hash] opts can pass the target sdk or the path to the application bundle
|
239
|
+
# @option opts [String, Symbol] :sdk (nil) The target sdk. If nil is
|
240
|
+
# passed, then only app sandbox for the latest sdk will be deleted. If
|
241
|
+
# `:all` is passed, then the sandboxes for all sdks will be deleted.
|
242
|
+
# @option opts [String] :path (nil) path to the application bundle
|
243
|
+
def reset_app_sandbox(opts={})
|
244
|
+
|
245
|
+
if device_target?
|
246
|
+
calabash_warn("calling 'reset_app_sandbox' when targeting a device.")
|
247
|
+
return
|
248
|
+
end
|
249
|
+
|
250
|
+
default_opts = {:sdk => nil, :path => nil}
|
251
|
+
merged_opts = default_opts.merge opts
|
252
|
+
|
253
|
+
sdk ||= merged_opts[:sdk] || sdk_version || self.simulator_launcher.sdk_detector.latest_sdk_version
|
254
|
+
path ||= merged_opts[:path] || self.simulator_launcher.app_bundle_or_raise(app_path)
|
128
255
|
|
129
256
|
app = File.basename(path)
|
130
|
-
|
131
|
-
|
257
|
+
|
258
|
+
directories_for_sdk_prefix(sdk).each do |sdk_dir|
|
259
|
+
app_dir = File.expand_path("#{sdk_dir}/Applications")
|
260
|
+
next unless File.exists?(app_dir)
|
261
|
+
|
262
|
+
bundle = `find "#{app_dir}" -type d -depth 2 -name "#{app}" | head -n 1`
|
263
|
+
|
132
264
|
next if bundle.empty? # Assuming we're already clean
|
265
|
+
|
133
266
|
if debug_logging?
|
134
267
|
puts "Reset app state for #{bundle}"
|
135
268
|
end
|
136
269
|
sandbox = File.dirname(bundle)
|
137
|
-
['Library', 'Documents', 'tmp'].each do |
|
138
|
-
FileUtils.rm_rf(File.join(sandbox,
|
270
|
+
['Library', 'Documents', 'tmp'].each do |content_dir|
|
271
|
+
FileUtils.rm_rf(File.join(sandbox, content_dir))
|
139
272
|
end
|
140
273
|
end
|
274
|
+
end
|
141
275
|
|
142
|
-
|
276
|
+
# Simulates touching the iOS Simulator > Reset Content and Settings... menu
|
277
|
+
# item.
|
278
|
+
#
|
279
|
+
# @note
|
280
|
+
# **WARNING** This is a destructive operation. You have been warned.
|
281
|
+
#
|
282
|
+
# @raise RuntimeError if called when targeting a physical device
|
283
|
+
def reset_simulator
|
284
|
+
if device_target?
|
285
|
+
raise "calling 'reset_simulator' when targeting a device is not allowed"
|
286
|
+
end
|
287
|
+
reset_simulator_content_and_settings
|
143
288
|
end
|
144
289
|
|
290
|
+
# @!visibility private
|
145
291
|
def directories_for_sdk_prefix(sdk)
|
146
|
-
|
292
|
+
if sdk == :all
|
293
|
+
existing_simulator_support_sdk_dirs
|
294
|
+
else
|
295
|
+
Dir["#{simulator_app_support_dir}/#{sdk}*"]
|
296
|
+
end
|
147
297
|
end
|
148
298
|
|
149
|
-
# Call as update_privacy_settings('com.my.app', {:photos => {:allow => true}})
|
299
|
+
# Call as `update_privacy_settings('com.my.app', {:photos => {:allow => true}})`
|
300
|
+
# @!visibility private
|
150
301
|
def update_privacy_settings(bundle_id, opts={})
|
151
302
|
if debug_logging?
|
152
303
|
puts "Update privacy settings #{bundle_id}, #{opts}"
|
@@ -191,13 +342,14 @@ class Calabash::Cucumber::Launcher
|
|
191
342
|
end
|
192
343
|
end
|
193
344
|
end
|
194
|
-
|
195
345
|
end
|
196
346
|
|
347
|
+
# @!visibility private
|
197
348
|
def tcc_database_for_sdk_dir(dir)
|
198
349
|
File.join(dir,'Library', 'TCC', 'TCC.db')
|
199
350
|
end
|
200
351
|
|
352
|
+
# @!visibility private
|
201
353
|
def privacy_setting(sdk_dir, bundle_id, setting_name)
|
202
354
|
setting_name = KNOWN_PRIVACY_SETTINGS[setting_name] || setting_name
|
203
355
|
path_to_tcc_db = tcc_database_for_sdk_dir(sdk_dir)
|
@@ -207,6 +359,7 @@ class Calabash::Cucumber::Launcher
|
|
207
359
|
(output == '0' || output == '1') ? output.to_i : nil
|
208
360
|
end
|
209
361
|
|
362
|
+
# @!visibility private
|
210
363
|
def default_launch_args
|
211
364
|
# APP_BUNDLE_PATH
|
212
365
|
# BUNDLE_ID
|
@@ -249,11 +402,12 @@ class Calabash::Cucumber::Launcher
|
|
249
402
|
end
|
250
403
|
|
251
404
|
if args[:device_target].nil?
|
252
|
-
args[:device_target] = 'simulator'
|
405
|
+
args[:device_target] = device_tgt || 'simulator'
|
253
406
|
end
|
254
407
|
args
|
255
408
|
end
|
256
409
|
|
410
|
+
# @!visibility private
|
257
411
|
def detect_connected_device?
|
258
412
|
if ENV['DETECT_CONNECTED_DEVICE'] == '1'
|
259
413
|
return true
|
@@ -272,6 +426,7 @@ class Calabash::Cucumber::Launcher
|
|
272
426
|
return false
|
273
427
|
end
|
274
428
|
|
429
|
+
# @!visibility private
|
275
430
|
def default_launch_method
|
276
431
|
sdk = sdk_version
|
277
432
|
major = nil
|
@@ -298,7 +453,35 @@ class Calabash::Cucumber::Launcher
|
|
298
453
|
end
|
299
454
|
end
|
300
455
|
|
456
|
+
# Launches your app on the connected device or simulator. Stops the app if it is already running.
|
457
|
+
# `relaunch` does a lot of error detection and handling to reliably start the app and test. Instruments (particularly the cli)
|
458
|
+
# has stability issues which we workaround by restarting the simulator process and checking that UIAutomation is correctly
|
459
|
+
# attaching.
|
460
|
+
#
|
461
|
+
# Takes optional args to specify details of the launch (e.g. device or simulator, sdk version, target device, launch method...).
|
462
|
+
# @note an important part of relaunch behavior is controlled by environment variables, specified below
|
463
|
+
#
|
464
|
+
# The two most important environment variables are `DEVICE_TARGET` and `APP_BUNDLE_PATH`.
|
465
|
+
#
|
466
|
+
# - `DEVICE_TARGET` controls which device you're running on. To see the options run: `instruments -s devices`.
|
467
|
+
# In addition you can specify `DEVICE_TARGET=device` to run on a (unique) usb-connected device.
|
468
|
+
# - `APP_BUNDLE_PATH` controls which `.app` bundle to launch in simulator (don't use for on-device testing, instead use `BUNDLE_ID`).
|
469
|
+
# - `BUNDLE_ID` used with `DEVICE_TARGET=device` to specify which app to launch on device
|
470
|
+
# - `DEBUG` - set to "1" to obtain debug info (typically used to debug launching, UIAutomation and other issues)
|
471
|
+
# - `DEBUG_HTTP` - set to "1" to show raw HTTP traffic
|
472
|
+
#
|
473
|
+
#
|
474
|
+
# @example Launching on iPad simulator with DEBUG settings
|
475
|
+
# DEBUG_HTTP=1 DEVICE_TARGET="iPad - Simulator - iOS 7.1" DEBUG=1 APP_BUNDLE_PATH=FieldServiceiOS.app bundle exec calabash-ios console
|
476
|
+
# @param {Hash} args optional args to specify details of the launch (e.g. device or simulator, sdk version,
|
477
|
+
# target device, launch method...).
|
478
|
+
# @option args {String} :app (detect the location of the bundle from project settings) app bundle path
|
479
|
+
# @option args {String} :bundle_id if launching on device, specify this or env `BUNDLE_ID` to be the bundle identifier
|
480
|
+
# of the application to launch
|
481
|
+
# @option args {Hash} :privacy_settings preset privacy settings for the, e.g., `{:photos => {:allow => true}}`.
|
482
|
+
# See {KNOWN_PRIVACY_SETTINGS}
|
301
483
|
def relaunch(args={})
|
484
|
+
#TODO stopping is currently broken, but this works anyway because instruments stop the process before relaunching
|
302
485
|
RunLoop.stop(run_loop) if run_loop
|
303
486
|
|
304
487
|
args = default_launch_args.merge(args)
|
@@ -330,9 +513,25 @@ class Calabash::Cucumber::Launcher
|
|
330
513
|
|
331
514
|
args[:device] ||= detect_device_from_args(args)
|
332
515
|
|
333
|
-
|
334
|
-
|
335
|
-
|
516
|
+
if simulator_target?(args) and args[:reset]
|
517
|
+
# attempt to find the sdk version from the :device_target
|
518
|
+
sdk = sdk_version_for_simulator_target(args)
|
519
|
+
|
520
|
+
# *** LEGACY SUPPORT ***
|
521
|
+
# If DEVICE_TARGET has not been set and is not a device UDID, then
|
522
|
+
# :device_target will be 'simulator'. In that case, we cannot know what
|
523
|
+
# SDK version of the app sandbox we should reset. The user _might_ give
|
524
|
+
# us a hint with SDK_VERSION, but we want to deprecate that variable ASAP.
|
525
|
+
#
|
526
|
+
# If passed a nil SDK arg, reset_app_sandbox will reset the _latest_ SDK.
|
527
|
+
# This is not good, because this is probably _not_ the SDK that should be
|
528
|
+
# reset. Our only option is to reset every sandbox for all SDKs by
|
529
|
+
# passing :sdk => :all to reset_app_sandbox.
|
530
|
+
if sdk.nil? and args[:device_target] == 'simulator'
|
531
|
+
sdk = :all
|
532
|
+
end
|
533
|
+
reset_app_sandbox({:sdk => sdk, :path => args[:app]})
|
534
|
+
end
|
336
535
|
|
337
536
|
if args[:privacy_settings]
|
338
537
|
if simulator_target?(args)
|
@@ -361,6 +560,7 @@ class Calabash::Cucumber::Launcher
|
|
361
560
|
check_server_gem_compatibility
|
362
561
|
end
|
363
562
|
|
563
|
+
# @!visibility private
|
364
564
|
def detect_device_from_args(args)
|
365
565
|
if args[:app] && File.directory?(args[:app])
|
366
566
|
# Derive bundle id from bundle_dir
|
@@ -379,11 +579,9 @@ class Calabash::Cucumber::Launcher
|
|
379
579
|
else
|
380
580
|
args[:app]
|
381
581
|
end
|
382
|
-
|
383
|
-
|
384
582
|
end
|
385
583
|
|
386
|
-
#
|
584
|
+
# @!visibility private
|
387
585
|
def detect_app_bundle_from_args(args)
|
388
586
|
if simulator_target?(args)
|
389
587
|
device_xamarin_build_dir = 'iPhoneSimulator'
|
@@ -394,6 +592,7 @@ class Calabash::Cucumber::Launcher
|
|
394
592
|
self.simulator_launcher.detect_app_bundle(nil, device_xamarin_build_dir)
|
395
593
|
end
|
396
594
|
|
595
|
+
# @!visibility private
|
397
596
|
def detect_bundle_id_from_app_bundle(args)
|
398
597
|
if args[:app] && File.directory?(args[:app])
|
399
598
|
# Derive bundle id from bundle_dir
|
@@ -406,11 +605,13 @@ class Calabash::Cucumber::Launcher
|
|
406
605
|
end
|
407
606
|
end
|
408
607
|
|
608
|
+
# @!visibility private
|
409
609
|
def info_plist_from_bundle_path(bundle_path)
|
410
610
|
plist_path = File.join(bundle_path, 'Info.plist')
|
411
611
|
info_plist_as_hash(plist_path) if File.exist?(plist_path)
|
412
612
|
end
|
413
613
|
|
614
|
+
# @!visibility private
|
414
615
|
def new_run_loop(args)
|
415
616
|
|
416
617
|
# for stability, quit the simulator if Xcode version is > 5.1 and the
|
@@ -441,6 +642,7 @@ class Calabash::Cucumber::Launcher
|
|
441
642
|
raise StartError.new(last_err)
|
442
643
|
end
|
443
644
|
|
645
|
+
# @!visibility private
|
444
646
|
def ensure_connectivity(max_retry=10, timeout=30)
|
445
647
|
begin
|
446
648
|
max_retry_count = (ENV['MAX_CONNECT_RETRY'] || max_retry).to_i
|
@@ -484,6 +686,7 @@ class Calabash::Cucumber::Launcher
|
|
484
686
|
end
|
485
687
|
end
|
486
688
|
|
689
|
+
# @!visibility private
|
487
690
|
def ping_app
|
488
691
|
url = URI.parse(ENV['DEVICE_ENDPOINT']|| "http://localhost:37265/")
|
489
692
|
|
@@ -506,17 +709,19 @@ class Calabash::Cucumber::Launcher
|
|
506
709
|
status
|
507
710
|
end
|
508
711
|
|
712
|
+
# @!visibility private
|
509
713
|
def stop
|
510
714
|
RunLoop.stop(run_loop) if run_loop && run_loop[:pid]
|
511
715
|
end
|
512
716
|
|
717
|
+
# @!visibility private
|
513
718
|
def calabash_notify(world)
|
514
719
|
if world.respond_to?(:on_launch)
|
515
720
|
world.on_launch
|
516
721
|
end
|
517
722
|
end
|
518
723
|
|
519
|
-
|
724
|
+
# @!visibility private
|
520
725
|
def info_plist_as_hash(plist_path)
|
521
726
|
unless File.exist?(plist_path)
|
522
727
|
raise "Unable to find Info.plist: #{plist_path}"
|
@@ -525,6 +730,7 @@ class Calabash::Cucumber::Launcher
|
|
525
730
|
CFPropertyList.native_types(parsedplist.value)
|
526
731
|
end
|
527
732
|
|
733
|
+
# @!visibility private
|
528
734
|
def detect_bundle_id
|
529
735
|
begin
|
530
736
|
bundle_path = self.simulator_launcher.app_bundle_or_raise(app_path)
|
@@ -535,60 +741,91 @@ class Calabash::Cucumber::Launcher
|
|
535
741
|
end
|
536
742
|
end
|
537
743
|
|
744
|
+
# @!visibility private
|
538
745
|
def calabash_no_stop?
|
539
746
|
calabash_no_launch? or ENV['NO_STOP']=="1"
|
540
747
|
end
|
541
748
|
|
749
|
+
# @!visibility private
|
542
750
|
def calabash_no_launch?
|
543
751
|
ENV['NO_LAUNCH']=='1'
|
544
752
|
end
|
545
753
|
|
754
|
+
# @!visibility private
|
546
755
|
def device_target?
|
547
756
|
(ENV['DEVICE_TARGET'] != nil) && (not simulator_target?)
|
548
757
|
end
|
549
758
|
|
759
|
+
# @!visibility private
|
550
760
|
def simulator_target?(launch_args={})
|
551
761
|
value = ENV['DEVICE_TARGET'] || launch_args[:device_target]
|
552
762
|
return false if value.nil?
|
553
763
|
value.downcase.include?('simulator')
|
554
764
|
end
|
555
765
|
|
766
|
+
# @!visibility private
|
556
767
|
def sdk_version
|
557
768
|
ENV['SDK_VERSION']
|
558
769
|
end
|
559
770
|
|
771
|
+
# @!visibility private
|
772
|
+
def sdk_version_for_simulator_target(launch_args)
|
773
|
+
return nil if device_target?
|
774
|
+
value = launch_args[:device_target]
|
775
|
+
return nil if value.nil?
|
776
|
+
return nil unless value.downcase.include?('simulator')
|
777
|
+
# we have a string like:
|
778
|
+
# iPhone Retina (4-inch) - Simulator - iOS 7.1
|
779
|
+
# iPad Retina - Simulator - iOS 6.1
|
780
|
+
# iPhone Retina (4-inch 64-bit) - Simulator - iOS 7.0
|
781
|
+
sdk = value.split(' ').last
|
782
|
+
|
783
|
+
# legacy support for DEVICE_TARGET=simulator
|
784
|
+
return nil if sdk == 'simulator'
|
785
|
+
sdk
|
786
|
+
end
|
787
|
+
|
788
|
+
# @!visibility private
|
560
789
|
def use_instruments_env?
|
561
790
|
ENV['LAUNCH_VIA'] == 'instruments'
|
562
791
|
end
|
563
792
|
|
793
|
+
# @!visibility private
|
564
794
|
def use_sim_launcher_env?
|
565
795
|
ENV['LAUNCH_VIA'] == 'sim_launcher'
|
566
796
|
end
|
567
797
|
|
798
|
+
# @!visibility private
|
568
799
|
def reset_between_scenarios?
|
569
800
|
ENV['RESET_BETWEEN_SCENARIOS']=="1"
|
570
801
|
end
|
571
802
|
|
803
|
+
# @!visibility private
|
572
804
|
def device_env
|
573
805
|
ENV['DEVICE']
|
574
806
|
end
|
575
807
|
|
808
|
+
# @!visibility private
|
576
809
|
def app_path
|
577
810
|
ENV['APP_BUNDLE_PATH'] || (defined?(APP_BUNDLE_PATH) && APP_BUNDLE_PATH) || ENV['APP']
|
578
811
|
end
|
579
812
|
|
813
|
+
# @!visibility private
|
580
814
|
def run_with_instruments?(args)
|
581
815
|
args && args[:launch_method] == :instruments
|
582
816
|
end
|
583
817
|
|
818
|
+
# @!visibility private
|
584
819
|
def active?
|
585
820
|
not run_loop.nil?
|
586
821
|
end
|
587
822
|
|
823
|
+
# @!visibility private
|
588
824
|
def instruments?
|
589
825
|
!!(active? && run_loop[:pid])
|
590
826
|
end
|
591
827
|
|
828
|
+
# @!visibility private
|
592
829
|
def inspect
|
593
830
|
msg = ["#{self.class}: Launch Method #{launch_args && launch_args[:launch_method]}"]
|
594
831
|
if run_with_instruments?(self.launch_args) && self.run_loop
|
@@ -597,17 +834,19 @@ class Calabash::Cucumber::Launcher
|
|
597
834
|
msg.join("\n")
|
598
835
|
end
|
599
836
|
|
600
|
-
#
|
837
|
+
# @!visibility private
|
838
|
+
# Extracts server version from the app binary at `app_bundle_path` by
|
601
839
|
# inspecting the binary's strings table.
|
602
840
|
#
|
603
|
-
#
|
604
|
-
#
|
841
|
+
# @note
|
842
|
+
# SPECIAL: sets the `@@server_version` class variable to cache the server
|
843
|
+
# version because the server version will never change during runtime.
|
605
844
|
#
|
606
845
|
# @return [String] the server version
|
607
846
|
# @param [String] app_bundle_path file path (usually) to the application bundle
|
608
|
-
# @raise [RuntimeError] if there is no executable at
|
847
|
+
# @raise [RuntimeError] if there is no executable at `app_bundle_path`
|
609
848
|
# @raise [RuntimeError] if the server version cannot be extracted from any
|
610
|
-
# binary at
|
849
|
+
# binary at `app_bundle_path`
|
611
850
|
def server_version_from_bundle(app_bundle_path)
|
612
851
|
return @@server_version unless @@server_version.nil?
|
613
852
|
exe_paths = []
|
@@ -665,6 +904,7 @@ class Calabash::Cucumber::Launcher
|
|
665
904
|
# WIP: this is a proof-of-concept implementation and requires _strict_
|
666
905
|
# equality. in the future we should allow minimum framework compatibility.
|
667
906
|
#
|
907
|
+
# @!visibility private
|
668
908
|
# @return [nil] nothing to return
|
669
909
|
def check_server_gem_compatibility
|
670
910
|
app_bundle_path = self.launch_args[:app]
|