run_loop 2.2.4 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/run_loop/cli/instruments.rb +9 -0
- data/lib/run_loop/core.rb +2 -4
- data/lib/run_loop/core_simulator.rb +232 -115
- data/lib/run_loop/device.rb +177 -105
- data/lib/run_loop/device_agent/Frameworks.zip +0 -0
- data/lib/run_loop/device_agent/app/DeviceAgent-Runner.app.zip +0 -0
- data/lib/run_loop/device_agent/bin/iOSDeviceManager +0 -0
- data/lib/run_loop/device_agent/client.rb +113 -37
- data/lib/run_loop/device_agent/ios_device_manager.rb +9 -14
- data/lib/run_loop/device_agent/ipa/DeviceAgent-Runner.app.zip +0 -0
- data/lib/run_loop/logging.rb +1 -1
- data/lib/run_loop/process_waiter.rb +35 -4
- data/lib/run_loop/simctl.rb +2 -2
- data/lib/run_loop/version.rb +1 -1
- data/scripts/lib/on_alert.js +33 -2
- data/vendor-licenses/CocoaAsyncSocket.LICENSE +4 -0
- data/vendor-licenses/CocoaHTTPServer.LICENSE +18 -0
- data/vendor-licenses/CocoaLumberjack.LICENSE +33 -0
- data/vendor-licenses/Facebook-WebDriverAgent.LICENSE +30 -0
- data/vendor-licenses/RoutingHTTPServer.LICENSE +19 -0
- metadata +8 -4
- data/vendor-licenses/xctestctl.LICENSE +0 -32
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 101e24777ce2bcf5ab9b3383d38bcee5b84e2380
|
4
|
+
data.tar.gz: cecaa67f6d26fcbacb586feb4cc8124fd83aeac3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8f8ddac54d1977cb746bea4d974e4467d99f90fad5f6597fa5aaff86cabab2fba0cba726aee42c32cf70b78f6986b09f200ad622de295e90710fbe920b16e904
|
7
|
+
data.tar.gz: 58c40dc759901a4188ae9499892d9baaecceb8ee8a6648e2bad6e7b966bd6c498da6528bff12f7a9eed3354a5ae67cdf35176d92d92f57e7f01ce4719e4e8e02
|
@@ -26,6 +26,11 @@ module RunLoop
|
|
26
26
|
|
27
27
|
|
28
28
|
def quit
|
29
|
+
if RunLoop::Xcode.new.version_gte_8?
|
30
|
+
puts "instruments quit with Xcode 8 is not supported"
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
|
29
34
|
signal = options[:signal]
|
30
35
|
ENV['DEBUG'] = '1' if options[:debug]
|
31
36
|
instruments = RunLoop::Instruments.new
|
@@ -94,6 +99,10 @@ module RunLoop
|
|
94
99
|
:type => :boolean
|
95
100
|
|
96
101
|
def launch
|
102
|
+
if RunLoop::Xcode.new.version_gte_8?
|
103
|
+
puts "Launching applications with Xcode 8 is not supported"
|
104
|
+
exit 1
|
105
|
+
end
|
97
106
|
|
98
107
|
debug = options[:debug]
|
99
108
|
original_value = ENV['DEBUG']
|
data/lib/run_loop/core.rb
CHANGED
@@ -807,8 +807,8 @@ $ xcrun instruments -s templates
|
|
807
807
|
# Validate the architecture.
|
808
808
|
self.expect_simulator_compatible_arch(device, app)
|
809
809
|
|
810
|
-
|
811
|
-
core_sim = RunLoop::CoreSimulator.new(device, app, :
|
810
|
+
RunLoop::CoreSimulator.quit_simulator
|
811
|
+
core_sim = RunLoop::CoreSimulator.new(device, app, xcode: xcode)
|
812
812
|
|
813
813
|
# Calabash 0.x can only reset the app sandbox (true/false).
|
814
814
|
# Calabash 2.x has advanced reset options.
|
@@ -816,13 +816,11 @@ $ xcrun instruments -s templates
|
|
816
816
|
core_sim.reset_app_sandbox
|
817
817
|
end
|
818
818
|
|
819
|
-
# Will quit the simulator if it is running.
|
820
819
|
# @todo fix accessibility_enabled? so we don't have to quit the sim
|
821
820
|
# SimControl#accessibility_enabled? is always false during Core#prepare_simulator
|
822
821
|
# https://github.com/calabash/run_loop/issues/167
|
823
822
|
simctl.ensure_accessibility(device)
|
824
823
|
|
825
|
-
# Will quit the simulator if it is running.
|
826
824
|
# @todo fix software_keyboard_enabled? so we don't have to quit the sim
|
827
825
|
# SimControl#software_keyboard_enabled? is always false during Core#prepare_simulator
|
828
826
|
# https://github.com/calabash/run_loop/issues/168
|
@@ -30,9 +30,6 @@ class RunLoop::CoreSimulator
|
|
30
30
|
# This should not be overridden
|
31
31
|
WAIT_FOR_SIMULATOR_STATE_INTERVAL = 0.1
|
32
32
|
|
33
|
-
# @!visibility private
|
34
|
-
@@simulator_pid = nil
|
35
|
-
|
36
33
|
# @!visibility private
|
37
34
|
attr_reader :app
|
38
35
|
|
@@ -70,12 +67,12 @@ class RunLoop::CoreSimulator
|
|
70
67
|
# Not yet.
|
71
68
|
# "com.apple.CoreSimulator.SimVerificationService",
|
72
69
|
|
73
|
-
|
74
|
-
|
75
|
-
|
70
|
+
"SimulatorBridge",
|
71
|
+
"configd_sim",
|
72
|
+
"CoreSimulatorBridge",
|
76
73
|
|
77
74
|
# Xcode 7
|
78
|
-
|
75
|
+
"ids_simd"
|
79
76
|
]
|
80
77
|
|
81
78
|
# @!visibility private
|
@@ -84,39 +81,40 @@ class RunLoop::CoreSimulator
|
|
84
81
|
SIMULATOR_QUIT_PROCESSES =
|
85
82
|
[
|
86
83
|
# Xcode 7 start throwing this error.
|
87
|
-
[
|
88
|
-
|
89
|
-
# Xcode < 5.1
|
90
|
-
['iPhone Simulator.app', true],
|
91
|
-
|
92
|
-
# 7.0 < Xcode <= 6.0
|
93
|
-
['iOS Simulator.app', true],
|
84
|
+
["splashboardd", false],
|
94
85
|
|
95
86
|
# Xcode >= 7.0
|
96
|
-
[
|
87
|
+
["Simulator", true],
|
97
88
|
|
98
|
-
#
|
99
|
-
|
100
|
-
|
101
|
-
|
89
|
+
# Xcode < 7.0
|
90
|
+
["iOS Simulator", true],
|
91
|
+
|
92
|
+
# Multiple launchd_sim processes have been causing problems.
|
93
|
+
# In theory, killing the parent launchd_sim process should kill
|
94
|
+
# child processes like assetsd, but in practice this does not
|
95
|
+
# always happen.
|
96
|
+
["launchd_sim", false],
|
102
97
|
|
103
98
|
# Required for DeviceAgent termination; the simulator hangs otherwise.
|
104
99
|
["xpcproxy", false],
|
105
100
|
|
106
|
-
# Causes crash reports on Xcode < 7.0
|
107
|
-
["apsd", true],
|
108
|
-
|
109
101
|
# assetsd instances clobber each other and are not properly
|
110
102
|
# killed when quiting the simulator.
|
111
|
-
[
|
103
|
+
["assetsd", false],
|
112
104
|
|
113
105
|
# iproxy is started by UITest.
|
114
|
-
[
|
106
|
+
["iproxy", false],
|
115
107
|
|
116
108
|
# Started by Xamarin Studio, this is the parent process of the
|
117
109
|
# processes launched by Xamarin's interaction with
|
118
110
|
# CoreSimulatorBridge.
|
119
|
-
[
|
111
|
+
["csproxy", false],
|
112
|
+
|
113
|
+
# Hundreds of these processes can be present in Xcode 8 and they
|
114
|
+
# appear to influence the behavior of DeviceAgent.
|
115
|
+
["MobileSMSSpotlightImporter", false],
|
116
|
+
["UserEventAgent", false],
|
117
|
+
["mobileassetd", false]
|
120
118
|
]
|
121
119
|
|
122
120
|
# @!visibility private
|
@@ -131,6 +129,29 @@ class RunLoop::CoreSimulator
|
|
131
129
|
send_term_first = false
|
132
130
|
self.term_or_kill(process_name, send_term_first)
|
133
131
|
end
|
132
|
+
|
133
|
+
ps_name_fn = lambda do |pid|
|
134
|
+
args = ["ps", "-o", "comm=", "-p", pid.to_s]
|
135
|
+
out = RunLoop::Shell.run_shell_command(args)[:out]
|
136
|
+
if out && out.strip != ""
|
137
|
+
out.strip
|
138
|
+
else
|
139
|
+
"UNKNOWN PROCESS: #{pid}"
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
kill_options = { :timeout => 0.5 }
|
144
|
+
|
145
|
+
RunLoop::ProcessWaiter.pgrep_f("launchd_sim").each do |pid|
|
146
|
+
process_name = ps_name_fn.call(pid)
|
147
|
+
RunLoop::ProcessTerminator.new(pid, 'KILL', process_name, kill_options).kill_process
|
148
|
+
end
|
149
|
+
|
150
|
+
RunLoop::ProcessWaiter.pgrep_f("iPhoneSimulator").each do |pid|
|
151
|
+
process_name = ps_name_fn.call(pid)
|
152
|
+
RunLoop::ProcessTerminator.new(pid, 'KILL', process_name, kill_options).kill_process
|
153
|
+
end
|
154
|
+
|
134
155
|
end
|
135
156
|
|
136
157
|
# @!visibility private
|
@@ -141,8 +162,6 @@ class RunLoop::CoreSimulator
|
|
141
162
|
send_term_first = process_details[1]
|
142
163
|
self.term_or_kill(process_name, send_term_first)
|
143
164
|
end
|
144
|
-
|
145
|
-
self.simulator_pid = nil
|
146
165
|
end
|
147
166
|
|
148
167
|
# @!visibility private
|
@@ -288,16 +307,6 @@ class RunLoop::CoreSimulator
|
|
288
307
|
installed
|
289
308
|
end
|
290
309
|
|
291
|
-
# @!visibility private
|
292
|
-
def self.simulator_pid
|
293
|
-
@@simulator_pid
|
294
|
-
end
|
295
|
-
|
296
|
-
# @!visibility private
|
297
|
-
def self.simulator_pid=(pid)
|
298
|
-
@@simulator_pid = pid
|
299
|
-
end
|
300
|
-
|
301
310
|
# @param [RunLoop::Device] device The device.
|
302
311
|
# @param [RunLoop::App] app The application.
|
303
312
|
# @param [Hash] options Controls the behavior of this class.
|
@@ -305,17 +314,9 @@ class RunLoop::CoreSimulator
|
|
305
314
|
# @option options :xcode An instance of Xcode to use
|
306
315
|
# simulators in the initialize method.
|
307
316
|
def initialize(device, app, options={})
|
308
|
-
defaults = { :quit_sim_on_init => true }
|
309
|
-
merged = defaults.merge(options)
|
310
|
-
|
311
317
|
@app = app
|
312
318
|
@device = device
|
313
|
-
|
314
|
-
@xcode = merged[:xcode]
|
315
|
-
|
316
|
-
if merged[:quit_sim_on_init]
|
317
|
-
RunLoop::CoreSimulator.quit_simulator
|
318
|
-
end
|
319
|
+
@xcode = options[:xcode]
|
319
320
|
|
320
321
|
# stdio.pipe - can cause problems finding the SHA of a simulator
|
321
322
|
rm_instruments_pipe
|
@@ -341,26 +342,27 @@ class RunLoop::CoreSimulator
|
|
341
342
|
@simctl ||= RunLoop::Simctl.new
|
342
343
|
end
|
343
344
|
|
345
|
+
# @!visibility private
|
346
|
+
def simulator_requires_relaunch?
|
347
|
+
[simulator_state_requires_relaunch?,
|
348
|
+
running_apps_require_relaunch?].any?
|
349
|
+
end
|
350
|
+
|
344
351
|
# Launch the simulator indicated by device.
|
345
352
|
def launch_simulator(options={})
|
346
353
|
merged_options = {
|
347
354
|
:wait_for_stable => true
|
348
355
|
}.merge(options)
|
349
356
|
|
350
|
-
if
|
351
|
-
|
352
|
-
|
353
|
-
# Did we launch it?
|
354
|
-
if running_simulator_pid == RunLoop::CoreSimulator.simulator_pid
|
355
|
-
# Nothing to do, we already launched the simulator.
|
356
|
-
return
|
357
|
-
else
|
358
|
-
# We did not launch this simulator; quit it.
|
359
|
-
RunLoop::CoreSimulator.quit_simulator
|
360
|
-
end
|
357
|
+
if !simulator_requires_relaunch?
|
358
|
+
RunLoop.log_debug("Simulator is running and does not require a relaunch.")
|
359
|
+
return
|
361
360
|
end
|
362
361
|
|
363
|
-
|
362
|
+
RunLoop::CoreSimulator.quit_simulator
|
363
|
+
|
364
|
+
args = ['open', '-g', '-a', sim_app_path, '--args',
|
365
|
+
'-CurrentDeviceUDID', device.udid, "LAUNCHED_BY_RUN_LOOP"]
|
364
366
|
|
365
367
|
RunLoop.log_debug("Launching #{device} with:")
|
366
368
|
RunLoop.log_unix_cmd("xcrun #{args.join(' ')}")
|
@@ -380,9 +382,6 @@ class RunLoop::CoreSimulator
|
|
380
382
|
elapsed = Time.now - start_time
|
381
383
|
RunLoop.log_debug("Took #{elapsed} seconds to launch the simulator")
|
382
384
|
|
383
|
-
# Keep track of the pid so we can know if we have already launched this sim.
|
384
|
-
RunLoop::CoreSimulator.simulator_pid = running_simulator_pid
|
385
|
-
|
386
385
|
true
|
387
386
|
end
|
388
387
|
|
@@ -470,15 +469,14 @@ Could not launch #{app.bundle_identifier} on #{device} after trying #{tries} tim
|
|
470
469
|
def uninstall_app_and_sandbox
|
471
470
|
return true if !app_is_installed?
|
472
471
|
|
473
|
-
|
474
|
-
|
475
|
-
timeout = DEFAULT_OPTIONS[:uninstall_app_timeout]
|
476
|
-
simctl.uninstall(device, app, timeout)
|
477
|
-
|
478
|
-
device.simulator_wait_for_stable_state
|
472
|
+
uninstall_app_with_simctl
|
479
473
|
true
|
480
474
|
end
|
481
475
|
|
476
|
+
=begin
|
477
|
+
PRIVATE METHODS
|
478
|
+
=end
|
479
|
+
|
482
480
|
private
|
483
481
|
|
484
482
|
# @!visibility private
|
@@ -501,6 +499,16 @@ Could not launch #{app.bundle_identifier} on #{device} after trying #{tries} tim
|
|
501
499
|
kill_options = { :timeout => 0.5 }
|
502
500
|
|
503
501
|
RunLoop::ProcessWaiter.new(process_name).pids.each do |pid|
|
502
|
+
|
503
|
+
# We could try to determine if terminating the process will be successful
|
504
|
+
# by asking for the parent pid and the user id. This adds another call
|
505
|
+
# to `ps` and does not save any time. It is easier to simply let the
|
506
|
+
# ProcessTerminator fail. The downside is that a failure will appear
|
507
|
+
# in the debug log.
|
508
|
+
#
|
509
|
+
# macOS is looking more like iOS. Process names like 'mobileassetd' are
|
510
|
+
# found in both operating systems.
|
511
|
+
|
504
512
|
killed = false
|
505
513
|
|
506
514
|
if send_term_first
|
@@ -508,8 +516,9 @@ Could not launch #{app.bundle_identifier} on #{device} after trying #{tries} tim
|
|
508
516
|
killed = term.kill_process
|
509
517
|
end
|
510
518
|
|
511
|
-
|
512
|
-
RunLoop::ProcessTerminator.new(pid, 'KILL', process_name, kill_options)
|
519
|
+
if !killed
|
520
|
+
term = RunLoop::ProcessTerminator.new(pid, 'KILL', process_name, kill_options)
|
521
|
+
term.kill_process
|
513
522
|
end
|
514
523
|
end
|
515
524
|
end
|
@@ -519,13 +528,13 @@ Could not launch #{app.bundle_identifier} on #{device} after trying #{tries} tim
|
|
519
528
|
# @return [String] A String suitable for searching for a pid, quitting, or
|
520
529
|
# launching the current simulator.
|
521
530
|
def sim_name
|
522
|
-
@sim_name ||=
|
531
|
+
@sim_name ||= begin
|
523
532
|
if xcode.version_gte_7?
|
524
533
|
"Simulator"
|
525
534
|
else
|
526
535
|
"iOS Simulator"
|
527
536
|
end
|
528
|
-
|
537
|
+
end
|
529
538
|
end
|
530
539
|
|
531
540
|
# @!visibility private
|
@@ -534,74 +543,114 @@ Could not launch #{app.bundle_identifier} on #{device} after trying #{tries} tim
|
|
534
543
|
# @return [String] The path to the simulator app for the current version of
|
535
544
|
# Xcode.
|
536
545
|
def sim_app_path
|
537
|
-
@sim_app_path ||=
|
538
|
-
|
539
|
-
|
540
|
-
"#{dev_dir}/Applications/Simulator.app"
|
541
|
-
else
|
542
|
-
"#{dev_dir}/Applications/iOS Simulator.app"
|
543
|
-
end
|
544
|
-
}.call
|
546
|
+
@sim_app_path ||= begin
|
547
|
+
"#{xcode.developer_dir}/Applications/#{sim_name}.app"
|
548
|
+
end
|
545
549
|
end
|
546
550
|
|
547
551
|
# @!visibility private
|
548
|
-
# Returns the current Simulator pid.
|
549
|
-
#
|
550
|
-
# @note Will only search for the current Xcode simulator.
|
551
552
|
#
|
552
|
-
# @return [
|
553
|
-
def
|
553
|
+
# @return [Hash] details about the running simulator.
|
554
|
+
def running_simulator_details
|
554
555
|
process_name = "MacOS/#{sim_name}"
|
555
556
|
|
556
|
-
args = ["ps", "x", "-o", "pid
|
557
|
+
args = ["ps", "x", "-o", "pid=,command="]
|
557
558
|
hash = run_shell_command(args)
|
558
559
|
|
559
560
|
exit_status = hash[:exit_status]
|
560
561
|
if exit_status != 0
|
561
562
|
raise RuntimeError,
|
562
|
-
%Q{Could not find the
|
563
|
+
%Q{Could not find the process details of #{sim_name} with:
|
563
564
|
|
564
565
|
#{args.join(" ")}
|
565
566
|
|
566
|
-
Command exited with status #{exit_status}
|
567
|
-
|
567
|
+
Command exited with status: #{exit_status}
|
568
|
+
|
569
|
+
'#{hash[:out]}'
|
568
570
|
}
|
569
571
|
end
|
570
572
|
|
571
573
|
if hash[:out].nil? || hash[:out] == ""
|
572
574
|
raise RuntimeError,
|
573
|
-
%Q{Could not find the
|
575
|
+
%Q{Could not find the process details of #{sim_name} with:
|
574
576
|
|
575
577
|
#{args.join(" ")}
|
576
578
|
|
577
|
-
Command had no output
|
579
|
+
Command had no output.
|
578
580
|
}
|
579
581
|
end
|
580
582
|
|
581
|
-
lines = hash[:out].split(
|
583
|
+
lines = hash[:out].split($-0)
|
582
584
|
|
583
585
|
match = lines.detect do |line|
|
584
|
-
line[/#{process_name}
|
586
|
+
line[/#{process_name}/]
|
585
587
|
end
|
586
588
|
|
587
|
-
return
|
589
|
+
return {} if match.nil?
|
590
|
+
|
591
|
+
hash = {}
|
592
|
+
|
593
|
+
pid = match.split(" ").first.strip.to_i
|
594
|
+
hash[:pid] = pid
|
595
|
+
|
596
|
+
hash[:launched_by_run_loop] = match[/LAUNCHED_BY_RUN_LOOP/]
|
597
|
+
|
598
|
+
hash
|
599
|
+
end
|
600
|
+
|
601
|
+
# @!visibility private
|
602
|
+
def uninstall_app_with_simctl
|
603
|
+
launch_simulator
|
604
|
+
|
605
|
+
app_size = RunLoop::Directory.size(app.path, :mb)
|
606
|
+
sim_size = device.simulator_size_on_disk
|
607
|
+
target_size = sim_size - app_size + 5
|
608
|
+
|
609
|
+
timeout = DEFAULT_OPTIONS[:install_app_timeout]
|
610
|
+
simctl.uninstall(device, app, timeout)
|
611
|
+
|
612
|
+
current_size = device.simulator_size_on_disk
|
613
|
+
start = Time.now
|
614
|
+
while current_size > target_size && Time.now < start + 5
|
615
|
+
sleep(0.5)
|
616
|
+
current_size = device.simulator_size_on_disk
|
617
|
+
end
|
588
618
|
|
589
|
-
|
619
|
+
elapsed = Time.now - start
|
620
|
+
if current_size <= target_size
|
621
|
+
RunLoop.log_debug("Waited for #{elapsed} seconds for app to uninstall")
|
622
|
+
else
|
623
|
+
RunLoop.log_debug("Timed out after #{elapsed} seconds for app to uninstall")
|
624
|
+
RunLoop.log_debug("Expected sim size #{current_size} < #{target_size}")
|
625
|
+
end
|
590
626
|
end
|
591
627
|
|
592
628
|
# @!visibility private
|
593
629
|
def install_app_with_simctl
|
594
630
|
launch_simulator
|
595
631
|
|
632
|
+
app_size = RunLoop::Directory.size(app.path, :mb)
|
633
|
+
sim_size = device.simulator_size_on_disk
|
634
|
+
target_size = sim_size + app_size
|
635
|
+
|
596
636
|
timeout = DEFAULT_OPTIONS[:install_app_timeout]
|
597
637
|
simctl.install(device, app, timeout)
|
598
638
|
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
639
|
+
current_size = device.simulator_size_on_disk
|
640
|
+
start = Time.now
|
641
|
+
while current_size <= target_size && Time.now < start + 5
|
642
|
+
sleep(0.5)
|
643
|
+
current_size = device.simulator_size_on_disk
|
644
|
+
end
|
645
|
+
|
646
|
+
elapsed = Time.now - start
|
647
|
+
if current_size > target_size
|
648
|
+
RunLoop.log_debug("Waited for #{elapsed} seconds for app to install")
|
649
|
+
else
|
650
|
+
RunLoop.log_debug("Timed out after #{elapsed} seconds for app to install")
|
651
|
+
RunLoop.log_debug("Expected sim size #{current_size} >= #{target_size}")
|
652
|
+
end
|
653
|
+
|
605
654
|
installed_app_bundle_dir
|
606
655
|
end
|
607
656
|
|
@@ -657,6 +706,86 @@ Command had no output
|
|
657
706
|
device.version >= RunLoop::Version.new('8.0')
|
658
707
|
end
|
659
708
|
|
709
|
+
# @!visibility private
|
710
|
+
def simulator_state_requires_relaunch?
|
711
|
+
running_sim_details = running_simulator_details
|
712
|
+
|
713
|
+
# Simulator is not running.
|
714
|
+
if !running_sim_details[:pid]
|
715
|
+
RunLoop.log_debug("Simulator relaunch required: simulator is not running.")
|
716
|
+
return true
|
717
|
+
end
|
718
|
+
|
719
|
+
# Simulator is running, but run-loop did not launch it.
|
720
|
+
if !running_sim_details[:launched_by_run_loop]
|
721
|
+
RunLoop.log_debug("Simulator relaunch required: simulator was not launched by run_loop")
|
722
|
+
return true
|
723
|
+
end
|
724
|
+
|
725
|
+
# No device was passed to initializer.
|
726
|
+
return true if device.nil?
|
727
|
+
|
728
|
+
# Simulator is running, run_loop launched it, but it is not Booted.
|
729
|
+
device.update_simulator_state
|
730
|
+
if device.state == "Booted"
|
731
|
+
RunLoop.log_debug("Simulator relaunch not required: simulator has state 'Booted'")
|
732
|
+
false
|
733
|
+
else
|
734
|
+
RunLoop.log_debug("Simulator relaunch required: simulator does not have state 'Booted'")
|
735
|
+
true
|
736
|
+
end
|
737
|
+
end
|
738
|
+
|
739
|
+
# @!visibility private
|
740
|
+
def running_apps_require_relaunch?
|
741
|
+
running_apps = device.simulator_running_app_details
|
742
|
+
|
743
|
+
if running_apps.empty?
|
744
|
+
RunLoop.log_debug("Simulator relaunch not required: no running apps")
|
745
|
+
return false
|
746
|
+
end
|
747
|
+
|
748
|
+
# DeviceAgent is running, but it was launched by Xcode.
|
749
|
+
if running_apps["XCTRunner"]
|
750
|
+
if running_apps["XCTRunner"][:args][/CBX_LAUNCHED_BY_XCODE/]
|
751
|
+
RunLoop.log_debug("Simulator relaunch required: XCTRunner is controlled by Xcode")
|
752
|
+
return true
|
753
|
+
end
|
754
|
+
end
|
755
|
+
|
756
|
+
# No app was passed to initializer.
|
757
|
+
return true if app.nil?
|
758
|
+
|
759
|
+
# AUT is running, but it was not launched by DeviceAgent.
|
760
|
+
app_name = app.executable_name
|
761
|
+
if running_apps[app_name]
|
762
|
+
launch_arg = RunLoop::DeviceAgent::Client::AUT_LAUNCHED_BY_RUN_LOOP_ARG
|
763
|
+
if !running_apps[app_name][:args][/#{launch_arg}/]
|
764
|
+
RunLoop.log_debug("Simulator relaunch required: AUT is running, but not launched by run-loop")
|
765
|
+
return true
|
766
|
+
end
|
767
|
+
end
|
768
|
+
|
769
|
+
# This is the UITest behavior. UITest does not inspect the simulator for
|
770
|
+
# system apps that are running - it only checks for running user apps.
|
771
|
+
#
|
772
|
+
# I don't think this condition is necessary, so we'll skip it for now, but
|
773
|
+
# capture there is a difference between UITest and run-loop.
|
774
|
+
#
|
775
|
+
# There is some other application running on the simulator.
|
776
|
+
# running_apps.delete("XCTRunner")
|
777
|
+
# running_apps.delete(app_name)
|
778
|
+
#
|
779
|
+
# if running_apps.empty?
|
780
|
+
# RunLoop.log_debug("Simulator relaunch not required: only XCTRunner and AUT are running")
|
781
|
+
# false
|
782
|
+
# else
|
783
|
+
# RunLoop.log_debug("Simulator relaunch required: other applications are running")
|
784
|
+
# true
|
785
|
+
# end
|
786
|
+
false
|
787
|
+
end
|
788
|
+
|
660
789
|
# The data directory for the the device.
|
661
790
|
#
|
662
791
|
# ~/Library/Developer/CoreSimulator/Devices/<UDID>/data
|
@@ -850,20 +979,8 @@ Command had no output
|
|
850
979
|
RunLoop.log_debug(" App to launch SHA: #{app_sha}")
|
851
980
|
RunLoop.log_debug("Will install #{app}")
|
852
981
|
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
directory = File.expand_path(File.join(installed_app_bundle, '..'))
|
857
|
-
bundle_name = File.basename(app.path)
|
858
|
-
target = File.join(directory, bundle_name)
|
859
|
-
|
860
|
-
args = ['ditto', app.path, target]
|
861
|
-
xcrun.run_command_in_context(args, log_cmd: true)
|
862
|
-
|
863
|
-
RunLoop.log_debug("Installed #{app} on CoreSimulator #{device.udid}")
|
864
|
-
|
865
|
-
clear_device_launch_csstore
|
866
|
-
|
982
|
+
uninstall_app_with_simctl
|
983
|
+
install_app_with_simctl
|
867
984
|
true
|
868
985
|
end
|
869
986
|
|
@@ -966,7 +1083,7 @@ Command had no output
|
|
966
1083
|
|
967
1084
|
# @!visibility private
|
968
1085
|
def self.user_app_installed?(device, bundle_identifier)
|
969
|
-
core_sim = self.new(device, bundle_identifier
|
1086
|
+
core_sim = self.new(device, bundle_identifier)
|
970
1087
|
sim_apps_dir = core_sim.send(:device_applications_dir)
|
971
1088
|
Dir.glob("#{sim_apps_dir}/**/*.app").find do |path|
|
972
1089
|
RunLoop::App.new(path).bundle_identifier == bundle_identifier
|