run_loop 2.1.3 → 2.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/lib/run_loop.rb +119 -4
  3. data/lib/run_loop/{host_cache.rb → cache.rb} +8 -3
  4. data/lib/run_loop/codesign.rb +3 -3
  5. data/lib/run_loop/core.rb +26 -5
  6. data/lib/run_loop/core_simulator.rb +14 -13
  7. data/lib/run_loop/detect_aut/detect.rb +1 -1
  8. data/lib/run_loop/device.rb +2 -2
  9. data/lib/run_loop/device_agent/Frameworks.zip +0 -0
  10. data/lib/run_loop/device_agent/app/CBX-Runner.app.zip +0 -0
  11. data/lib/run_loop/device_agent/bin/iOSDeviceManager +0 -0
  12. data/lib/run_loop/device_agent/cbxrunner.rb +3 -2
  13. data/lib/run_loop/device_agent/frameworks.rb +7 -13
  14. data/lib/run_loop/device_agent/{xctestctl.rb → ios_device_manager.rb} +36 -24
  15. data/lib/run_loop/device_agent/ipa/CBX-Runner.app.zip +0 -0
  16. data/lib/run_loop/device_agent/launcher.rb +8 -0
  17. data/lib/run_loop/device_agent/xcodebuild.rb +5 -0
  18. data/lib/run_loop/dnssd.rb +148 -0
  19. data/lib/run_loop/dot_dir.rb +1 -1
  20. data/lib/run_loop/dylib_injector.rb +1 -1
  21. data/lib/run_loop/encoding.rb +17 -0
  22. data/lib/run_loop/environment.rb +15 -5
  23. data/lib/run_loop/instruments.rb +2 -2
  24. data/lib/run_loop/language.rb +4 -0
  25. data/lib/run_loop/locale.rb +4 -1
  26. data/lib/run_loop/otool.rb +1 -1
  27. data/lib/run_loop/process_terminator.rb +1 -1
  28. data/lib/run_loop/shell.rb +2 -2
  29. data/lib/run_loop/sim_control.rb +5 -5
  30. data/lib/run_loop/simctl.rb +2 -2
  31. data/lib/run_loop/strings.rb +1 -1
  32. data/lib/run_loop/version.rb +1 -1
  33. data/lib/run_loop/xcode.rb +15 -0
  34. data/lib/run_loop/xcrun.rb +7 -3
  35. data/lib/run_loop/xcuitest.rb +155 -68
  36. metadata +41 -21
  37. data/lib/run_loop/cache/cache.rb +0 -68
  38. data/lib/run_loop/device_agent/bin/xctestctl +0 -0
  39. data/lib/run_loop/device_agent/frameworks/Frameworks.zip +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f87d14b21bab0d48f84d2d4793f5f38b7c75e537
4
- data.tar.gz: 9e565515f6f9abcc1926424c17473dca66c05222
3
+ metadata.gz: b78530b9096de94687ede2b3747d0c767c32b369
4
+ data.tar.gz: 146634e680bf39a1ddb834c5ccc0b48baf0878bc
5
5
  SHA512:
6
- metadata.gz: b1c91bc8ef53e04e8766d9b2f7fffb11ff0ddf3dc940e6ac996bee128a64bce81b70f92eaa71af466862a491f0519cbfd5b8eab2479baf481b42552839c3ca69
7
- data.tar.gz: bb0eaeef42beda6c2e9622f5b1d55a3e09f5f793b0fb0d1b0fc36935617937d0b8c8826355cdab218d57b82f6701ab26c84cc831e3092b8effc33e869c39e204
6
+ metadata.gz: 3b7f41b533a82f4b9602a99f25671b2273d6da50bb7e69f4a2e0f169013d7d042af3b7bf081607c91276aff2c3da9473c6ab31062cbd047d1c482ad159e45b19
7
+ data.tar.gz: 3d3ed52198cb8cf0c8dc274d384142f5d149c3c00a5b0219c4f49f58798c979b8898e5f5180d96f6bfef716b2229720c751488d042e25c7066d15cecdb155640
data/lib/run_loop.rb CHANGED
@@ -23,7 +23,7 @@ require 'run_loop/ipa'
23
23
  require "run_loop/device_agent/cbxrunner"
24
24
  require "run_loop/device_agent/frameworks"
25
25
  require "run_loop/device_agent/launcher"
26
- require "run_loop/device_agent/xctestctl"
26
+ require "run_loop/device_agent/ios_device_manager"
27
27
  require "run_loop/device_agent/xcodebuild"
28
28
  require "run_loop/detect_aut/errors"
29
29
  require "run_loop/detect_aut/xamarin_studio"
@@ -35,8 +35,7 @@ require 'run_loop/instruments'
35
35
  require 'run_loop/lipo'
36
36
  require "run_loop/otool"
37
37
  require "run_loop/strings"
38
- require 'run_loop/cache/cache'
39
- require 'run_loop/host_cache'
38
+ require 'run_loop/cache'
40
39
  require 'run_loop/patches/awesome_print'
41
40
  require 'run_loop/core_simulator'
42
41
  require "run_loop/simctl"
@@ -49,6 +48,7 @@ require "run_loop/http/server"
49
48
  require "run_loop/http/request"
50
49
  require "run_loop/http/retriable_client"
51
50
  require "run_loop/physical_device/life_cycle"
51
+ require "run_loop/dnssd"
52
52
 
53
53
  module RunLoop
54
54
 
@@ -80,10 +80,20 @@ module RunLoop
80
80
  # We want to use the _exact_ objects that were passed.
81
81
  if options[:xcode]
82
82
  cloned_options[:xcode] = options[:xcode]
83
+ else
84
+ cloned_options[:xcode] = RunLoop::Xcode.new
83
85
  end
84
86
 
85
87
  if options[:simctl]
86
88
  cloned_options[:simctl] = options[:simctl]
89
+ else
90
+ cloned_options[:simctl] = RunLoop::Simctl.new
91
+ end
92
+
93
+ if options[:instruments]
94
+ cloned_options[:instruments] = options[:instruments]
95
+ else
96
+ cloned_options[:instruments] = RunLoop::Instruments.new
87
97
  end
88
98
 
89
99
  # Soon to be unsupported.
@@ -91,7 +101,15 @@ module RunLoop
91
101
  cloned_options[:sim_control] = options[:sim_control]
92
102
  end
93
103
 
94
- if options[:xcuitest]
104
+ xcode = cloned_options[:xcode]
105
+ simctl = cloned_options[:simctl]
106
+ instruments = cloned_options[:instruments]
107
+
108
+ device = Device.detect_device(cloned_options, xcode, simctl, instruments)
109
+ cloned_options[:device] = device
110
+
111
+ gesture_performer = RunLoop.detect_gesture_performer(cloned_options, xcode, device)
112
+ if gesture_performer == :device_agent
95
113
  RunLoop::XCUITest.run(cloned_options)
96
114
  else
97
115
  if RunLoop::Instruments.new.instruments_app_running?
@@ -224,4 +242,101 @@ Please quit the Instruments.app and try again.)
224
242
  def self.log_info(*args)
225
243
  RunLoop::Logging.log_info(*args)
226
244
  end
245
+
246
+ # @!visibility private
247
+ #
248
+ # @param [RunLoop::Xcode] xcode The active Xcode
249
+ # @param [RunLoop::Device] device The device under test.
250
+ def self.default_gesture_performer(xcode, device)
251
+ # TODO XTC support
252
+ return :instruments if RunLoop::Environment.xtc?
253
+
254
+ if xcode.version_gte_8?
255
+ if device.version >= RunLoop::Version.new("9.0")
256
+ :device_agent
257
+ else
258
+ raise RuntimeError, %Q[
259
+ Invalid Xcode and iOS combination:
260
+
261
+ Xcode version: #{xcode.version.to_s}
262
+ iOS version: #{device.version.to_s}
263
+
264
+ Calabash cannot test iOS < 9.0 using Xcode 8 because XCUITest is not compatible
265
+ with iOS < 9.0 and UIAutomation is not available in Xcode 8.
266
+
267
+ You can rerun your test if you have Xcode 7 installed:
268
+
269
+ $ DEVELOPER_DIR=/path/to/Xcode/7.3.1/Xcode.app/Contents/Developer cucumber
270
+
271
+ ]
272
+ end
273
+
274
+ else
275
+ :instruments
276
+ end
277
+ end
278
+
279
+ # @!visibility private
280
+ #
281
+ # First pass at choosing the correct code path.
282
+ #
283
+ # We don't know if we can test on iOS 8 with UIAutomation or XCUITest on
284
+ # Xcode 8.
285
+ #
286
+ # @param [Hash] options The options passed by the user
287
+ # @param [RunLoop::Xcode] xcode The active Xcode
288
+ # @param [RunLoop::Device] device The device under test
289
+ def self.detect_gesture_performer(options, xcode, device)
290
+ # TODO XTC support
291
+ return :instruments if RunLoop::Environment.xtc?
292
+
293
+ gesture_performer = options[:gesture_performer]
294
+
295
+ if gesture_performer
296
+ if xcode.version_gte_8?
297
+ if gesture_performer == :instruments
298
+ raise RuntimeError, %Q[
299
+ Incompatible :gesture_performer option for active Xcode.
300
+
301
+ Detected :gesture_performer => :instruments and Xcode #{xcode.version}.
302
+
303
+ Don't set the :gesture_performer option unless you are gem maintainer.
304
+
305
+ ]
306
+ elsif device.version < RunLoop::Version.new("9.0")
307
+ raise RuntimeError, %Q[
308
+
309
+ Invalid Xcode and iOS combination:
310
+
311
+ Xcode version: #{xcode.version.to_s}
312
+ iOS version: #{device.version.to_s}
313
+
314
+ Calabash cannot test iOS < 9.0 using Xcode 8 because XCUITest is not compatible
315
+ with iOS < 9.0 and UIAutomation is not available in Xcode 8.
316
+
317
+ You can rerun your test if you have Xcode 7 installed:
318
+
319
+ $ DEVELOPER_DIR=/path/to/Xcode/7.3.1/Xcode.app/Contents/Developer cucumber
320
+
321
+ Don't set the :gesture_performer option unless you are gem maintainer.
322
+
323
+ ]
324
+ end
325
+ end
326
+
327
+ if ![:device_agent, :instruments].include?(gesture_performer)
328
+ raise RuntimeError, %Q[
329
+ Invalid :gesture_performer option: #{gesture_performer}
330
+
331
+ Allowed performers: :device_agent or :instruments.
332
+
333
+ Don't set the :gesture_performer option unless you are gem maintainer.
334
+
335
+ ]
336
+ end
337
+ gesture_performer
338
+ else
339
+ RunLoop.default_gesture_performer(xcode, device)
340
+ end
341
+ end
227
342
  end
@@ -12,7 +12,7 @@ module RunLoop
12
12
  # Marshal is safe to use here because:
13
13
  # 1. This code is not executed on the XTC.
14
14
  # 2. Users who muck about with this cache can only hurt themselves.
15
- class HostCache
15
+ class Cache
16
16
 
17
17
  # The path to the cache file.
18
18
  #
@@ -40,7 +40,7 @@ RunLoop requires this directory to cache files
40
40
 
41
41
  # The default cache.
42
42
  def self.default
43
- RunLoop::HostCache.new(self.default_directory)
43
+ RunLoop::Cache.new(self.default_directory)
44
44
  end
45
45
 
46
46
  # Creates a new HostCache that is ready for IO.
@@ -50,7 +50,7 @@ RunLoop requires this directory to cache files
50
50
  # @options [Hash] options Options to control the state of the new object.
51
51
  # @option [String] filename (host_run_loop.hash) The cache filename.
52
52
  # @option [Boolean] clear (false) If true, the current cache will be cleared.
53
- # @return [RunLoop::HostCache] A cache that is ready for IO.
53
+ # @return [RunLoop::Cache] A cache that is ready for IO.
54
54
  def initialize(directory, options = {})
55
55
  sha1 = Digest::SHA1.hexdigest 'host_run_loop.hash'
56
56
  default_opts = {:filename => sha1,
@@ -125,4 +125,9 @@ RunLoop requires this directory to cache files
125
125
  self.write({})
126
126
  end
127
127
  end
128
+
129
+ # @!visibility private
130
+ # Required for backward compatibility.
131
+ # The only legitimate caller is in Calabash iOS Launcher#attach.
132
+ class HostCache < RunLoop::Cache ; end
128
133
  end
@@ -18,7 +18,7 @@ module RunLoop
18
18
  # @!visibility private
19
19
  def self.info(path)
20
20
  self.expect_path_exists(path)
21
- self.exec(["--display", "--verbose=4", path])
21
+ self.run_codesign_command(["--display", "--verbose=4", path])
22
22
  end
23
23
 
24
24
  # @!visibility private
@@ -59,7 +59,7 @@ module RunLoop
59
59
  end
60
60
  end
61
61
 
62
- def self.exec(args)
62
+ def self.run_codesign_command(args)
63
63
  if !args.is_a?(Array)
64
64
  raise ArgumentError, "Expected args: '#{args}' to be an Array"
65
65
  end
@@ -67,7 +67,7 @@ module RunLoop
67
67
  xcrun = RunLoop::Xcrun.new
68
68
  cmd = ["codesign"] + args
69
69
  options = {:log_cmd => true}
70
- hash = xcrun.exec(cmd, options)
70
+ hash = xcrun.run_command_in_context(cmd, options)
71
71
 
72
72
  hash[:out]
73
73
  end
data/lib/run_loop/core.rb CHANGED
@@ -53,6 +53,8 @@ module RunLoop
53
53
  SCRIPTS[key]
54
54
  end
55
55
 
56
+ # @!visibility private
57
+ # This is the entry point for UIAutomation.
56
58
  def self.run_with_options(options)
57
59
  before = Time.now
58
60
 
@@ -63,6 +65,22 @@ module RunLoop
63
65
  xcode = options[:xcode] || RunLoop::Xcode.new
64
66
  instruments = options[:instruments] || RunLoop::Instruments.new
65
67
 
68
+ if xcode.version_gte_8?
69
+ raise %Q[
70
+ UIAutomation is not available on Xcode >= 8.*.
71
+
72
+ We are in the process of updating Calabash to use our new tool: DeviceAgent.
73
+
74
+ We will track progress in this forum post:
75
+
76
+ https://groups.google.com/forum/#!topic/calabash-ios/g34znf0LnE4
77
+
78
+ For now, testing with Xcode 8 is not supported.
79
+
80
+ Thank you for your patience.
81
+ ]
82
+ end
83
+
66
84
  # Device under test: DUT
67
85
  device = RunLoop::Device.detect_device(options, xcode, simctl, instruments)
68
86
 
@@ -120,7 +138,7 @@ module RunLoop
120
138
  FileUtils.touch repl_path
121
139
  end
122
140
 
123
- RunLoop::HostCache.default.clear unless RunLoop::Environment.xtc?
141
+ RunLoop::Cache.default.clear unless RunLoop::Environment.xtc?
124
142
 
125
143
  cal_script = File.join(SCRIPTS_PATH, 'calabash_script_uia.js')
126
144
  File.open(script, 'w') do |file|
@@ -202,7 +220,8 @@ means that the APP variable is pointing to a .app that does not exist.
202
220
  :app => app_details[:bundle_id],
203
221
  :repl_path => repl_path,
204
222
  :log_file => log_file,
205
- :results_dir => results_dir
223
+ :results_dir => results_dir,
224
+ :gesture_performer => :instruments
206
225
  }
207
226
 
208
227
  uia_timeout = options[:uia_timeout] || RunLoop::Environment.uia_timeout || 10
@@ -322,7 +341,9 @@ Logfile: #{log_file}
322
341
  # version.
323
342
  def self.default_simulator(xcode=RunLoop::Xcode.new)
324
343
 
325
- if xcode.version_gte_73?
344
+ if xcode.version_gte_8?
345
+ "iPhone 6s (10.0)"
346
+ elsif xcode.version_gte_73?
326
347
  "iPhone 6s (9.3)"
327
348
  elsif xcode.version_gte_72?
328
349
  "iPhone 6s (9.2)"
@@ -387,7 +408,7 @@ Logfile: #{log_file}
387
408
  raise RunLoop::WriteFailedError.new("Trying write of command #{cmd_str} at index #{index}")
388
409
  end
389
410
  run_loop[:index] = index + 1
390
- RunLoop::HostCache.default.write(run_loop) unless RunLoop::Environment.xtc?
411
+ RunLoop::Cache.default.write(run_loop) unless RunLoop::Environment.xtc?
391
412
  index
392
413
  end
393
414
 
@@ -503,7 +524,7 @@ Logfile: #{log_file}
503
524
  end
504
525
 
505
526
  run_loop[:initial_offset] = offset
506
- RunLoop::HostCache.default.write(run_loop) unless RunLoop::Environment.xtc?
527
+ RunLoop::Cache.default.write(run_loop) unless RunLoop::Environment.xtc?
507
528
  result
508
529
  end
509
530
 
@@ -1,6 +1,9 @@
1
1
  # A class to manage interactions with CoreSimulators.
2
2
  class RunLoop::CoreSimulator
3
3
 
4
+ require "run_loop/shell"
5
+ include RunLoop::Shell
6
+
4
7
  # These options control various aspects of an app's life cycle on the iOS
5
8
  # Simulator.
6
9
  #
@@ -61,15 +64,13 @@ class RunLoop::CoreSimulator
61
64
  # This process is a daemon, and requires 'KILL' to terminate.
62
65
  # Killing the process is fast, but it takes a long time to
63
66
  # restart.
64
- ['com.apple.CoreSimulator.CoreSimulatorService', false],
67
+ "com.apple.CoreSimulator.CoreSimulatorService",
65
68
 
66
- # Probably do not need to quit this, but it is tempting to do so.
67
- #['com.apple.CoreSimulator.SimVerificationService', false],
69
+ # Not yet.
70
+ # "com.apple.CoreSimulator.SimVerificationService",
68
71
 
69
72
  'SimulatorBridge',
70
73
  'configd_sim',
71
-
72
- # Does not always appear.
73
74
  'CoreSimulatorBridge',
74
75
 
75
76
  # Xcode 7
@@ -207,7 +208,7 @@ class RunLoop::CoreSimulator
207
208
 
208
209
  if simulator.update_simulator_state != "Shutdown"
209
210
  args = ["simctl", "shutdown", simulator.udid]
210
- xcrun.exec(args, xcrun_opts)
211
+ xcrun.run_command_in_context(args, xcrun_opts)
211
212
  begin
212
213
  self.wait_for_simulator_state(simulator, "Shutdown")
213
214
  rescue RuntimeError => _
@@ -226,7 +227,7 @@ $ bundle exec run-loop simctl manage-processes
226
227
  end
227
228
 
228
229
  args = ["simctl", "erase", simulator.udid]
229
- hash = xcrun.exec(args, xcrun_opts)
230
+ hash = xcrun.run_command_in_context(args, xcrun_opts)
230
231
 
231
232
  if hash[:exit_status] != 0
232
233
  raise RuntimeError, %Q{
@@ -489,7 +490,7 @@ $ bundle exec run-loop simctl manage-processes
489
490
  args = ['simctl', 'uninstall', device.udid, app.bundle_identifier]
490
491
 
491
492
  timeout = DEFAULT_OPTIONS[:uninstall_app_timeout]
492
- xcrun.exec(args, log_cmd: true, timeout: timeout)
493
+ xcrun.run_command_in_context(args, log_cmd: true, timeout: timeout)
493
494
 
494
495
  device.simulator_wait_for_stable_state
495
496
  true
@@ -569,8 +570,8 @@ $ bundle exec run-loop simctl manage-processes
569
570
  def running_simulator_pid
570
571
  process_name = "MacOS/#{sim_name}"
571
572
 
572
- args = ["xcrun", "ps", "x", "-o", "pid,command"]
573
- hash = xcrun.exec(args)
573
+ args = ["ps", "x", "-o", "pid,command"]
574
+ hash = run_shell_command(args)
574
575
 
575
576
  exit_status = hash[:exit_status]
576
577
  if exit_status != 0
@@ -611,7 +612,7 @@ Command had no output
611
612
 
612
613
  args = ['simctl', 'install', device.udid, app.path]
613
614
  timeout = DEFAULT_OPTIONS[:install_app_timeout]
614
- xcrun.exec(args, log_cmd: true, timeout: timeout)
615
+ xcrun.run_command_in_context(args, log_cmd: true, timeout: timeout)
615
616
 
616
617
  device.simulator_wait_for_stable_state
617
618
  installed_app_bundle_dir
@@ -621,7 +622,7 @@ Command had no output
621
622
  def launch_app_with_simctl
622
623
  args = ['simctl', 'launch', device.udid, app.bundle_identifier]
623
624
  timeout = DEFAULT_OPTIONS[:launch_app_timeout]
624
- xcrun.exec(args, log_cmd: true, timeout: timeout)
625
+ xcrun.run_command_in_context(args, log_cmd: true, timeout: timeout)
625
626
  end
626
627
 
627
628
  # @!visibility private
@@ -864,7 +865,7 @@ Command had no output
864
865
  target = File.join(directory, bundle_name)
865
866
 
866
867
  args = ['ditto', app.path, target]
867
- xcrun.exec(args, log_cmd: true)
868
+ xcrun.run_command_in_context(args, log_cmd: true)
868
869
 
869
870
  RunLoop.log_debug("Installed #{app} on CoreSimulator #{device.udid}")
870
871
 
@@ -29,7 +29,7 @@ module RunLoop
29
29
 
30
30
  # @!visibility private
31
31
  DEFAULTS = {
32
- :search_depth => 5
32
+ :search_depth => 10
33
33
  }
34
34
 
35
35
  # @!visibility private
@@ -505,7 +505,7 @@ version: #{version}
505
505
  ]
506
506
 
507
507
  # RunLoop::PlistBuddy cannot add items to arrays.
508
- xcrun.exec(cmd, {:log_cmd => true})
508
+ xcrun.run_command_in_context(cmd, {:log_cmd => true})
509
509
 
510
510
  simulator_languages
511
511
  end
@@ -547,7 +547,7 @@ version: #{version}
547
547
  end
548
548
 
549
549
  args = ['simctl', 'list', 'devices']
550
- hash = xcrun.exec(args)
550
+ hash = xcrun.run_command_in_context(args)
551
551
  out = hash[:out]
552
552
 
553
553
  matched_line = out.split("\n").find do |line|
@@ -5,7 +5,6 @@ module RunLoop
5
5
  # @!visibility private
6
6
  class CBXRunner
7
7
 
8
- require "run_loop/shell"
9
8
 
10
9
  # @!visibility private
11
10
  @@cbxdevice = nil
@@ -87,8 +86,10 @@ but runner does not exist at that path.
87
86
  end
88
87
 
89
88
  # @!visibility private
89
+ # TODO move this behavior to shell.rb - should be able to call Shell.run_unix_command
90
90
  def self.expand_runner_archive(archive)
91
91
  shell = Class.new do
92
+ require "run_loop/shell"
92
93
  include RunLoop::Shell
93
94
  def to_s; "#<CBXRunner Shell>"; end
94
95
  def inspect; to_s; end
@@ -98,7 +99,7 @@ but runner does not exist at that path.
98
99
  options = { :log_cmd => true }
99
100
  Dir.chdir(dir) do
100
101
  RunLoop.log_unix_cmd("cd #{dir}")
101
- shell.exec(["unzip", File.basename(archive)], options)
102
+ shell.run_shell_command(["ditto", "-xk", File.basename(archive), "."], options)
102
103
  end
103
104
  File.join(dir, "CBX-Runner.app")
104
105
  end