run_loop 2.1.3 → 2.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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