calabash-cucumber 0.9.169.pre2 → 0.9.169.pre5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +14 -1
  3. data/bin/calabash-ios-setup.rb +2 -4
  4. data/bin/calabash-ios-sim.rb +10 -40
  5. data/calabash-cucumber.gemspec +25 -22
  6. data/features-skeleton/support/01_launch.rb +1 -1
  7. data/lib/calabash-cucumber.rb +13 -1
  8. data/lib/calabash-cucumber/actions/instruments_actions.rb +0 -4
  9. data/lib/calabash-cucumber/actions/playback_actions.rb +0 -4
  10. data/lib/calabash-cucumber/core.rb +9 -16
  11. data/lib/calabash-cucumber/device.rb +11 -2
  12. data/lib/calabash-cucumber/environment_helpers.rb +4 -56
  13. data/lib/calabash-cucumber/ios7_operations.rb +4 -2
  14. data/lib/calabash-cucumber/keyboard_helpers.rb +6 -3
  15. data/lib/calabash-cucumber/launch/simulator_helper.rb +40 -386
  16. data/lib/calabash-cucumber/launch/simulator_launcher.rb +534 -0
  17. data/lib/calabash-cucumber/launcher.rb +172 -36
  18. data/lib/calabash-cucumber/operations.rb +3 -4
  19. data/lib/calabash-cucumber/playback_helpers.rb +15 -29
  20. data/lib/calabash-cucumber/rotation_helpers.rb +14 -10
  21. data/lib/calabash-cucumber/status_bar_helpers.rb +5 -1
  22. data/lib/calabash-cucumber/uia.rb +6 -12
  23. data/lib/calabash-cucumber/utils/logging.rb +97 -0
  24. data/lib/calabash-cucumber/utils/plist_buddy.rb +178 -0
  25. data/lib/calabash-cucumber/utils/simulator_accessibility.rb +250 -0
  26. data/lib/calabash-cucumber/utils/xctools.rb +95 -0
  27. data/lib/calabash-cucumber/version.rb +197 -2
  28. data/lib/calabash-cucumber/wait_helpers.rb +16 -20
  29. data/scripts/.irbrc +11 -6
  30. data/scripts/com.example.plist +0 -0
  31. data/scripts/launch.rb +1 -1
  32. data/spec/bin/calabash_ios_sim_spec.rb +24 -0
  33. data/spec/launcher_spec.rb +76 -0
  34. data/spec/logging_spec.rb +38 -0
  35. data/spec/plist_buddy_spec.rb +99 -0
  36. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/Default-568h@2x.png +0 -0
  37. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/Info.plist +0 -0
  38. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/LPSimpleExample-cal +0 -0
  39. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/PkgInfo +1 -0
  40. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/InfoPlist.strings +0 -0
  41. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPFirstViewController.nib +0 -0
  42. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPFirstViewController~ipad.nib +0 -0
  43. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPFourthViewController.nib +0 -0
  44. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPFourthViewController~ipad.nib +0 -0
  45. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPSecondViewController.nib +0 -0
  46. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPSecondViewController~ipad.nib +0 -0
  47. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPThirdViewController.nib +0 -0
  48. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/en.lproj/LPThirdViewController~ipad.nib +0 -0
  49. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/first.png +0 -0
  50. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/first@2x.png +0 -0
  51. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/second.png +0 -0
  52. data/spec/resources/enable-accessibility/LPSimpleExample-cal.app/second@2x.png +0 -0
  53. data/spec/resources/plist_buddy/com.example.plist +0 -0
  54. data/spec/resources/plist_buddy/com.testing.plist +18 -0
  55. data/spec/simulator_accessibility_spec.rb +144 -0
  56. data/spec/spec_helper.rb +31 -0
  57. data/spec/xctools_spec.rb +58 -0
  58. metadata +120 -34
@@ -0,0 +1,534 @@
1
+ require 'sim_launcher'
2
+ require 'json'
3
+ require 'net/http'
4
+ require 'cfpropertylist'
5
+ require 'calabash-cucumber/utils/logging'
6
+
7
+ module Calabash
8
+ module Cucumber
9
+
10
+ # acts as a bridge to the sim_launcher SimLauncher and SdkDetector classes
11
+ class SimulatorLauncher
12
+ include Calabash::Cucumber::Logging
13
+
14
+ # custom error indicating a timeout in launching and connecting to the
15
+ # embedded calabash server
16
+ # todo is duplicated in Launcher class - consider exceptions.rb module
17
+ class TimeoutErr < RuntimeError
18
+ end
19
+
20
+ # the file path to the default Xcode DerivedData directory
21
+ DERIVED_DATA = File.expand_path('~/Library/Developer/Xcode/DerivedData')
22
+
23
+ # REGEX for finding application Info.plist
24
+ DEFAULT_DERIVED_DATA_INFO = File.expand_path("#{DERIVED_DATA}/*/info.plist")
25
+
26
+ # if CONNECT_TIMEOUT is not set, wait this long for the app to launch
27
+ # in the simulator before retrying
28
+ DEFAULT_SIM_WAIT = 30
29
+
30
+ # if MAX_CONNECT_RETRY is not set, try to launch the app this many times
31
+ # in the simulator before giving up
32
+ DEFAULT_SIM_RETRY = 2
33
+
34
+ # an instance of Calabash::Cucumber::Device
35
+ attr_accessor :device
36
+
37
+ # an instance of SimLauncher::Simulator
38
+ attr_accessor :simulator
39
+
40
+ # an instance of SimLauncher::SdkDetector
41
+ attr_accessor :sdk_detector
42
+
43
+ # the launch args passed from Calabash::Cucumber::Launcher to the
44
+ # launch and relaunch methods.
45
+ attr_accessor :launch_args
46
+
47
+ # creates a new instance an sets the :simulator and :sdk_detector attributes
48
+ def initialize
49
+ @simulator = SimLauncher::Simulator.new
50
+ @sdk_detector = SimLauncher::SdkDetector.new()
51
+ end
52
+
53
+ # uses heuristics to deduce the derived data directory for the project
54
+ # so the path to the app bundle (.app) can be detected.
55
+ # @return [String] absolute path to derived data directory
56
+ # @raise [RuntimeError] if the derived data directory cannot be found
57
+ def derived_data_dir_for_project
58
+ dir = project_dir
59
+ xcode_workspace_name = ''
60
+ info_plist = Dir.glob(DEFAULT_DERIVED_DATA_INFO).find { |plist_file|
61
+ begin
62
+ plist = CFPropertyList::List.new(:file => plist_file)
63
+ hash = CFPropertyList.native_types(plist.value)
64
+ ws_dir = File.dirname(hash['WorkspacePath']).downcase
65
+ p_dir = dir.downcase
66
+ if p_dir.include? ws_dir
67
+ xcode_workspace_name = ws_dir.split('/').last
68
+ end
69
+ ws_dir == p_dir
70
+ rescue
71
+ false
72
+ end
73
+ }
74
+
75
+ return File.dirname(info_plist) unless info_plist.nil?
76
+
77
+ res = Dir.glob("#{dir}/*.xcodeproj")
78
+ if res.empty?
79
+ raise "Unable to find *.xcodeproj in #{dir}"
80
+ elsif res.count > 1
81
+ raise "Unable to found several *.xcodeproj in #{dir}: #{res}"
82
+ end
83
+
84
+ xcode_proj_name = res.first.split('.xcodeproj')[0]
85
+
86
+ xcode_proj_name = File.basename(xcode_proj_name)
87
+
88
+ build_dirs = Dir.glob("#{DERIVED_DATA}/*").find_all do |xc_proj|
89
+ File.basename(xc_proj).start_with?(xcode_proj_name)
90
+ end
91
+
92
+ if build_dirs.count == 0 && !xcode_workspace_name.empty?
93
+ # check for directory named "workspace-{deriveddirectoryrandomcharacters}"
94
+ build_dirs = Dir.glob("#{DERIVED_DATA}/*").find_all do |xc_proj|
95
+ File.basename(xc_proj).downcase.start_with?(xcode_workspace_name)
96
+ end
97
+ end
98
+
99
+ # todo analyze `derived_data_dir_for_project` to see if it contains dead code
100
+ # todo assuming this is not dead code, the documentation around derived data for project needs to be updated
101
+
102
+ if build_dirs.count == 0
103
+ msg = ['Unable to find your built app.']
104
+ msg << "This means that Calabash can't automatically launch iOS simulator."
105
+ msg << "Searched in Xcode 4.x default: #{DEFAULT_DERIVED_DATA_INFO}"
106
+ msg << ''
107
+ msg << "To fix there are a couple of options:\n"
108
+ msg << 'Option 1) Make sure you are running this command from your project directory, '
109
+ msg << 'i.e., the directory containing your .xcodeproj file.'
110
+ msg << 'In Xcode, build your calabash target for simulator.'
111
+ msg << "Check that your app can be found in\n #{DERIVED_DATA}"
112
+ msg << "\n\nOption 2). In features/support/01_launch.rb set APP_BUNDLE_PATH to"
113
+ msg << 'the path where Xcode has built your Calabash target.'
114
+ msg << "Alternatively you can use the environment variable APP_BUNDLE_PATH.\n"
115
+ raise msg.join("\n")
116
+
117
+ elsif build_dirs.count > 1
118
+ msg = ['Unable to auto detect APP_BUNDLE_PATH.']
119
+ msg << "You have several projects with the same name: #{xcode_proj_name} in #{DERIVED_DATA}:\n"
120
+ msg << build_dirs.join("\n")
121
+
122
+ msg << "\nThis means that Calabash can't automatically launch iOS simulator."
123
+ msg << "Searched in Xcode 4.x default: #{DEFAULT_DERIVED_DATA_INFO}"
124
+ msg << "\nIn features/support/01_launch.rb set APP_BUNDLE_PATH to"
125
+ msg << 'the path where Xcode has built your Calabash target.'
126
+ msg << "Alternatively you can use the environment variable APP_BUNDLE_PATH.\n"
127
+ raise msg.join("\n")
128
+ else
129
+ if full_console_logging?
130
+ puts "Found potential build dir: #{build_dirs.first}"
131
+ puts 'Checking...'
132
+ end
133
+ build_dirs.first
134
+ end
135
+ end
136
+
137
+ # returns the absolute path to the project directory
138
+ # unless PROJECT_DIR is defined, returns the absolute path to the current
139
+ # directory
140
+ # @return [String] absolute path to the project directory
141
+ # todo migrate PROJECT_DIR to environment_helpers.rb
142
+ def project_dir
143
+ File.expand_path(ENV['PROJECT_DIR'] || Dir.pwd)
144
+ end
145
+
146
+ # attempts to deduce the app bundle path
147
+ # @param [String] path NEEDS DOCUMENTATION
148
+ # @param [String] device_build_dir NEEDS DOCUMENTATION
149
+ # @return [String] absolute path to app bundle (.app)
150
+ # @return [nil] iff app bundle cannot be found
151
+ # todo methods should not use 2 optional arguments
152
+ def detect_app_bundle(path=nil,device_build_dir='iPhoneSimulator')
153
+ begin
154
+ app_bundle_or_raise(path,device_build_dir)
155
+ rescue
156
+ nil
157
+ end
158
+ end
159
+
160
+ # attempts to deduce the path the to the app bundle (.app)
161
+ # @param [String] path NEEDS DOCUMENTATION
162
+ # @param [String] device_build_dir NEEDS DOCUMENTATION
163
+ # @return [String] absolute path to app bundle (.app)
164
+ # @raise [RuntimeError] if app bundle (.app) cannot be found
165
+ # todo methods should not use 2 optional arguments
166
+ def app_bundle_or_raise(path=nil, device_build_dir='iPhoneSimulator')
167
+ path = File.expand_path(path) if path
168
+
169
+ if path and not File.directory?(path)
170
+ raise "Unable to find .app bundle at #{path}. It should be an .app directory."
171
+ elsif path
172
+ bundle_path = path
173
+ elsif xamarin_project?
174
+ bundle_path = bundle_path_from_xamarin_project(device_build_dir)
175
+ unless bundle_path
176
+ msg = ['Detected Xamarin project, but did not detect built app linked with Calabash']
177
+ msg << 'You should build your project from Xamarin Studio'
178
+ msg << "Make sure you build for Simulator and that you're using the Calabash components"
179
+ raise msg.join("\n")
180
+ end
181
+ if full_console_logging?
182
+ puts('-'*37)
183
+ puts "Auto detected APP_BUNDLE_PATH:\n\n"
184
+
185
+ puts "APP_BUNDLE_PATH= '#{bundle_path}'\n\n"
186
+ puts 'Please verify!'
187
+ puts "If this is wrong please set it as APP_BUNDLE_PATH in features/support/01_launch.rb\n"
188
+ puts('-'*37)
189
+ end
190
+ else
191
+ dd_dir = derived_data_dir_for_project
192
+ sim_dirs = Dir.glob(File.join(dd_dir, 'Build', 'Products', '*-iphonesimulator', '*.app'))
193
+ if sim_dirs.empty?
194
+ msg = ['Unable to auto detect APP_BUNDLE_PATH.']
195
+ msg << 'Have you built your app for simulator?'
196
+ msg << "Searched dir: #{dd_dir}/Build/Products"
197
+ msg << 'Please build your app from Xcode'
198
+ msg << 'You should build the -cal target.'
199
+ msg << ''
200
+ msg << 'Alternatively, specify APP_BUNDLE_PATH in features/support/01_launch.rb'
201
+ msg << "This should point to the location of your built app linked with calabash.\n"
202
+ raise msg.join("\n")
203
+ end
204
+ preferred_dir = find_preferred_dir(sim_dirs)
205
+ if preferred_dir.nil?
206
+ msg = ['Error... Unable to find APP_BUNDLE_PATH.']
207
+ msg << 'Cannot find a built app that is linked with calabash.framework'
208
+ msg << 'Please build your app from Xcode'
209
+ msg << 'You should build your calabash target.'
210
+ msg << ''
211
+ msg << 'Alternatively, specify APP_BUNDLE_PATH in features/support/01_launch.rb'
212
+ msg << "This should point to the location of your built app linked with calabash.\n"
213
+ raise msg.join("\n")
214
+ end
215
+ if full_console_logging?
216
+ puts('-'*37)
217
+ puts "Auto detected APP_BUNDLE_PATH:\n\n"
218
+
219
+ puts "APP_BUNDLE_PATH=#{preferred_dir || sim_dirs[0]}\n\n"
220
+ puts 'Please verify!'
221
+ puts "If this is wrong please set it as APP_BUNDLE_PATH in features/support/01_launch.rb\n"
222
+ puts('-'*37)
223
+ end
224
+ bundle_path = sim_dirs[0]
225
+ end
226
+ bundle_path
227
+ end
228
+
229
+ # is this a Xamarin IDE project?
230
+ # @return [Boolean] true iff the project is a Xamarin IDE project
231
+ def xamarin_project?
232
+ xamarin_ios_csproj_path != nil
233
+ end
234
+
235
+ # path to the Xamarin IDE project
236
+ # @return [String] absolute path to the Xamarin IDE project
237
+ def xamarin_ios_csproj_path
238
+ solution_path = Dir['*.sln'].first
239
+
240
+ project_dir = nil
241
+ if solution_path
242
+ project_dir = Dir.pwd
243
+ else
244
+ solution_path = Dir[File.join('..','*.sln')].first
245
+ if solution_path
246
+ project_dir = File.expand_path('..')
247
+ end
248
+ end
249
+
250
+ return nil unless project_dir
251
+
252
+ ios_project_dir = Dir[File.join(project_dir,'*.iOS')].first
253
+ return ios_project_dir if ios_project_dir && File.directory?(ios_project_dir)
254
+ # ios_project_dir does not exist
255
+ # Detect case where there is no such sub directory
256
+ # (i.e. iOS only Xamarin project)
257
+ bin_dir = File.join(project_dir, 'bin')
258
+ if xamarin_ios_bin_dir?(bin_dir)
259
+ return project_dir ## Looks like iOS bin dir is here
260
+ end
261
+
262
+ sub_dirs = Dir[File.join(project_dir,'*')].select {|dir| File.directory?(dir)}
263
+
264
+ sub_dirs.find do |sub_dir|
265
+ contains_csproj = Dir[File.join(sub_dir,'*.csproj')].first
266
+ contains_csproj && xamarin_ios_bin_dir?(File.join(sub_dir,'bin'))
267
+ end
268
+
269
+ end
270
+
271
+ # is this the Xamarin iOS bin directory?
272
+ # @return [Boolean] true iff this is the Xamarin iOS bin directory
273
+ def xamarin_ios_bin_dir?(bin_dir)
274
+ File.directory?(bin_dir) &&
275
+ (File.directory?(File.join(bin_dir,'iPhoneSimulator')) ||
276
+ File.directory?(File.join(bin_dir,'iPhone')))
277
+ end
278
+
279
+ # attempts to deduce the path to the app bundle path (*.app) using
280
+ # heuristics and checking for executables linked with the Calabash server
281
+ #
282
+ # @param [String] device_build_dir NEEDS DOCUMENTATION
283
+ # @return [String] absolute path the app bundle .app
284
+ # @return [nil] iff the app bundle cannot be found
285
+ def bundle_path_from_xamarin_project(device_build_dir='iPhoneSimulator')
286
+ ios_project_path = xamarin_ios_csproj_path
287
+ conf_glob = File.join(ios_project_path,'bin',device_build_dir,'*')
288
+ built_confs = Dir[conf_glob]
289
+
290
+ calabash_build = built_confs.find {|path| File.basename(path) == 'Calabash'}
291
+ debug_build = built_confs.find {|path| File.basename(path) == 'Debug'}
292
+
293
+ bundle_path = [calabash_build, debug_build, *built_confs].find do |path|
294
+ next unless path && File.directory?(path)
295
+ app_dir = Dir[File.join(path,'*.app')].first
296
+ app_dir && linked_with_calabash?(app_dir)
297
+ end
298
+
299
+ Dir[File.join(bundle_path,'*.app')].first if bundle_path
300
+ end
301
+
302
+ # searches +d+ for a file linked with Calabash server
303
+ # @param [String] d path to a directory
304
+ # @return [Boolean] true iff there is a file that is linked with the
305
+ # Calabash server
306
+ # todo why are we not grep'ing for executable files? see server_version_from_bundle
307
+ def linked_with_calabash?(d)
308
+ skipped_formats = ['.png', '.jpg', '.jpeg', '.plist', '.nib', '.lproj']
309
+ dir = File.expand_path(d)
310
+
311
+ # For every file on that .app directory
312
+ Dir.entries(d).each do |file|
313
+ # If this is an asset or any of those skipped formats, skip it.
314
+ next if skipped_formats.include? File.extname(file)
315
+
316
+ # If its not, try to run otool against that file, check whether we are linked against calabash framework.
317
+ out = `otool "#{dir}/#{file}" -o 2> /dev/null | grep CalabashServer`
318
+ return true if /CalabashServer/.match(out)
319
+ end
320
+
321
+ # Defaulted to false
322
+ false
323
+ end
324
+
325
+ # @return [String] the first path in +sim_dirs+ that contains a binary
326
+ # linked with Calabash server
327
+ # @return [nil] iff there is no path in +sim_dirs+ that contains a binary
328
+ # linked with Calabash server
329
+ # @param [Array<String>] sim_dirs eke! why sim_dirs? why not a list of any directories?
330
+ # todo find_preferred_dir is a bad name - preferred for what?
331
+ # todo sim_dirs arg is a bad name - we can be iterating over any directory
332
+ def find_preferred_dir(sim_dirs)
333
+ sim_dirs.find do |d|
334
+ linked_with_calabash?(d)
335
+ end
336
+ end
337
+
338
+
339
+ # ping the version route of the calabash server embedded in the app
340
+ #
341
+ # has the side effect of setting self.device attribute if successful
342
+ #
343
+ # @return [String] returns the server status - '200' is a success
344
+ # todo migrate DEVICE_ENDPOINT to environment_helpers
345
+ # todo migrate CALABASH_VERSION_PATH to environment_helpers
346
+ # todo this is an exact duplicate of Launcher ping method
347
+ def ping_app
348
+ url = URI.parse(ENV['DEVICE_ENDPOINT']|| 'http://localhost:37265/')
349
+ if full_console_logging?
350
+ puts "Ping #{url}..."
351
+ end
352
+
353
+ http = Net::HTTP.new(url.host, url.port)
354
+ res = http.start do |sess|
355
+ # noinspection RubyResolve
356
+ sess.request Net::HTTP::Get.new(ENV['CALABASH_VERSION_PATH'] || 'version')
357
+ end
358
+
359
+ status = res.code
360
+ begin
361
+ http.finish if http and http.started?
362
+ rescue
363
+ # nop
364
+ end
365
+
366
+ if status == '200'
367
+ version_body = JSON.parse(res.body)
368
+ self.device = Calabash::Cucumber::Device.new(url, version_body)
369
+ end
370
+
371
+ if full_console_logging?
372
+ puts "ping status = '#{status}'"
373
+ end
374
+ status
375
+ end
376
+
377
+ # attempts to connect to launch the app and connect to the embedded
378
+ # calabash server.
379
+ #
380
+ # to change the number of times launching is attempted set MAX_CONNECT_RETRY
381
+ #
382
+ # to change the relaunch timeout set CONNECT_TIMEOUT
383
+ #
384
+ # @param [String] app_bundle_path path to the .app that should be launched
385
+ # @param [String] sdk 6.0.3, 6.1. if nil latest SDK will be used
386
+ # @param [String] device_family {iphone | ipad}
387
+ # @param [Hash] args eke! not used (see todo)
388
+ #
389
+ # @raise [TimeoutErr] if app cannot be launched in the simulator
390
+ # todo nearly a duplicate of Launcher ensure_connectivity
391
+ # todo args was originally intended to be the args passed to the application @ launch
392
+ def ensure_connectivity(app_bundle_path, sdk, device_family, args = nil)
393
+ begin
394
+ # todo should get the retry could from the args
395
+ # todo should migrate MAX_CONNECT_RETRY to environment_helpers
396
+ max_retry_count = (ENV['MAX_CONNECT_RETRY'] || DEFAULT_SIM_RETRY).to_i
397
+ # todo should get the timeout from the args
398
+ # todo should migrate CONNECT_TIMEOUT to environment helpers
399
+ timeout = (ENV['CONNECT_TIMEOUT'] || DEFAULT_SIM_WAIT).to_i
400
+ retry_count = 0
401
+ connected = false
402
+
403
+ if full_console_logging?
404
+ puts "Waiting at most #{timeout} seconds for simulator (CONNECT_TIMEOUT)"
405
+ puts "Retrying at most #{max_retry_count} times (MAX_CONNECT_RETRY)"
406
+ end
407
+
408
+ until connected do
409
+ raise 'MAX_RETRIES' if retry_count == max_retry_count
410
+ retry_count += 1
411
+ if full_console_logging?
412
+ puts "(#{retry_count}.) Start Simulator #{sdk}, #{device_family}, for #{app_bundle_path}"
413
+ end
414
+ begin
415
+ Timeout::timeout(timeout, TimeoutErr) do
416
+ launch(app_bundle_path, sdk, device_family, args)
417
+ until connected
418
+ begin
419
+ connected = (ping_app == '200')
420
+ break if connected
421
+ rescue Exception => e
422
+ # nop
423
+ ensure
424
+ sleep 1 unless connected
425
+ end
426
+ end
427
+ end
428
+ rescue TimeoutErr => e
429
+ puts 'Timed out... Retrying'
430
+ stop
431
+ end
432
+ end
433
+ rescue RuntimeError => e
434
+ p e
435
+ msg = "Unable to make connection to Calabash Server at #{ENV['DEVICE_ENDPOINT']|| 'http://localhost:37265/'}\n"
436
+ msg << "Make sure you've' linked correctly with calabash.framework and set Other Linker Flags.\n"
437
+ msg << "Make sure you don't have a firewall blocking traffic to #{ENV['DEVICE_ENDPOINT']|| 'http://localhost:37265/'}.\n"
438
+ raise msg
439
+ end
440
+ end
441
+
442
+ # launches the app
443
+ # @param [String] app_bundle_path path to the .app that should be launched
444
+ # @param [String] sdk 6.0.3, 6.1. if nil latest SDK will be used
445
+ # @param [String] device_family {iphone | ipad}
446
+ # @param [Hash] args eke! not used (see todo)
447
+ # todo args was originally intended to be the args passed to the application @ launch
448
+ def launch(app_bundle_path, sdk, device_family, args = nil)
449
+ # cached but not used
450
+ self.launch_args = args
451
+ # launch arguments (eg. -NSShowNonLocalizedStrings) are not being passed
452
+ # to sim_launcher
453
+ # https://github.com/calabash/calabash-ios/issues/363
454
+ self.simulator.launch_ios_app(app_bundle_path, sdk, device_family)
455
+ simulator
456
+ end
457
+
458
+ # relaunches the app at +app_path+ in the simulator using +sdk+ and +args+
459
+ #
460
+ # @param [String] app_path the path to the .app
461
+ # @param [String] sdk eg. 6.0.3, 6.1
462
+ # @param [Hash] args the only option we are interested in is :device
463
+ #
464
+ # todo args was originally intended to be the args passed to the application @ launch
465
+ # todo it is _very_ likely that args[:app] == app_path so we might be able
466
+ # to eliminate an argument
467
+ def relaunch(app_path, sdk, args)
468
+ app_bundle_path = app_bundle_or_raise(app_path)
469
+
470
+ if sdk.nil?
471
+ # iOS 7 requires launching with instruments, so we _must_ launch with
472
+ # the first SDK that is _not_ iOS 7
473
+ _sdk = self.sdk_detector.available_sdk_versions.reverse.find { |x| !x.start_with?('7') }
474
+ else
475
+ # use SDK_VERSION to specify a different version
476
+ # as of Xcode 5.0.2, the min supported simulator version is iOS 6
477
+ _sdk = sdk
478
+ end
479
+
480
+ if args[:device]
481
+ device_family = args[:device].to_s
482
+ else
483
+ device_family = 'iphone'
484
+ end
485
+
486
+ self.launch_args = args
487
+
488
+ ensure_connectivity(app_bundle_path, _sdk, device_family, args)
489
+ end
490
+
491
+ # stops (quits) the simulator
492
+ def stop
493
+ self.simulator.quit_simulator
494
+ end
495
+
496
+
497
+ # @deprecated Calabash::Cucumber::Launcher.launcher.device instance methods
498
+ # @since 0.9.169
499
+ # @raise [NotImplementedError] no longer implemented
500
+ def get_version
501
+ _deprecated('0.9.169', 'use an instance Device class instead', :warn)
502
+ raise(NotImplementedError, 'this method has been deprecated')
503
+ end
504
+
505
+ # @deprecated Calabash::Cucumber::Launcher.launcher.device instance methods
506
+ # @since 0.9.169
507
+ # @raise [NotImplementedError] no longer implemented
508
+ def ios_version
509
+ _deprecated('0.9.169', 'use an instance Device class instead', :warn)
510
+ raise(NotImplementedError, 'this method has been deprecated')
511
+ end
512
+
513
+ # @deprecated use Calabash::Cucumber::Launcher.launcher.ios_major_version
514
+ # @since 0.9.169
515
+ # @raise [NotImplementedError] no longer implemented
516
+ def ios_major_version
517
+ _deprecated('0.9.169', 'use an instance Device class instead', :warn)
518
+ raise(NotImplementedError, 'this method has been deprecated')
519
+ end
520
+
521
+
522
+ # noinspection RubyUnusedLocalVariable
523
+
524
+ # @deprecated version checking is done in Launcher
525
+ # @since 0.9.169
526
+ # @raise [NotImplementedError] no longer implemented
527
+ def version_check(version)
528
+ _deprecated('0.9.169', 'check is now done in Launcher', :warn)
529
+ raise(NotImplementedError, 'this method has been deprecated and will be removed')
530
+ end
531
+ end
532
+
533
+ end
534
+ end