calabash-cucumber 0.18.2 → 0.19.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. checksums.yaml +4 -4
  2. data/bin/calabash-ios +0 -16
  3. data/bin/calabash-ios-build.rb +0 -86
  4. data/bin/calabash-ios-helpers.rb +0 -65
  5. data/bin/calabash-ios-setup.rb +5 -119
  6. data/bin/calabash-ios-sim.rb +0 -37
  7. data/bin/frank-calabash +0 -1
  8. data/doc/calabash-ios-help.txt +0 -8
  9. data/dylibs/libCalabashDyn.dylib +0 -0
  10. data/dylibs/libCalabashDynSim.dylib +0 -0
  11. data/features-skeleton/support/01_launch.rb +3 -4
  12. data/features/step_definitions/calabash_steps.rb +1 -7
  13. data/lib/calabash-cucumber.rb +1 -2
  14. data/lib/calabash-cucumber/actions/instruments_actions.rb +2 -3
  15. data/lib/calabash-cucumber/core.rb +97 -101
  16. data/lib/calabash-cucumber/device.rb +5 -118
  17. data/lib/calabash-cucumber/environment.rb +109 -5
  18. data/lib/calabash-cucumber/environment_helpers.rb +4 -66
  19. data/lib/calabash-cucumber/http/http.rb +114 -0
  20. data/lib/calabash-cucumber/http_helpers.rb +3 -1
  21. data/lib/calabash-cucumber/ipad_1x_2x.rb +5 -7
  22. data/lib/calabash-cucumber/keyboard_helpers.rb +0 -44
  23. data/lib/calabash-cucumber/launcher.rb +425 -808
  24. data/lib/calabash-cucumber/logging.rb +2 -74
  25. data/lib/calabash-cucumber/operations.rb +0 -2
  26. data/lib/calabash-cucumber/rotation_helpers.rb +2 -82
  27. data/lib/calabash-cucumber/status_bar_helpers.rb +2 -8
  28. data/lib/calabash-cucumber/store/preferences.rb +2 -1
  29. data/lib/calabash-cucumber/uia.rb +4 -9
  30. data/lib/calabash-cucumber/version.rb +2 -2
  31. data/lib/calabash-cucumber/wait_helpers.rb +0 -2
  32. data/staticlib/calabash.framework.zip +0 -0
  33. data/staticlib/libFrankCalabash.a +0 -0
  34. metadata +13 -143
  35. data/lib/calabash-cucumber/actions/playback_actions.rb +0 -109
  36. data/lib/calabash-cucumber/deprecated.rb +0 -34
  37. data/lib/calabash-cucumber/launch/simulator_helper.rb +0 -62
  38. data/lib/calabash-cucumber/launch/simulator_launcher.rb +0 -617
  39. data/lib/calabash-cucumber/playback_helpers.rb +0 -225
  40. data/lib/calabash-cucumber/resources/cell_swipe_ios4_ipad.base64 +0 -51
  41. data/lib/calabash-cucumber/resources/cell_swipe_ios4_iphone.base64 +0 -51
  42. data/lib/calabash-cucumber/resources/cell_swipe_ios5_ipad.base64 +0 -74
  43. data/lib/calabash-cucumber/resources/cell_swipe_ios5_iphone.base64 +0 -74
  44. data/lib/calabash-cucumber/resources/double_tap_ios5_ipad.base64 +0 -15
  45. data/lib/calabash-cucumber/resources/double_tap_ios5_iphone.base64 +0 -15
  46. data/lib/calabash-cucumber/resources/double_tap_ios6_ipad.base64 +0 -22
  47. data/lib/calabash-cucumber/resources/double_tap_ios6_iphone.base64 +0 -22
  48. data/lib/calabash-cucumber/resources/pan_ios5_ipad.base64 +0 -199
  49. data/lib/calabash-cucumber/resources/pan_ios5_iphone.base64 +0 -199
  50. data/lib/calabash-cucumber/resources/pan_ios6_ipad.base64 +0 -206
  51. data/lib/calabash-cucumber/resources/pan_ios6_iphone.base64 +0 -206
  52. data/lib/calabash-cucumber/resources/pinch_in_ios4_ipad.base64 +0 -104
  53. data/lib/calabash-cucumber/resources/pinch_in_ios4_iphone.base64 +0 -104
  54. data/lib/calabash-cucumber/resources/pinch_in_ios5_ipad.base64 +0 -144
  55. data/lib/calabash-cucumber/resources/pinch_in_ios5_iphone.base64 +0 -144
  56. data/lib/calabash-cucumber/resources/pinch_in_ios6_ipad.base64 +0 -70
  57. data/lib/calabash-cucumber/resources/pinch_in_ios6_iphone.base64 +0 -70
  58. data/lib/calabash-cucumber/resources/pinch_out_ios5_ipad.base64 +0 -207
  59. data/lib/calabash-cucumber/resources/pinch_out_ios5_iphone.base64 +0 -207
  60. data/lib/calabash-cucumber/resources/pinch_out_ios6_ipad.base64 +0 -96
  61. data/lib/calabash-cucumber/resources/pinch_out_ios6_iphone.base64 +0 -96
  62. data/lib/calabash-cucumber/resources/rotate_left_home_down_ios4_ipad.base64 +0 -2
  63. data/lib/calabash-cucumber/resources/rotate_left_home_down_ios4_iphone.base64 +0 -2
  64. data/lib/calabash-cucumber/resources/rotate_left_home_down_ios5_ipad.base64 +0 -2
  65. data/lib/calabash-cucumber/resources/rotate_left_home_down_ios5_iphone.base64 +0 -2
  66. data/lib/calabash-cucumber/resources/rotate_left_home_left_ios4_ipad.base64 +0 -2
  67. data/lib/calabash-cucumber/resources/rotate_left_home_left_ios4_iphone.base64 +0 -2
  68. data/lib/calabash-cucumber/resources/rotate_left_home_left_ios5_ipad.base64 +0 -2
  69. data/lib/calabash-cucumber/resources/rotate_left_home_left_ios5_iphone.base64 +0 -2
  70. data/lib/calabash-cucumber/resources/rotate_left_home_right_ios4_ipad.base64 +0 -2
  71. data/lib/calabash-cucumber/resources/rotate_left_home_right_ios4_iphone.base64 +0 -2
  72. data/lib/calabash-cucumber/resources/rotate_left_home_right_ios5_ipad.base64 +0 -2
  73. data/lib/calabash-cucumber/resources/rotate_left_home_right_ios5_iphone.base64 +0 -2
  74. data/lib/calabash-cucumber/resources/rotate_left_home_up_ios4_ipad.base64 +0 -2
  75. data/lib/calabash-cucumber/resources/rotate_left_home_up_ios4_iphone.base64 +0 -2
  76. data/lib/calabash-cucumber/resources/rotate_left_home_up_ios5_ipad.base64 +0 -2
  77. data/lib/calabash-cucumber/resources/rotate_left_home_up_ios5_iphone.base64 +0 -2
  78. data/lib/calabash-cucumber/resources/rotate_right_home_down_ios4_ipad.base64 +0 -2
  79. data/lib/calabash-cucumber/resources/rotate_right_home_down_ios4_iphone.base64 +0 -2
  80. data/lib/calabash-cucumber/resources/rotate_right_home_down_ios5_ipad.base64 +0 -2
  81. data/lib/calabash-cucumber/resources/rotate_right_home_down_ios5_iphone.base64 +0 -2
  82. data/lib/calabash-cucumber/resources/rotate_right_home_left_ios4_ipad.base64 +0 -2
  83. data/lib/calabash-cucumber/resources/rotate_right_home_left_ios4_iphone.base64 +0 -2
  84. data/lib/calabash-cucumber/resources/rotate_right_home_left_ios5_ipad.base64 +0 -2
  85. data/lib/calabash-cucumber/resources/rotate_right_home_left_ios5_iphone.base64 +0 -2
  86. data/lib/calabash-cucumber/resources/rotate_right_home_right_ios4_ipad.base64 +0 -2
  87. data/lib/calabash-cucumber/resources/rotate_right_home_right_ios4_iphone.base64 +0 -2
  88. data/lib/calabash-cucumber/resources/rotate_right_home_right_ios5_ipad.base64 +0 -2
  89. data/lib/calabash-cucumber/resources/rotate_right_home_right_ios5_iphone.base64 +0 -2
  90. data/lib/calabash-cucumber/resources/rotate_right_home_up_ios4_ipad.base64 +0 -2
  91. data/lib/calabash-cucumber/resources/rotate_right_home_up_ios4_iphone.base64 +0 -2
  92. data/lib/calabash-cucumber/resources/rotate_right_home_up_ios5_ipad.base64 +0 -2
  93. data/lib/calabash-cucumber/resources/rotate_right_home_up_ios5_iphone.base64 +0 -2
  94. data/lib/calabash-cucumber/resources/swipe_down_ios5_ipad.base64 +0 -18
  95. data/lib/calabash-cucumber/resources/swipe_down_ios5_iphone.base64 +0 -31
  96. data/lib/calabash-cucumber/resources/swipe_down_ios6_ipad.base64 +0 -25
  97. data/lib/calabash-cucumber/resources/swipe_down_ios6_iphone.base64 +0 -25
  98. data/lib/calabash-cucumber/resources/swipe_left_hard_ios4_ipad.base64 +0 -15
  99. data/lib/calabash-cucumber/resources/swipe_left_hard_ios4_iphone.base64 +0 -15
  100. data/lib/calabash-cucumber/resources/swipe_left_ios4_ipad.base64 +0 -18
  101. data/lib/calabash-cucumber/resources/swipe_left_ios4_iphone.base64 +0 -18
  102. data/lib/calabash-cucumber/resources/swipe_left_ios5_ipad.base64 +0 -17
  103. data/lib/calabash-cucumber/resources/swipe_left_ios5_iphone.base64 +0 -34
  104. data/lib/calabash-cucumber/resources/swipe_left_ios6_ipad.base64 +0 -28
  105. data/lib/calabash-cucumber/resources/swipe_left_ios6_iphone.base64 +0 -28
  106. data/lib/calabash-cucumber/resources/swipe_right_hard_ios4_ipad.base64 +0 -17
  107. data/lib/calabash-cucumber/resources/swipe_right_hard_ios4_iphone.base64 +0 -17
  108. data/lib/calabash-cucumber/resources/swipe_right_ios4_ipad.base64 +0 -13
  109. data/lib/calabash-cucumber/resources/swipe_right_ios4_iphone.base64 +0 -13
  110. data/lib/calabash-cucumber/resources/swipe_right_ios5_ipad.base64 +0 -17
  111. data/lib/calabash-cucumber/resources/swipe_right_ios5_iphone.base64 +0 -17
  112. data/lib/calabash-cucumber/resources/swipe_right_ios6_ipad.base64 +0 -25
  113. data/lib/calabash-cucumber/resources/swipe_right_ios6_iphone.base64 +0 -25
  114. data/lib/calabash-cucumber/resources/swipe_up_ios5_ipad.base64 +0 -34
  115. data/lib/calabash-cucumber/resources/swipe_up_ios5_iphone.base64 +0 -28
  116. data/lib/calabash-cucumber/resources/swipe_up_ios6_ipad.base64 +0 -25
  117. data/lib/calabash-cucumber/resources/swipe_up_ios6_iphone.base64 +0 -25
  118. data/lib/calabash-cucumber/resources/touch_done_ios4_ipad.base64 +0 -7
  119. data/lib/calabash-cucumber/resources/touch_done_ios4_iphone.base64 +0 -9
  120. data/lib/calabash-cucumber/resources/touch_done_ios5_ipad.base64 +0 -7
  121. data/lib/calabash-cucumber/resources/touch_done_ios5_iphone.base64 +0 -9
  122. data/lib/calabash-cucumber/resources/touch_hold_ios5_ipad.base64 +0 -9
  123. data/lib/calabash-cucumber/resources/touch_hold_ios5_iphone.base64 +0 -9
  124. data/lib/calabash-cucumber/resources/touch_hold_ios6_ipad.base64 +0 -9
  125. data/lib/calabash-cucumber/resources/touch_hold_ios6_iphone.base64 +0 -9
  126. data/lib/calabash-cucumber/resources/touch_ios4_ipad.base64 +0 -9
  127. data/lib/calabash-cucumber/resources/touch_ios4_iphone.base64 +0 -9
  128. data/lib/calabash-cucumber/resources/touch_ios5_ipad.base64 +0 -9
  129. data/lib/calabash-cucumber/resources/touch_ios5_iphone.base64 +0 -9
  130. data/lib/calabash-cucumber/resources/touch_ios7_ipad.base64 +0 -9
  131. data/lib/calabash-cucumber/resources/touch_ios7_iphone.base64 +0 -9
  132. data/lib/calabash-cucumber/resources/wheel_down_ios4_ipad.base64 +0 -159
  133. data/lib/calabash-cucumber/resources/wheel_down_ios4_iphone.base64 +0 -159
  134. data/lib/calabash-cucumber/resources/wheel_down_ios5_ipad.base64 +0 -156
  135. data/lib/calabash-cucumber/resources/wheel_down_ios5_iphone.base64 +0 -156
  136. data/lib/calabash-cucumber/resources/wheel_up_ios4_ipad.base64 +0 -166
  137. data/lib/calabash-cucumber/resources/wheel_up_ios4_iphone.base64 +0 -166
  138. data/lib/calabash-cucumber/resources/wheel_up_ios5_ipad.base64 +0 -156
  139. data/lib/calabash-cucumber/resources/wheel_up_ios5_iphone.base64 +0 -156
  140. data/lib/calabash-cucumber/utils/logging.rb +0 -111
  141. data/lib/calabash-cucumber/utils/plist_buddy.rb +0 -45
  142. data/lib/calabash-cucumber/utils/simulator_accessibility.rb +0 -334
  143. data/lib/calabash-cucumber/utils/xctools.rb +0 -101
  144. data/scripts/.irbrc +0 -64
  145. data/scripts/launch.rb +0 -48
@@ -1,896 +1,513 @@
1
- require 'calabash-cucumber/launch/simulator_launcher'
2
- require 'calabash-cucumber/utils/simulator_accessibility'
3
- require 'sim_launcher'
4
- require 'calabash-cucumber/device'
5
- require 'calabash-cucumber/actions/instruments_actions'
6
- require 'calabash-cucumber/actions/playback_actions'
7
- require 'run_loop'
8
- require 'cfpropertylist'
9
- require 'calabash-cucumber/utils/logging'
10
- require "calabash-cucumber/usage_tracker"
11
-
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.
31
- class Calabash::Cucumber::Launcher
32
-
33
- require "calabash-cucumber/dylibs"
34
- require "calabash-cucumber/environment"
35
-
36
- include Calabash::Cucumber::Logging
37
- include Calabash::Cucumber::SimulatorAccessibility
38
-
39
- # noinspection RubyClassVariableUsageInspection
40
-
41
- # @!visibility private
42
- @@launcher = nil
43
-
44
- # @!visibility private
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.
51
- @@server_version = nil
52
-
53
- attr_accessor :run_loop
54
- attr_accessor :device
55
- attr_accessor :actions
56
- attr_accessor :launch_args
57
- attr_accessor :simulator_launcher
58
- attr_reader :xcode
59
- attr_reader :usage_tracker
60
-
61
- # @!visibility private
62
- # Generated when calabash cannot launch the app.
63
- class StartError < RuntimeError
64
- attr_accessor :error
65
-
66
- def initialize(err)
67
- self.error= err
68
- end
1
+ module Calabash
2
+ module Cucumber
69
3
 
70
- # @!visibility private
71
- def to_s
72
- "#{super.to_s}: #{error}"
73
- end
74
- end
4
+ # Raised when calabash cannot launch the app.
5
+ class LaunchError < RuntimeError
6
+ attr_accessor :error
75
7
 
76
- # @!visibility private
77
- # Generated when calabash cannot communicate with the app.
78
- class CalabashLauncherTimeoutErr < Timeout::Error
79
- end
8
+ def initialize(err)
9
+ self.error= err
10
+ end
80
11
 
81
- def xcode
82
- @xcode ||= RunLoop::Xcode.new
83
- end
12
+ # @!visibility private
13
+ def to_s
14
+ "#{super.to_s}: #{error}"
15
+ end
16
+ end
84
17
 
85
- def usage_tracker
86
- @usage_tracker ||= Calabash::Cucumber::UsageTracker.new
87
- end
18
+ # Raised when Calabash cannot find a device based on DEVICE_TARGET
19
+ class DeviceNotFoundError < RuntimeError ; end
20
+
21
+ # Launch apps on iOS Simulators and physical devices.
22
+ #
23
+ # ### Accessing the current launcher from ruby.
24
+ #
25
+ # If you need a reference to the current launcher in your ruby code.
26
+ #
27
+ # `Calabash::Cucumber::Launcher.launcher`
28
+ #
29
+ # This is usually not required, but might be useful in `support/01_launch.rb`.
30
+ #
31
+ # ### Attaching to the current launcher in a console
32
+ #
33
+ # If Calabash already running and you want to attach to the current launcher,
34
+ # use `console_attach`. This is useful when a cucumber Scenario has failed and
35
+ # you want to query the current state of the app.
36
+ #
37
+ # * **Pro Tip:** Set the `QUIT_APP_AFTER_SCENARIO=0` env variable so calabash
38
+ # does not quit your application after a failed Scenario.
39
+ class Launcher
40
+
41
+ require "calabash-cucumber/device"
42
+ require "calabash-cucumber/actions/instruments_actions"
43
+ require "calabash-cucumber/usage_tracker"
44
+ require "calabash-cucumber/dylibs"
45
+ require "calabash-cucumber/environment"
46
+ require "calabash-cucumber/http/http"
47
+ require "run_loop"
48
+
49
+ # @!visibility private
50
+ DEFAULTS = {
51
+ :launch_retries => 5
52
+ }
88
53
 
89
- # @!visibility private
90
- def initialize
91
- @simulator_launcher = Calabash::Cucumber::SimulatorLauncher.new
92
- @@launcher = self
93
- end
54
+ # @!visibility private
55
+ @@launcher = nil
94
56
 
95
- # @!visibility private
96
- def actions
97
- attach if @actions.nil?
98
- @actions
99
- end
57
+ # @!visibility private
58
+ @@launcher = nil
100
59
 
101
- # @see Calabash::Cucumber::Core#console_attach
102
- def self.attach
103
- l = launcher
104
- return l if l && l.active?
105
- l.attach
106
- end
60
+ # @!visibility private
61
+ attr_accessor :run_loop
107
62
 
108
- # @see Calabash::Cucumber::Core#console_attach
109
- def attach(options={})
110
- default_options = {:max_retry => 1,
111
- :timeout => 10}
112
- merged_options = default_options.merge(options)
63
+ # @!visibility private
64
+ attr_accessor :actions
113
65
 
114
- if calabash_no_launch?
115
- self.actions = Calabash::Cucumber::PlaybackActions.new
116
- return
117
- end
66
+ # @!visibility private
67
+ attr_accessor :launch_args
118
68
 
119
- self.run_loop = RunLoop::HostCache.default.read
69
+ # @!visibility private
70
+ attr_reader :usage_tracker
120
71
 
121
- # Sets the device attribute.
122
- ensure_connectivity(merged_options[:max_retry], merged_options[:timeout])
72
+ # @!visibility private
73
+ def initialize
74
+ @@launcher = self
75
+ end
123
76
 
124
- if self.run_loop[:pid]
125
- self.actions = Calabash::Cucumber::InstrumentsActions.new
126
- else
127
- self.actions = Calabash::Cucumber::PlaybackActions.new
128
- end
77
+ # @!visibility private
78
+ def to_s
79
+ msg = ["#{self.class}"]
80
+ if self.run_loop
81
+ msg << "Log file: #{self.run_loop[:log_file]}"
82
+ else
83
+ msg << "Not attached to instruments."
84
+ msg << "Start your app with `start_test_server_in_background`"
85
+ msg << "If you app is already running, try `console_attach`"
86
+ end
87
+ msg.join("\n")
88
+ end
129
89
 
130
- major = self.device.ios_major_version
131
- if major.to_i >= 7 && self.actions.is_a?(Calabash::Cucumber::PlaybackActions)
132
- puts %Q{
90
+ # @!visibility private
91
+ def inspect
92
+ to_s
93
+ end
133
94
 
134
- WARNING
95
+ # @!visibility private
96
+ #
97
+ # Use this method to see if your app is already running. This is helpful
98
+ # if you have Scenarios that don't require an app relaunch.
99
+ #
100
+ # @raise Raises an error if the server does not respond.
101
+ def ping_app
102
+ Calabash::Cucumber::HTTP.ping_app
103
+ end
135
104
 
136
- Connected to simulator that was not launched by Calabash.
105
+ # @!visibility private
106
+ #
107
+ # This Calabash::Cucumber::Device instance is required because we cannot
108
+ # determine the iOS version of physical devices.
109
+ #
110
+ # This device instance can only be created _if the server is running_.
111
+ #
112
+ # We need this instance because we need to know at runtime whether or
113
+ # not to translate touch coordinates in the client or on the server. For
114
+ # iOS >= 8.0 translation is done on the server. Further, we need a
115
+ # Device instance for iOS < 8 so we can perform the necessary
116
+ # coordinate normalization - based on the device attributes.
117
+ #
118
+ # We also need this instance to determine the default uia strategy.
119
+ #
120
+ # +1 for tools to ask physical devices about attributes.
121
+ def device
122
+ @device ||= lambda do
123
+ _, body = Calabash::Cucumber::HTTP.ensure_connectivity
124
+ endpoint = Calabash::Cucumber::Environment.device_endpoint
125
+ Calabash::Cucumber::Device.new(endpoint, body)
126
+ end.call
127
+ end
137
128
 
138
- Queries will work, but gestures will not.
129
+ # @!visibility private
130
+ #
131
+ # Legacy API. This is a required method. Do not remove
132
+ def device=(new_device)
133
+ @device = new_device
134
+ end
139
135
 
140
- }
141
- end
142
- self
143
- end
136
+ # @!visibility private
137
+ def usage_tracker
138
+ @usage_tracker ||= Calabash::Cucumber::UsageTracker.new
139
+ end
144
140
 
145
- # Are we running using instruments?
146
- #
147
- # @return {Boolean} true if we're using instruments to launch
148
- def self.instruments?
149
- l = launcher_if_used
150
- return false unless l
151
- l.instruments?
152
- end
141
+ # @!visibility private
142
+ def actions
143
+ attach if @actions.nil?
144
+ @actions
145
+ end
153
146
 
154
- # Get a reference to the current launcher (instantiates a new one if needed). Usually we use a singleton launcher throughout a test run.
155
- # @return {Calabash::Cucumber::Launcher} the current launcher
156
- def self.launcher
157
- @@launcher ||= Calabash::Cucumber::Launcher.new
158
- end
147
+ # @!visibility private
148
+ # @see Calabash::Cucumber::Core#console_attach
149
+ def self.attach
150
+ l = launcher
151
+ return l if l && l.active?
152
+ l.attach
153
+ end
159
154
 
160
- # Get a reference to the current launcher (does not instantiate a new one if unset).
161
- # Usually we use a singleton launcher throughout a test run.
162
- # @return {Calabash::Cucumber::Launcher} the current launcher or nil
163
- def self.launcher_if_used
164
- @@launcher
165
- end
155
+ # @!visibility private
156
+ # @see Calabash::Cucumber::Core#console_attach
157
+ def attach(options={})
158
+ if Calabash::Cucumber::Environment.xtc?
159
+ raise "This method is not available on the Xamarin Test Cloud"
160
+ end
166
161
 
167
- # "Major" component of the current iOS version of the device
168
- # @return {String} the "major" component, e.g., "7" for "7.1.1"
169
- def ios_major_version
170
- # pinging the app will set self.device
171
- ping_app if self.device.nil?
172
- # guard against Runtime errors
173
- return nil if device.nil? or device.ios_version.nil?
174
- device.ios_major_version
175
- end
162
+ default_options = {:http_connection_retry => 1,
163
+ :http_connection_timeout => 10}
164
+ merged_options = default_options.merge(options)
176
165
 
177
- # the current iOS version of the device
178
- # @return {String} the current iOS version of the device
179
- def ios_version
180
- return nil if device.nil?
181
- device.ios_version
182
- end
166
+ self.run_loop = RunLoop::HostCache.default.read
183
167
 
184
- # @deprecated 0.10.0 Replaced with {#reset_app_sandbox}.
185
- # Reset the app sandbox for a device.
186
- def reset_app_jail(sdk=nil, path=nil)
187
- # will be deprecated in a future version
188
- #_deprecated('0.10.0', 'use reset_app_sandbox instead', :warn)
189
- reset_app_sandbox({:sdk => sdk, :path => path})
190
- end
168
+ begin
169
+ Calabash::Cucumber::HTTP.ensure_connectivity(merged_options)
170
+ rescue Calabash::Cucumber::ServerNotRespondingError => _
171
+ device_endpoint = Calabash::Cucumber::Environment.device_endpoint
172
+ RunLoop.log_warn(
173
+ %Q[
191
174
 
192
- # Resets the app's content and settings by deleting the following directories
193
- # from application sandbox:
194
- #
195
- # * Library
196
- # * Documents
197
- # * tmp
198
- #
199
- # @note It is not recommended that you call this method directly. See the
200
- # examples below for how use the `RESET_BETWEEN_SCENARIOS` environmental
201
- # variable to reset the app sandbox.
202
- #
203
- # @note This method is only available for the iOS Simulator.
204
- #
205
- # @note Generates a warning if called when targeting a physical device and
206
- # otherwise has no effect.
207
- #
208
- # @note When testing against the Xamarin Test Cloud, this method is never
209
- # called. Use the `RESET_BETWEEN_SCENARIOS` environmental variable.
210
- # See the examples.
211
- #
212
- # @example Use `RESET_BETWEEN_SCENARIOS` to reset the app sandbox before every Scenario.
213
- # When testing devices outside the Xamarin Test Cloud this has no effect.
214
- #
215
- # On the Xamarin Test Cloud, the app sandbox will be reset, but this method
216
- # will not be called; the resetting is done via an alternative mechanism.
217
- #
218
- # When testing simulators, this method will be called.
219
- #
220
- # Launch cucumber with RESET_BETWEEN_SCENARIOS=1
221
- #
222
- # $ RESET_BETWEEN_SCENARIOS=1 bundle exec cucumber
223
- #
224
- # @example Use tags and a Before hook to reset the app sandbox before specific Scenarios.
225
- # # in your .feature file
226
- #
227
- # @reset_app_before_hook
228
- # Scenario: some scenario that requires the app be reset
229
- #
230
- # # in your support/01_launch.rb file
231
- # #
232
- # # 1. add a Before hook
233
- # Before('@reset_app_before_hook') do
234
- # ENV['RESET_BETWEEN_SCENARIOS'] = '1'
235
- # end
236
- #
237
- # # 2. after launching, revert the env var value
238
- # Before do |scenario|
239
- # # launch the app
240
- # launcher = Calabash::Cucumber::Launcher.new
241
- # unless launcher.calabash_no_launch?
242
- # launcher.relaunch
243
- # launcher.calabash_notify(self)
244
- # end
245
- # # disable resetting between Scenarios
246
- # ENV['RESET_BETWEEN_SCENARIOS'] = ''
247
- # end
248
- #
249
- # @param [Hash] opts can pass the target sdk or the path to the application bundle
250
- # @option opts [String, Symbol] :sdk (nil) The target sdk. If nil is
251
- # passed, then only app sandbox for the latest sdk will be deleted. If
252
- # `:all` is passed, then the sandboxes for all sdks will be deleted.
253
- # @option opts [String] :path (nil) path to the application bundle
254
- def reset_app_sandbox(opts={})
255
- calabash_warn(%Q{
256
- Starting in Calabash 0.17.0, this method does nothing.
257
-
258
- You can still control whether or not your app's sandbox is
259
- reset between Scenarios using RESET_BETWEEN_SCENARIOS=1 or
260
- by passing :reset => true as a launch option.
261
-
262
- options = {
263
- :reset => true
264
- }
175
+ Could not connect to Calabash Server @ #{device_endpoint}.
265
176
 
266
- launcher.relaunch(options)
177
+ If your app is running, check that you have set the DEVICE_ENDPOINT correctly.
267
178
 
268
- Please do not ignore this message.
179
+ If your app is not running, it was a mistake to call this method.
269
180
 
270
- Remove direct calls to reset_app_sandbox.
181
+ http://calabashapi.xamarin.com/ios/Calabash/Cucumber/Core.html#console_attach-instance_method
271
182
 
272
- })
273
- end
183
+ Try `start_test_server_in_background`
274
184
 
275
- # Erases a simulator. This is the same as touching the Simulator
276
- # "Reset Content & Settings" menu item.
277
- #
278
- # @param [RunLoop::Device, String] The simulator to erase. Can be a device
279
- # instance, a simulator UUID, or a human readable simulator name.
280
- #
281
- # @raise ArgumentError If the simulator is a physical device
282
- # @raise RuntimeError If the simulator cannot be shutdown
283
- # @raise RuntimeError If the simulator cannot be erased
284
- def reset_simulator(device=nil)
285
- if device_target?
286
- raise ArgumentError, "Resetting physical devices is not supported."
287
- end
185
+ ])
288
186
 
289
- simulator = nil
187
+ # Nothing to do except log the problem and exit early.
188
+ return false
189
+ end
290
190
 
291
- if device.nil? || device == ""
292
- device_target = Calabash::Cucumber::Environment.device_target
293
- if device_target.nil?
294
- default_simulator = RunLoop::Core.default_simulator
295
- simulator = RunLoop::Device.device_with_identifier(default_simulator)
296
- else
297
- simulator = RunLoop::Device.device_with_identifier(device_target)
298
- end
299
- elsif device.is_a?(RunLoop::Device)
300
- if device.physical_device?
301
- raise ArgumentError,
302
- %Q{
303
- Cannot reset: #{device}.
191
+ if self.run_loop[:pid]
192
+ self.actions = Calabash::Cucumber::InstrumentsActions.new
193
+ else
194
+ RunLoop.log_warn(
195
+ %Q[
304
196
 
305
- Resetting physical devices is not supported.
306
- }
307
- end
308
- simulator = device
309
- else
310
- simulator = RunLoop::Device.device_with_identifier(device)
311
- end
197
+ Connected to an app that was not launched by Calabash using instruments.
312
198
 
313
- RunLoop::CoreSimulator.erase(simulator)
314
- simulator
315
- end
199
+ Queries will work, but gestures will not.
316
200
 
317
- # @!visibility private
318
- def default_launch_args
319
- # APP_BUNDLE_PATH
320
- # BUNDLE_ID
321
- # APP (unifies APP_BUNDLE_PATH, BUNDLE_ID)
322
- # DEVICE_TARGET
323
- # SDK_VERSION
324
- # RESET_BETWEEN_SCENARIOS
325
- # DEVICE
326
- # NO_LAUNCH
327
- # NO_STOP
328
-
329
- args = {
330
- :launch_method => default_launch_method,
331
- :reset => reset_between_scenarios?,
332
- :bundle_id => ENV['BUNDLE_ID'],
333
- :no_stop => calabash_no_stop?,
334
- :no_launch => calabash_no_launch?,
335
- :sdk_version => sdk_version,
336
- :relaunch_simulator => true,
337
- # Do not advertise this to users!
338
- # For example, don't include documentation about this option.
339
- # This is used to instrument internal testing (failing fast).
340
- :launch_retries => 5
341
- }
342
-
343
- device_tgt = ENV['DEVICE_TARGET']
344
- if run_with_instruments?(args)
345
- if simulator_target?
346
- args[:device_target] = device_tgt
347
- args[:udid] = nil
348
- else
349
- if detect_connected_device? && (device_tgt.nil? || device_tgt.downcase == 'device')
350
- device_tgt = RunLoop::Core.detect_connected_device
201
+ ])
351
202
  end
352
203
 
353
- if device_tgt
354
- args[:device_target] = args[:udid] = device_tgt
355
- end
204
+ self
356
205
  end
357
- end
358
-
359
- if args[:device_target].nil?
360
- args[:device_target] = device_tgt || 'simulator'
361
- end
362
- args
363
- end
364
206
 
365
- # @!visibility private
366
- def detect_connected_device?
367
- if ENV['DETECT_CONNECTED_DEVICE'] == '1'
368
- return true
369
- end
370
-
371
- if ENV['BUNDLE_ID'].nil? && ENV['DETECT_CONNECTED_DEVICE'].nil?
372
- return false
373
- end
374
- if ENV['BUNDLE_ID'] && ENV['DETECT_CONNECTED_DEVICE'].nil?
375
- return true
376
- end
377
- if ENV['DETECT_CONNECTED_DEVICE']
378
- return ENV['DETECT_CONNECTED_DEVICE'] != '0'
379
- end
380
-
381
- return false
382
- end
383
-
384
- # @!visibility private
385
- def default_launch_method
386
- sdk = sdk_version
387
- major = nil
388
- if sdk && !sdk.strip.empty?
389
- major = sdk.split('.')[0]
390
- begin
391
- major = major.to_i
392
- rescue
393
- calabash_warn("SDK_VERSION invalid #{sdk_version} - ignoring...")
207
+ # Are we running using instruments?
208
+ #
209
+ # @return {Boolean} true if we're using instruments to launch
210
+ def self.instruments?
211
+ l = launcher_if_used
212
+ return false unless l
213
+ l.instruments?
394
214
  end
395
- end
396
- return :instruments if major && major >= 7 # Only instruments supported for iOS7+
397
- return :sim_launcher if major # and then we have <= 6
398
-
399
- if RunLoop::Xcode.new.version_gte_51?
400
- return use_sim_launcher_env? ? :sim_launcher : :instruments
401
- end
402
215
 
403
- available = self.simulator_launcher.sdk_detector.available_sdk_versions.reject { |v| v.start_with?('7') }
404
- if available.include?(sdk_version)
405
- :sim_launcher
406
- else
407
- :instruments
408
- end
409
- end
410
-
411
- # Launches your app on the connected device or simulator.
412
- #
413
- # `relaunch` does a lot of error detection and handling to reliably start the
414
- # app and test. Instruments (particularly the cli) has stability issues which
415
- # we workaround by restarting the simulator process and checking that
416
- # UIAutomation is correctly attaching to your application.
417
- #
418
- # Use the `args` parameter to to control:
419
- #
420
- # * `:app` - which app to launch.
421
- # * `:device_target` - simulator or device to target.
422
- # * `:reset_app_sandbox - reset he app's data (sandbox) before testing
423
- #
424
- # and many other behaviors.
425
- #
426
- # Many of these behaviors can be be controlled by environment variables. The
427
- # most important environment variables are `APP`, `DEVICE_TARGET`, and
428
- # `DEVICE_ENDPOINT`.
429
- #
430
- # @param {Hash} args optional arguments to control the how the app is launched
431
- def relaunch(args={})
432
-
433
- # @todo Don't overwrite the _args_ parameter!
434
- args = default_launch_args.merge(args)
435
-
436
- # RunLoop::Core.run_with_options can reuse the SimControl instance. Many
437
- # of the Xcode tool calls, like instruments -s templates, take a long time
438
- # to execute.
439
- # @todo Use SimControl in Launcher in place of methods like simulator_target?
440
- args[:sim_control] = RunLoop::SimControl.new
441
- args[:instruments] = RunLoop::Instruments.new
442
- args[:xcode] = xcode
443
-
444
- if args[:app]
445
- if !File.exist?(args[:app])
446
- raise "Unable to find app bundle at #{args[:app]}. It should be an iOS Simulator build (typically a *.app directory)."
216
+ # @!visibility private
217
+ def instruments?
218
+ !!(active? && run_loop[:pid])
447
219
  end
448
- end
449
220
 
450
- # User passed {:app => "path/to/my.app"} _and_ it exists.
451
- # User defined BUNDLE_ID or passed {:bundle_id => com.example.myapp}
452
- # User defined APP or APP_BUNDLE_PATH env vars _or_ APP_BUNDLE_PATH constant.
453
- args[:app] = args[:app] || args[:bundle_id] || app_path
454
-
455
- if args[:app]
456
- if File.directory?(args[:app])
457
- args[:app] = File.expand_path(args[:app])
458
- else
459
- # args[:app] is not a directory so must be a bundle id.
460
- if simulator_target?(args)
461
- args[:app] = app_path
462
- end
221
+ # @!visibility private
222
+ def active?
223
+ not run_loop.nil?
463
224
  end
464
- end
465
225
 
466
- # At this point :app is either nil because we are targeting a simulator
467
- # or it is a CFBundleIdentifier.
468
- if args[:app]
469
- # nothing to do because :bundle_id and :app are the same.
470
- else
471
- # User gave us no information about where the simulator app is located
472
- # so we have to auto detect it. This RunLoop method raises an error
473
- # with a meaningful message based on the environment. The message
474
- # includes suggestions about what to do next.
475
- run_loop_app = RunLoop::DetectAUT::Detect.new.app_for_simulator
476
-
477
- # This is not great - RunLoop is going to take this path and create a new
478
- # RunLoop::App. This is the best we can do for now.
479
- args[:app] = run_loop_app.path
480
- args[:bundle_id] = run_loop_app.bundle_identifier
481
- end
482
-
483
- use_dylib = args[:inject_dylib]
484
- if use_dylib
485
- # User passed a Boolean, not a file.
486
- if use_dylib.is_a?(TrueClass)
487
- if simulator_target?(args)
488
- args[:inject_dylib] = Calabash::Cucumber::Dylibs.path_to_sim_dylib
489
- else
490
- raise RuntimeError, "Injecting a dylib is not supported when targetting a device"
491
- end
492
- else
493
- unless File.exist? use_dylib
494
- raise "Dylib does not exist at path: '#{use_dylib}'"
495
- end
226
+ # A reference to the current launcher (instantiates a new one if needed).
227
+ # @return {Calabash::Cucumber::Launcher} the current launcher
228
+ def self.launcher
229
+ @@launcher ||= Calabash::Cucumber::Launcher.new
496
230
  end
497
- end
498
-
499
- if run_with_instruments?(args)
500
- # Patch for bug in Xcode 6 GM + iOS 8 device testing.
501
- # http://openradar.appspot.com/radar?id=5891145586442240
502
- uia_strategy = default_uia_strategy(args, args[:sim_control], args[:instruments])
503
- args[:uia_strategy] ||= uia_strategy
504
- calabash_info "Using uia strategy: '#{args[:uia_strategy]}'" if debug_logging?
505
-
506
- self.run_loop = new_run_loop(args)
507
- self.actions= Calabash::Cucumber::InstrumentsActions.new
508
- else
509
- # run with sim launcher
510
- self.actions= Calabash::Cucumber::PlaybackActions.new
511
- # why not just pass args - AFAICT args[:app] == app_path?
512
- self.simulator_launcher.relaunch(app_path, sdk_version(), args)
513
- end
514
- self.launch_args = args
515
231
 
516
- unless args[:calabash_lite]
517
- ensure_connectivity
518
- # skip compatibility check if injecting dylib
519
- unless args.fetch(:inject_dylib, false)
520
- check_server_gem_compatibility
232
+ # Get a reference to the current launcher (does not instantiate a new one if unset).
233
+ # @return {Calabash::Cucumber::Launcher} the current launcher or nil
234
+ def self.launcher_if_used
235
+ @@launcher
521
236
  end
522
- end
523
-
524
- usage_tracker.post_usage_async
525
- end
526
237
 
527
- # @!visibility private
528
- #
529
- # Choose the appropriate default UIA strategy based on the test target.
530
- #
531
- # This is a temporary (I hope) fix for a UIAApplication bug in
532
- # setPreferencesValueForKey on iOS 8 devices in Xcode 6 GM.
533
- #
534
- # rdar://18296714
535
- # http://openradar.appspot.com/radar?id=5891145586442240
536
- #
537
- # @param [Hash] launch_args The launch arguments.
538
- # @param [RunLoop::SimControl] sim_control Used to find simulators.
539
- # @param [RunLoop::Instruments] instruments Used to find physical devices.
540
- def default_uia_strategy(launch_args, sim_control, instruments)
541
-
542
- xcode = sim_control.xcode
543
- if xcode.version_gte_7?
544
- :host
545
- else
546
- udid_or_name = launch_args[:device_target]
547
-
548
- # Can't make a determination, so return :host because it works everywhere.
549
- return :host if udid_or_name == nil || udid_or_name == ''
550
-
551
- # The default.
552
- # No DEVICE_TARGET is set and no option was passed to relaunch.
553
- return :preferences if udid_or_name.downcase.include?('simulator')
554
-
555
- simulator = sim_control.simulators.find do |sim|
556
- sim.instruments_identifier(xcode) == udid_or_name ||
557
- sim.udid == udid_or_name
558
- end
559
-
560
- return :preferences if simulator
561
-
562
- physical_device = instruments.physical_devices.find do |device|
563
- device.name == udid_or_name ||
564
- device.udid == udid_or_name
565
- end
566
-
567
- if physical_device
568
- if physical_device.version < RunLoop::Version.new('8.0')
569
- :preferences
238
+ # Erases a simulator. This is the same as touching the Simulator
239
+ # "Reset Content & Settings" menu item.
240
+ #
241
+ # @param [RunLoop::Device, String] device The simulator to erase. Can be a
242
+ # RunLoop::Device instance, a simulator UUID, or a human readable simulator
243
+ # name.
244
+ #
245
+ # @raise ArgumentError If the simulator is a physical device
246
+ # @raise RuntimeError If the simulator cannot be shutdown
247
+ # @raise RuntimeError If the simulator cannot be erased
248
+ def reset_simulator(device=nil)
249
+ if device.is_a?(RunLoop::Device)
250
+ device_target = device
570
251
  else
571
- :host
252
+ device_target = detect_device(:device => device)
572
253
  end
573
- else
574
- # Return host because it works everywhere.
575
- :host
576
- end
577
- end
578
- end
579
-
580
- # @!visibility private
581
- def new_run_loop(args)
582
254
 
583
- last_err = nil
255
+ if device_target.physical_device?
256
+ raise ArgumentError,
257
+ %Q{
258
+ Cannot reset: #{device_target}.
584
259
 
585
- num_retries = args[:launch_retries] || 5
260
+ Resetting physical devices is not supported.
261
+ }
262
+ end
586
263
 
587
- num_retries.times do
588
- begin
589
- return RunLoop.run(args)
590
- rescue RunLoop::TimeoutError => e
591
- last_err = e
264
+ RunLoop::CoreSimulator.erase(device_target)
265
+ device_target
592
266
  end
593
- end
594
-
595
- if simulator_target?(args)
596
- puts "Unable to launch app on Simulator."
597
- else
598
- puts "Unable to launch app on physical device"
599
- end
600
- raise StartError.new(last_err)
601
- end
602
267
 
603
- # @!visibility private
604
- def ensure_connectivity(max_retry=10, timeout=30)
605
- begin
606
- max_retry_count = (ENV['MAX_CONNECT_RETRY'] || max_retry).to_i
607
- timeout = (ENV['CONNECT_TIMEOUT'] || timeout).to_i
608
- retry_count = 0
609
- connected = false
610
- if full_console_logging?
611
- puts 'Waiting for App to be ready'
612
- end
613
- until connected do
614
- if retry_count == max_retry_count
615
- raise "Timed out connecting to Calabash server after #{max_retry_count} retries. Make sure it is linked and App isn't crashing"
616
- end
617
- retry_count += 1
618
- begin
619
- Timeout::timeout(timeout, CalabashLauncherTimeoutErr) do
620
- until connected
621
- begin
622
- connected = (ping_app == '200')
623
- break if connected
624
- rescue StandardError => e
625
- if full_console_logging?
626
- puts "Could not connect. #{e.message}"
627
- puts "Will retry ..."
628
- end
629
- ensure
630
- sleep 1 unless connected
631
- end
632
- end
633
- end
634
- rescue CalabashLauncherTimeoutErr => e
635
- if full_console_logging?
636
- puts "Timed out after #{timeout} secs, trying to connect to Calabash server..."
637
- puts "Will retry #{max_retry_count - retry_count}"
638
- end
268
+ # Launches your app on the connected device or simulator.
269
+ #
270
+ # `relaunch` does a lot of error detection and handling to reliably start the
271
+ # app and test. Instruments (particularly the cli) has stability issues which
272
+ # we workaround by restarting the simulator process and checking that
273
+ # UIAutomation is correctly attaching to your application.
274
+ #
275
+ # Use the `args` parameter to to control:
276
+ #
277
+ # * `:app` - which app to launch.
278
+ # * `:device` - simulator or device to target.
279
+ # * `:reset_app_sandbox - reset the app's data (sandbox) before testing
280
+ #
281
+ # and many other behaviors.
282
+ #
283
+ # Many of these behaviors can be be controlled by environment variables. The
284
+ # most important environment variables are `APP`, `DEVICE_TARGET`, and
285
+ # `DEVICE_ENDPOINT`.
286
+ #
287
+ # @param {Hash} launch_options optional arguments to control the how the app is launched
288
+ def relaunch(launch_options={})
289
+ simctl = launch_options[:simctl] || launch_options[:sim_control]
290
+ instruments = launch_options[:instruments]
291
+ xcode = launch_options[:xcode]
292
+
293
+ options = launch_options.clone
294
+
295
+ # Reusing SimControl, Instruments, and Xcode can speed up launches.
296
+ options[:simctl] = simctl || Calabash::Cucumber::Environment.simctl
297
+ options[:instruments] = instruments || Calabash::Cucumber::Environment.instruments
298
+ options[:xcode] = xcode || Calabash::Cucumber::Environment.xcode
299
+
300
+ self.launch_args = options
301
+
302
+ self.run_loop = new_run_loop(options)
303
+ self.actions= Calabash::Cucumber::InstrumentsActions.new
304
+
305
+ if !options[:calabash_lite]
306
+ Calabash::Cucumber::HTTP.ensure_connectivity
307
+ check_server_gem_compatibility
639
308
  end
640
- end
641
- rescue RuntimeError => e
642
- p e
643
- msg = "Unable to make connection to Calabash Server at #{ENV['DEVICE_ENDPOINT']|| "http://localhost:37265/"}\n"
644
- msg << "Make sure you don't have a firewall blocking traffic to #{ENV['DEVICE_ENDPOINT']|| "http://localhost:37265/"}.\n"
645
- raise msg
646
- end
647
- end
648
-
649
- # @!visibility private
650
- def ping_app
651
- url = URI.parse(ENV['DEVICE_ENDPOINT']|| "http://localhost:37265/")
652
-
653
- http = Net::HTTP.new(url.host, url.port)
654
- res = http.start do |sess|
655
- sess.request Net::HTTP::Get.new(ENV['CALABASH_VERSION_PATH'] || "version")
656
- end
657
- status = res.code
658
309
 
659
- http.finish if http and http.started?
310
+ usage_tracker.post_usage_async
660
311
 
661
- if status == '200'
662
- version_body = JSON.parse(res.body)
663
- self.device = Calabash::Cucumber::Device.new(url, version_body)
664
- end
665
-
666
- status
667
- end
668
-
669
- # @!visibility private
670
- def stop
671
- RunLoop.stop(run_loop) if run_loop && run_loop[:pid]
672
- end
312
+ # :on_launch to the Cucumber World if:
313
+ # * the Launcher is part of the World (it is not by default).
314
+ # * Cucumber responds to :on_launch.
315
+ self.send(:on_launch) if self.respond_to?(:on_launch)
673
316
 
674
- # @!visibility private
675
- def calabash_notify(world)
676
- if world.respond_to?(:on_launch)
677
- world.on_launch
678
- end
679
- end
680
-
681
- # @!visibility private
682
- def calabash_no_stop?
683
- calabash_no_launch? or ENV['NO_STOP']=="1"
684
- end
685
-
686
- # @!visibility private
687
- def calabash_no_launch?
688
- ENV['NO_LAUNCH']=='1'
689
- end
690
-
691
- # @!visibility private
692
- def device_target?
693
- (ENV['DEVICE_TARGET'] != nil) && (not simulator_target?)
694
- end
695
-
696
- # @!visibility private
697
- def discover_device_target(launch_args)
698
- ENV['DEVICE_TARGET'] || launch_args[:device_target]
699
- end
700
-
701
- # @!visibility private
702
- def simulator_target?(launch_args={})
703
- udid_or_name = discover_device_target(launch_args)
704
-
705
- return false if udid_or_name.nil? || udid_or_name == ''
706
-
707
- return true if udid_or_name.downcase.include?('simulator')
708
-
709
- return false if udid_or_name[RunLoop::Regex::DEVICE_UDID_REGEX, 0] != nil
710
-
711
- if xcode.version_gte_6?
712
- sim_control = launch_args[:sim_control] || RunLoop::SimControl.new
713
- simulator = sim_control.simulators.find do |sim|
714
- sim.instruments_identifier(xcode) == udid_or_name ||
715
- sim.udid == udid_or_name
317
+ self
716
318
  end
717
319
 
718
- !simulator.nil?
719
- else
720
- false
721
- end
722
- end
723
-
724
- # @!visibility private
725
- def sdk_version
726
- ENV['SDK_VERSION']
727
- end
320
+ # @!visibility private
321
+ def new_run_loop(args)
322
+ last_err = nil
323
+ num_retries = args[:launch_retries] || DEFAULTS[:launch_retries]
324
+ num_retries.times do
325
+ begin
326
+ return RunLoop.run(args)
327
+ rescue RunLoop::TimeoutError => e
328
+ last_err = e
329
+ end
330
+ end
728
331
 
729
- # @!visibility private
730
- def sdk_version_for_simulator_target(launch_args)
731
- return nil if device_target?
732
- value = launch_args[:device_target]
733
- return nil if value.nil?
734
- return nil unless value.downcase.include?('simulator')
735
- # we have a string like:
736
- # iPhone Retina (4-inch) - Simulator - iOS 7.1
737
- # iPad Retina - Simulator - iOS 6.1
738
- # iPhone Retina (4-inch 64-bit) - Simulator - iOS 7.0
739
- sdk = value.split(' ').last
740
-
741
- # legacy support for DEVICE_TARGET=simulator
742
- return nil if sdk == 'simulator'
743
- sdk
744
- end
332
+ raise Calabash::Cucumber::LaunchError.new(last_err)
333
+ end
745
334
 
746
- # @!visibility private
747
- def use_instruments_env?
748
- ENV['LAUNCH_VIA'] == 'instruments'
749
- end
335
+ # @!visibility private
336
+ # TODO Should call calabash exit route to shutdown the server.
337
+ def stop
338
+ RunLoop.stop(run_loop) if run_loop && run_loop[:pid]
339
+ end
750
340
 
751
- # @!visibility private
752
- def use_sim_launcher_env?
753
- ENV['LAUNCH_VIA'] == 'sim_launcher'
754
- end
341
+ # Should Calabash quit the app under test after a Scenario?
342
+ #
343
+ # Control this behavior using the QUIT_APP_AFTER_SCENARIO variable.
344
+ #
345
+ # The default behavior is to quit after every Scenario.
346
+ def quit_app_after_scenario?
347
+ Calabash::Cucumber::Environment.quit_app_after_scenario?
348
+ end
755
349
 
756
- # @!visibility private
757
- def reset_between_scenarios?
758
- ENV['RESET_BETWEEN_SCENARIOS']=="1"
759
- end
350
+ # @!visibility private
351
+ # Checks the server and gem version compatibility and generates a warning if
352
+ # the server and gem are not compatible.
353
+ #
354
+ # @note This is a proof-of-concept implementation and requires _strict_
355
+ # equality. in the future we should allow minimum framework compatibility.
356
+ #
357
+ # @return [nil] nothing to return
358
+ def check_server_gem_compatibility
359
+ # Only check once.
360
+ return server_version if server_version
361
+
362
+ version_string = self.device.server_version
363
+
364
+ @server_version = RunLoop::Version.new(version_string)
365
+ gem_version = RunLoop::Version.new(Calabash::Cucumber::VERSION)
366
+ min_server_version = RunLoop::Version.new(Calabash::Cucumber::MIN_SERVER_VERSION)
367
+
368
+ if @server_version < min_server_version
369
+ msgs = [
370
+ "The server version is not compatible with gem version.",
371
+ "Please update your server.",
372
+ "https://github.com/calabash/calabash-ios/wiki/Updating-your-Calabash-iOS-version",
373
+ " gem version: '#{gem_version}'",
374
+ "min server version: '#{min_server_version}'",
375
+ " server version: '#{@server_version}'"]
376
+ RunLoop.log_warn("#{msgs.join("\n")}")
377
+ end
378
+ @server_version
379
+ end
760
380
 
761
- # @!visibility private
762
- def app_path
763
- RunLoop::Environment.path_to_app_bundle || (defined?(APP_BUNDLE_PATH) && APP_BUNDLE_PATH)
764
- end
381
+ # @deprecated 0.19.0 - replaced with #quit_app_after_scenario?
382
+ # @!visibility private
383
+ def calabash_no_stop?
384
+ # Not yet. Save for 0.20.0.
385
+ # RunLoop.deprecated("0.19.0", "replaced with quit_app_after_scenario")
386
+ !quit_app_after_scenario?
387
+ end
765
388
 
766
- # @!visibility private
767
- def run_with_instruments?(args)
768
- args && args[:launch_method] == :instruments
769
- end
389
+ # @!visibility private
390
+ # @deprecated 0.19.0 - no replacement
391
+ def calabash_no_launch?
392
+ RunLoop.log_warn(%Q[
393
+ Calabash::Cucumber::Launcher #calabash_no_launch? and support for the NO_LAUNCH
394
+ environment variable has been removed from Calabash. This always returns
395
+ true. Please remove this method call from your hooks.
396
+ ])
397
+ false
398
+ end
770
399
 
771
- # @!visibility private
772
- def active?
773
- not run_loop.nil?
774
- end
400
+ # @!visibility private
401
+ # @deprecated 0.19.0 - no replacement.
402
+ def default_uia_strategy(launch_args, sim_control, instruments)
403
+ RunLoop::deprecated("0.19.0", "This method has been removed.")
404
+ :host
405
+ end
775
406
 
776
- # @!visibility private
777
- def instruments?
778
- !!(active? && run_loop[:pid])
779
- end
407
+ # @!visibility private
408
+ # @deprecated 0.19.0 - no replacement
409
+ def detect_connected_device?
410
+ RunLoop.deprecated("0.19.0", "No replacement")
411
+ false
412
+ end
780
413
 
781
- # @!visibility private
782
- def inspect
783
- msg = ["#{self.class}: Launch Method #{launch_args && launch_args[:launch_method]}"]
784
- if run_with_instruments?(self.launch_args) && self.run_loop
785
- msg << "Log file: #{self.run_loop[:log_file]}"
786
- end
787
- msg.join("\n")
788
- end
414
+ # @!visibility private
415
+ # @deprecated 0.19.0 - no replacement
416
+ def default_launch_args
417
+ RunLoop.deprecated("0.19.0", "No replacement")
418
+ {}
419
+ end
789
420
 
790
- # @!visibility private
791
- # Extracts server version from the app binary at `app_bundle_path` by
792
- # inspecting the binary's strings table.
793
- #
794
- # @note
795
- # SPECIAL: sets the `@@server_version` class variable to cache the server
796
- # version because the server version will never change during runtime.
797
- #
798
- # @return [String] the server version
799
- # @param [String] app_bundle_path file path (usually) to the application bundle
800
- # @raise [RuntimeError] if there is no executable at `app_bundle_path`
801
- # @raise [RuntimeError] if the server version cannot be extracted from any
802
- # binary at `app_bundle_path`
803
- def server_version_from_bundle(app_bundle_path)
804
- return @@server_version unless @@server_version.nil?
805
- exe_paths = []
806
- Dir.foreach(app_bundle_path) do |item|
807
- next if item == '.' or item == '..'
808
-
809
- full_path = File.join(app_bundle_path, item)
810
- if File.executable?(full_path) and not File.directory?(full_path)
811
- exe_paths << full_path
421
+ # @!visibility private
422
+ # @deprecated 0.19.0 - no replacement
423
+ def discover_device_target(launch_args)
424
+ RunLoop.deprecated("0.19.0", "No replacement")
425
+ nil
812
426
  end
813
- end
814
427
 
815
- if exe_paths.empty?
816
- calabash_warn "could not find executable in '#{app_bundle_path}'"
428
+ # @!visibility private
429
+ # @deprecated 0.19.0 - no replacement
430
+ def device_target?(options={})
431
+ RunLoop.deprecated("0.19.0", "No replacement")
432
+ detect_device(options).physical_device?
433
+ end
817
434
 
818
- @@server_version = SERVER_VERSION_NOT_AVAILABLE
819
- return @@server_version
820
- end
435
+ # @!visibility private
436
+ # @deprecated 0.19.0 - no replacement
437
+ def simulator_target?(options={})
438
+ RunLoop.deprecated("0.19.0", "No replacement")
439
+ detect_device(options).simulator?
440
+ end
821
441
 
822
- server_version = nil
823
- exe_paths.each do |path|
824
- server_version_string = `xcrun strings "#{path}" | grep -E 'CALABASH VERSION'`.chomp!
825
- if server_version_string
826
- server_version = server_version_string.split(' ').last
827
- break
442
+ # @!visibility private
443
+ # @deprecated 0.19.0 - no replacement
444
+ def app_path
445
+ RunLoop.deprecated("0.19.0", "No replacement")
446
+ nil
828
447
  end
829
- end
830
448
 
831
- unless server_version
832
- calabash_warn('could not find server version by inspecting the binary strings table')
449
+ # @!visibility private
450
+ # @deprecated 0.19.0 - no replacement
451
+ def xcode
452
+ RunLoop.deprecated("0.19.0", "Use Calabash::Cucumber::Environment.xcode")
453
+ Calabash::Cucumber::Environment.xcode
454
+ end
833
455
 
834
- @@server_version = SERVER_VERSION_NOT_AVAILABLE
835
- return @@server_version
836
- end
456
+ # @!visibility private
457
+ # @deprecated 0.19.0 - no replacement
458
+ def ensure_connectivity
459
+ RunLoop.deprecated("0.19.0", "No replacement")
460
+ Calabash::Cucumber::HTTP.ensure_connectivity
461
+ end
837
462
 
838
- @@server_version = server_version
839
- end
463
+ # @!visibility private
464
+ # @deprecated 0.19.0 - no replacement - this method is a no op
465
+ #
466
+ # #relaunch will now send ":on_launch" to the Cucumber World if:
467
+ # * the Launcher is part of the World (it is not by default).
468
+ # * Cucumber responds to :on_launch.
469
+ def calabash_notify(_)
470
+ false
471
+ end
840
472
 
841
- # queries the server for its version.
842
- #
843
- # SPECIAL: sets the +@@server_version+ class variable to cache the server
844
- # version because the server version will never change during runtime.
845
- #
846
- # @return [String] the server version
847
- # @raise [RuntimeError] if the server cannot be reached
848
- def server_version_from_server
849
- return @@server_version unless @@server_version.nil?
850
- ensure_connectivity if self.device == nil
851
- @@server_version = self.device.server_version
852
- end
473
+ # @!visibility private
474
+ # @deprecated 0.19.0 - no replacement.
475
+ def server_version_from_server
476
+ RunLoop.deprecated("0.19.0", "No replacement")
477
+ server_version
478
+ end
853
479
 
854
- # @!visibility private
855
- # Checks the server and gem version compatibility and generates a warning if
856
- # the server and gem are not compatible.
857
- #
858
- # @note This is a proof-of-concept implementation and requires _strict_
859
- # equality. in the future we should allow minimum framework compatibility.
860
- #
861
- # @return [nil] nothing to return
862
- def check_server_gem_compatibility
863
- app_bundle_path = self.launch_args[:app]
864
- if File.directory?(app_bundle_path)
865
- server_version = server_version_from_bundle(app_bundle_path)
866
- else
867
- server_version = server_version_from_server
868
- end
480
+ # @!visibility private
481
+ # @deprecated 0.19.0 - no replacement
482
+ def server_version_from_bundle(app_bundle_path)
483
+ RunLoop.deprecated("0.19.0", "No replacement")
484
+ options = {:app => app_bundle_path }
485
+ app_details = RunLoop::DetectAUT.detect_app_under_test(options)
486
+ app = app_details[:app]
869
487
 
870
- if server_version == SERVER_VERSION_NOT_AVAILABLE
871
- calabash_warn('server version could not be found - skipping compatibility check')
872
- return nil
873
- end
488
+ if app.respond_to?(:calabash_server_version)
489
+ app.calabash_server_version
490
+ else
491
+ nil
492
+ end
493
+ end
874
494
 
875
- server_version = RunLoop::Version.new(server_version)
876
- gem_version = RunLoop::Version.new(Calabash::Cucumber::VERSION)
877
- min_server_version = RunLoop::Version.new(Calabash::Cucumber::MIN_SERVER_VERSION)
495
+ private
878
496
 
879
- if server_version < min_server_version
880
- msgs = [
881
- 'The server version is not compatible with gem version.',
882
- 'Please update your server.',
883
- 'https://github.com/calabash/calabash-ios/wiki/Updating-your-Calabash-iOS-version',
884
- " gem version: '#{gem_version}'",
885
- "min server version: '#{min_server_version}'",
886
- " server version: '#{server_version}'"]
887
- calabash_warn("#{msgs.join("\n")}")
888
- else
889
- if full_console_logging?
890
- calabash_info("gem #{gem_version} is compat with '#{server_version}'")
497
+ # @!visibility private
498
+ #
499
+ # A convenience wrapper around RunLoop::Device.detect_device
500
+ def detect_device(options)
501
+ xcode = Calabash::Cucumber::Environment.xcode
502
+ simctl = Calabash::Cucumber::Environment.simctl
503
+ instruments = Calabash::Cucumber::Environment.instruments
504
+ RunLoop::Device.detect_device(options, xcode, simctl, instruments)
891
505
  end
506
+
507
+ # The version of the embedded LPServer
508
+ # @return RunLoop::Version
509
+ attr_reader :server_version
892
510
  end
893
- nil
894
511
  end
895
-
896
512
  end
513
+