run_loop 2.1.2 → 2.1.3
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.
- checksums.yaml +4 -4
- data/lib/run_loop.rb +7 -0
- data/lib/run_loop/abstract.rb +18 -0
- data/lib/run_loop/core.rb +30 -1
- data/lib/run_loop/core_simulator.rb +5 -1
- data/lib/run_loop/detect_aut/detect.rb +8 -2
- data/lib/run_loop/detect_aut/xcode.rb +6 -2
- data/lib/run_loop/device.rb +9 -2
- data/lib/run_loop/device_agent/app/CBX-Runner.app.zip +0 -0
- data/lib/run_loop/device_agent/bin/xctestctl +0 -0
- data/lib/run_loop/device_agent/cbxrunner.rb +155 -0
- data/lib/run_loop/device_agent/frameworks.rb +64 -0
- data/lib/run_loop/device_agent/frameworks/Frameworks.zip +0 -0
- data/lib/run_loop/device_agent/ipa/CBX-Runner.app.zip +0 -0
- data/lib/run_loop/device_agent/launcher.rb +51 -0
- data/lib/run_loop/device_agent/xcodebuild.rb +91 -0
- data/lib/run_loop/device_agent/xctestctl.rb +109 -0
- data/lib/run_loop/dylib_injector.rb +10 -1
- data/lib/run_loop/environment.rb +66 -0
- data/lib/run_loop/host_cache.rb +7 -2
- data/lib/run_loop/physical_device/{ideviceinstaller.rb → life_cycle.rb} +86 -39
- data/lib/run_loop/sim_control.rb +8 -3
- data/lib/run_loop/version.rb +1 -1
- data/lib/run_loop/xcuitest.rb +134 -116
- data/scripts/lib/log.js +1 -1
- data/scripts/lib/on_alert.js +102 -17
- data/vendor-licenses/FBSimulatorControl.LICENSE +30 -0
- data/vendor-licenses/xctestctl.LICENSE +32 -0
- metadata +15 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f87d14b21bab0d48f84d2d4793f5f38b7c75e537
|
4
|
+
data.tar.gz: 9e565515f6f9abcc1926424c17473dca66c05222
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b1c91bc8ef53e04e8766d9b2f7fffb11ff0ddf3dc940e6ac996bee128a64bce81b70f92eaa71af466862a491f0519cbfd5b8eab2479baf481b42552839c3ca69
|
7
|
+
data.tar.gz: bb0eaeef42beda6c2e9622f5b1d55a3e09f5f793b0fb0d1b0fc36935617937d0b8c8826355cdab218d57b82f6701ab26c84cc831e3092b8effc33e869c39e204
|
data/lib/run_loop.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require "run_loop/abstract"
|
1
2
|
require 'run_loop/regex'
|
2
3
|
require 'run_loop/directory'
|
3
4
|
require "run_loop/encoding"
|
@@ -19,6 +20,11 @@ require 'run_loop/plist_buddy'
|
|
19
20
|
require "run_loop/codesign"
|
20
21
|
require 'run_loop/app'
|
21
22
|
require 'run_loop/ipa'
|
23
|
+
require "run_loop/device_agent/cbxrunner"
|
24
|
+
require "run_loop/device_agent/frameworks"
|
25
|
+
require "run_loop/device_agent/launcher"
|
26
|
+
require "run_loop/device_agent/xctestctl"
|
27
|
+
require "run_loop/device_agent/xcodebuild"
|
22
28
|
require "run_loop/detect_aut/errors"
|
23
29
|
require "run_loop/detect_aut/xamarin_studio"
|
24
30
|
require "run_loop/detect_aut/xcode"
|
@@ -42,6 +48,7 @@ require "run_loop/http/error"
|
|
42
48
|
require "run_loop/http/server"
|
43
49
|
require "run_loop/http/request"
|
44
50
|
require "run_loop/http/retriable_client"
|
51
|
+
require "run_loop/physical_device/life_cycle"
|
45
52
|
|
46
53
|
module RunLoop
|
47
54
|
|
@@ -0,0 +1,18 @@
|
|
1
|
+
|
2
|
+
module RunLoop
|
3
|
+
module Abstract
|
4
|
+
# @!visibility private
|
5
|
+
class AbstractMethodError < StandardError; end
|
6
|
+
|
7
|
+
# @!visibility private
|
8
|
+
def abstract_method!
|
9
|
+
if Kernel.method_defined?(:caller_locations)
|
10
|
+
method_name = icaller_locations.first.label
|
11
|
+
else
|
12
|
+
method_name = caller.first[/\`(.*)\'/, 1]
|
13
|
+
end
|
14
|
+
|
15
|
+
raise AbstractMethodError.new("Abstract method '#{method_name}'")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/run_loop/core.rb
CHANGED
@@ -145,11 +145,40 @@ module RunLoop
|
|
145
145
|
:script => script,
|
146
146
|
:log_file => log_file,
|
147
147
|
:args => args,
|
148
|
-
:uia_strategy => uia_strategy
|
148
|
+
:uia_strategy => uia_strategy,
|
149
|
+
:base_script => instruments_script
|
149
150
|
}
|
150
151
|
merged_options = options.merge(discovered_options)
|
151
152
|
|
152
153
|
if device.simulator?
|
154
|
+
if !app_details[:app]
|
155
|
+
raise %Q[
|
156
|
+
|
157
|
+
Invalid APP, APP_BUNDLE_PATH, or BUNDLE_ID detected.
|
158
|
+
|
159
|
+
The following information was detected from the environment:
|
160
|
+
|
161
|
+
APP='#{ENV["APP"]}'
|
162
|
+
APP_BUNDLE_PATH='#{ENV["APP_BUNDLE_PATH"]}'
|
163
|
+
BUNDLE_ID='#{ENV["BUNDLE_ID"]}'
|
164
|
+
|
165
|
+
|
166
|
+
It looks like you are trying to launch an app on a simulator using a bundle
|
167
|
+
identifier or you have incorrectly set the APP variable to an app bundle that
|
168
|
+
does not exist.
|
169
|
+
|
170
|
+
If you are trying to launch a test against a physical device, set the DEVICE_TARGET
|
171
|
+
variable to the UDID of your device an APP to a bundle identifier or a path to
|
172
|
+
an .ipa.
|
173
|
+
|
174
|
+
# com.example.MyApp must be installed on the target device
|
175
|
+
$ APP=com.example.MyApp DEVICE_TARGET="John's iPhone" cucumber
|
176
|
+
|
177
|
+
If you are trying to launch against a simulator and you encounter this error, it
|
178
|
+
means that the APP variable is pointing to a .app that does not exist.
|
179
|
+
|
180
|
+
]
|
181
|
+
end
|
153
182
|
self.prepare_simulator(app_details[:app], device, xcode, simctl, reset_options)
|
154
183
|
end
|
155
184
|
|
@@ -48,7 +48,11 @@ class RunLoop::CoreSimulator
|
|
48
48
|
METADATA_PLIST = '.com.apple.mobile_container_manager.metadata.plist'
|
49
49
|
|
50
50
|
# @!visibility private
|
51
|
-
CORE_SIMULATOR_DEVICE_DIR = File.
|
51
|
+
CORE_SIMULATOR_DEVICE_DIR = File.join(RunLoop::Environment.user_home_directory,
|
52
|
+
"Library",
|
53
|
+
"Developer",
|
54
|
+
"CoreSimulator",
|
55
|
+
"Devices")
|
52
56
|
|
53
57
|
|
54
58
|
# @!visibility private
|
@@ -131,8 +131,14 @@ module RunLoop
|
|
131
131
|
|
132
132
|
# @!visibility private
|
133
133
|
def self.app_from_environment
|
134
|
-
RunLoop::Environment.path_to_app_bundle
|
135
|
-
|
134
|
+
app_bundle_path = RunLoop::Environment.path_to_app_bundle
|
135
|
+
|
136
|
+
candidate = app_bundle_path
|
137
|
+
if app_bundle_path && !File.exist?(app_bundle_path)
|
138
|
+
candidate = File.basename(app_bundle_path)
|
139
|
+
end
|
140
|
+
|
141
|
+
candidate || RunLoop::Environment.bundle_id
|
136
142
|
end
|
137
143
|
|
138
144
|
# @!visibility private
|
@@ -135,12 +135,16 @@ module RunLoop
|
|
135
135
|
# @!visibility private
|
136
136
|
def derived_data
|
137
137
|
RunLoop::Environment.derived_data ||
|
138
|
-
File.
|
138
|
+
File.join(RunLoop::Environment.user_home_directory,
|
139
|
+
"Library", "Developer", "Xcode", "DerivedData")
|
139
140
|
end
|
140
141
|
|
141
142
|
# @!visibility private
|
142
143
|
def xcode_preferences_plist
|
143
|
-
File.
|
144
|
+
File.join(RunLoop::Environment.user_home_directory,
|
145
|
+
"Library",
|
146
|
+
"Preferences",
|
147
|
+
"com.apple.dt.Xcode.plist")
|
144
148
|
end
|
145
149
|
|
146
150
|
# @!visibility private
|
data/lib/run_loop/device.rb
CHANGED
@@ -563,10 +563,17 @@ version: #{version}
|
|
563
563
|
end
|
564
564
|
|
565
565
|
# @!visibility private
|
566
|
-
CORE_SIMULATOR_DEVICE_DIR = File.
|
566
|
+
CORE_SIMULATOR_DEVICE_DIR = File.join(RunLoop::Environment.user_home_directory,
|
567
|
+
"Library",
|
568
|
+
"Developer",
|
569
|
+
"CoreSimulator",
|
570
|
+
"Devices")
|
567
571
|
|
568
572
|
# @!visibility private
|
569
|
-
CORE_SIMULATOR_LOGS_DIR = File.
|
573
|
+
CORE_SIMULATOR_LOGS_DIR = File.join(RunLoop::Environment.user_home_directory,
|
574
|
+
"Library",
|
575
|
+
"Logs",
|
576
|
+
"CoreSimulator")
|
570
577
|
|
571
578
|
# @!visibility private
|
572
579
|
def self.device_from_options(options)
|
Binary file
|
Binary file
|
@@ -0,0 +1,155 @@
|
|
1
|
+
|
2
|
+
module RunLoop
|
3
|
+
# @!visibility private
|
4
|
+
module DeviceAgent
|
5
|
+
# @!visibility private
|
6
|
+
class CBXRunner
|
7
|
+
|
8
|
+
require "run_loop/shell"
|
9
|
+
|
10
|
+
# @!visibility private
|
11
|
+
@@cbxdevice = nil
|
12
|
+
|
13
|
+
# @!visibility private
|
14
|
+
@@cbxsim = nil
|
15
|
+
|
16
|
+
# @!visibility private
|
17
|
+
def self.device_agent_dir
|
18
|
+
@@device_agent_dir ||= File.expand_path(File.dirname(__FILE__))
|
19
|
+
end
|
20
|
+
|
21
|
+
# @!visibility private
|
22
|
+
def self.detect_cbxsim
|
23
|
+
@@cbxsim ||= lambda do
|
24
|
+
from_env = RunLoop::Environment.cbxsim
|
25
|
+
|
26
|
+
if from_env
|
27
|
+
if File.exist?(from_env)
|
28
|
+
from_env
|
29
|
+
else
|
30
|
+
raise RuntimeError, %Q[
|
31
|
+
CBXSIM environment variable defined:
|
32
|
+
|
33
|
+
#{from_env}
|
34
|
+
|
35
|
+
but runner does not exist at that path.
|
36
|
+
]
|
37
|
+
end
|
38
|
+
else
|
39
|
+
self.default_cbxsim
|
40
|
+
end
|
41
|
+
end.call
|
42
|
+
end
|
43
|
+
|
44
|
+
# @!visibility private
|
45
|
+
def self.detect_cbxdevice
|
46
|
+
@@cbxdevice ||= lambda do
|
47
|
+
from_env = RunLoop::Environment.cbxdevice
|
48
|
+
|
49
|
+
if from_env
|
50
|
+
if File.exist?(from_env)
|
51
|
+
from_env
|
52
|
+
else
|
53
|
+
raise RuntimeError, %Q[
|
54
|
+
CBXDEVICE environment variable defined:
|
55
|
+
|
56
|
+
#{from_env}
|
57
|
+
|
58
|
+
but runner does not exist at that path.
|
59
|
+
]
|
60
|
+
end
|
61
|
+
else
|
62
|
+
self.default_cbxdevice
|
63
|
+
end
|
64
|
+
end.call
|
65
|
+
end
|
66
|
+
|
67
|
+
# @!visibility private
|
68
|
+
def self.default_cbxdevice
|
69
|
+
cbx = File.join(self.device_agent_dir, "ipa", "CBX-Runner.app")
|
70
|
+
|
71
|
+
if !File.exist?(cbx)
|
72
|
+
self.expand_runner_archive("#{cbx}.zip")
|
73
|
+
else
|
74
|
+
cbx
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# @!visibility private
|
79
|
+
def self.default_cbxsim
|
80
|
+
cbx = File.join(self.device_agent_dir, "app", "CBX-Runner.app")
|
81
|
+
|
82
|
+
if !File.exist?(cbx)
|
83
|
+
self.expand_runner_archive("#{cbx}.zip")
|
84
|
+
else
|
85
|
+
cbx
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# @!visibility private
|
90
|
+
def self.expand_runner_archive(archive)
|
91
|
+
shell = Class.new do
|
92
|
+
include RunLoop::Shell
|
93
|
+
def to_s; "#<CBXRunner Shell>"; end
|
94
|
+
def inspect; to_s; end
|
95
|
+
end.new
|
96
|
+
|
97
|
+
dir = File.dirname(archive)
|
98
|
+
options = { :log_cmd => true }
|
99
|
+
Dir.chdir(dir) do
|
100
|
+
RunLoop.log_unix_cmd("cd #{dir}")
|
101
|
+
shell.exec(["unzip", File.basename(archive)], options)
|
102
|
+
end
|
103
|
+
File.join(dir, "CBX-Runner.app")
|
104
|
+
end
|
105
|
+
|
106
|
+
# @!visibility private
|
107
|
+
attr_reader :device
|
108
|
+
|
109
|
+
# @!visibility private
|
110
|
+
# @param [RunLoop::Device] device the target device
|
111
|
+
def initialize(device)
|
112
|
+
@device = device
|
113
|
+
end
|
114
|
+
|
115
|
+
# @!visibility private
|
116
|
+
def runner
|
117
|
+
@runner ||= lambda do
|
118
|
+
if device.physical_device?
|
119
|
+
RunLoop::DeviceAgent::CBXRunner.detect_cbxdevice
|
120
|
+
else
|
121
|
+
RunLoop::DeviceAgent::CBXRunner.detect_cbxsim
|
122
|
+
end
|
123
|
+
end.call
|
124
|
+
end
|
125
|
+
|
126
|
+
# @!visibility private
|
127
|
+
def tester
|
128
|
+
@tester ||= File.join(runner, "PlugIns", "CBX.xctest")
|
129
|
+
end
|
130
|
+
|
131
|
+
# @!visibility private
|
132
|
+
def version
|
133
|
+
@version ||= lambda do
|
134
|
+
short = pbuddy.plist_read("CFBundleShortVersionString", info_plist)
|
135
|
+
build = pbuddy.plist_read("CFBundleVersion", info_plist)
|
136
|
+
str = "#{short}.pre#{build}"
|
137
|
+
RunLoop::Version.new(str)
|
138
|
+
end.call
|
139
|
+
end
|
140
|
+
|
141
|
+
private
|
142
|
+
|
143
|
+
# @!visibility private
|
144
|
+
def info_plist
|
145
|
+
@info_plist ||= File.join(runner, "PlugIns", "CBX.xctest", "Info.plist")
|
146
|
+
end
|
147
|
+
|
148
|
+
# @!visibility private
|
149
|
+
def pbuddy
|
150
|
+
@pbuddy ||= RunLoop::PlistBuddy.new
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
@@ -0,0 +1,64 @@
|
|
1
|
+
|
2
|
+
module RunLoop
|
3
|
+
# @!visibility private
|
4
|
+
module DeviceAgent
|
5
|
+
# @!visibility private
|
6
|
+
class Frameworks
|
7
|
+
require "run_loop/shell"
|
8
|
+
require "singleton"
|
9
|
+
include Singleton
|
10
|
+
|
11
|
+
# @!visibility private
|
12
|
+
def install
|
13
|
+
if File.exist?(frameworks)
|
14
|
+
RunLoop.log_debug("#{frameworks} already exists; skipping install")
|
15
|
+
return true
|
16
|
+
end
|
17
|
+
|
18
|
+
RunLoop.log_debug("Installing Frameworks to #{target}")
|
19
|
+
|
20
|
+
options = { :log_cmd => true }
|
21
|
+
|
22
|
+
Dir.chdir(rootdir) do
|
23
|
+
RunLoop.log_unix_cmd("cd #{rootdir}")
|
24
|
+
shell.exec(["unzip", File.basename(zip)], options)
|
25
|
+
end
|
26
|
+
|
27
|
+
shell.exec(["cp", "-r", "#{frameworks}/*.framework", target], options)
|
28
|
+
shell.exec(["cp", "#{frameworks}/*LICENSE", target], options)
|
29
|
+
RunLoop.log_debug("Installed frameworks to #{target}")
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
# @!visibility private
|
35
|
+
def shell
|
36
|
+
Class.new do
|
37
|
+
include RunLoop::Shell
|
38
|
+
def to_s; "#<Frameworks Shell>"; end
|
39
|
+
def inspect; to_s; end
|
40
|
+
end.new
|
41
|
+
end
|
42
|
+
|
43
|
+
# @!visibility private
|
44
|
+
def target
|
45
|
+
@target ||= File.join(RunLoop::DotDir.directory, "Frameworks")
|
46
|
+
end
|
47
|
+
|
48
|
+
# @!visibility private
|
49
|
+
def frameworks
|
50
|
+
@frameworks ||= File.join(rootdir, "Frameworks")
|
51
|
+
end
|
52
|
+
|
53
|
+
# @!visibility private
|
54
|
+
def zip
|
55
|
+
@zip ||= File.join(rootdir, "Frameworks.zip")
|
56
|
+
end
|
57
|
+
|
58
|
+
# @!visibility private
|
59
|
+
def rootdir
|
60
|
+
@rootdir ||= File.expand_path(File.join(File.dirname(__FILE__), "frameworks"))
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
Binary file
|
Binary file
|
@@ -0,0 +1,51 @@
|
|
1
|
+
|
2
|
+
module RunLoop
|
3
|
+
# @!visibility private
|
4
|
+
module DeviceAgent
|
5
|
+
# @!visibility private
|
6
|
+
#
|
7
|
+
# An abstract base class for something that can launch the CBXRunner on a
|
8
|
+
# device. The CBXRunner is AKA the DeviceAgent.
|
9
|
+
class Launcher
|
10
|
+
require "run_loop/abstract"
|
11
|
+
include RunLoop::Abstract
|
12
|
+
|
13
|
+
# @!visibility private
|
14
|
+
attr_reader :device
|
15
|
+
|
16
|
+
# @!visibility private
|
17
|
+
# @param [RunLoop::Device] device where to launch the CBX-Runner
|
18
|
+
def initialize(device)
|
19
|
+
@device = device
|
20
|
+
|
21
|
+
if device.version < RunLoop::Version.new("9.0")
|
22
|
+
raise ArgumentError, %Q[
|
23
|
+
Invalid device:
|
24
|
+
|
25
|
+
#{device}
|
26
|
+
|
27
|
+
XCUITest is only available for iOS >= 9.0
|
28
|
+
]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# @!visibility private
|
33
|
+
#
|
34
|
+
# Does whatever it takes to launch the CBX-Runner on the device.
|
35
|
+
def launch
|
36
|
+
abstract_method!
|
37
|
+
end
|
38
|
+
|
39
|
+
# @!visibility private
|
40
|
+
def self.dot_dir
|
41
|
+
path = File.join(RunLoop::DotDir.directory, "xcuitest")
|
42
|
+
|
43
|
+
if !File.exist?(path)
|
44
|
+
FileUtils.mkdir_p(path)
|
45
|
+
end
|
46
|
+
|
47
|
+
path
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|