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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 153c09febc934625b8890c29fbead9efd47ccec9
4
- data.tar.gz: def40d52e20c4e6eff000a13b14ebedaf989b11c
3
+ metadata.gz: f87d14b21bab0d48f84d2d4793f5f38b7c75e537
4
+ data.tar.gz: 9e565515f6f9abcc1926424c17473dca66c05222
5
5
  SHA512:
6
- metadata.gz: e8e4c05e8d8ffc9287c9f8b9b8c7db070eab11580d6219156f6c25d59938448ef6a617136a54184b6459f7c66f3741352f6234c5d27cdafb3fe4300e2f8403a6
7
- data.tar.gz: f2896bcd29d50e34bdc418bd3f255bddb8e0adb172263e3a5a8859662ec4aa7437485754a9e35def02b682e069dd768acb97ed5074859ebf82083c3d3d772694
6
+ metadata.gz: b1c91bc8ef53e04e8766d9b2f7fffb11ff0ddf3dc940e6ac996bee128a64bce81b70f92eaa71af466862a491f0519cbfd5b8eab2479baf481b42552839c3ca69
7
+ data.tar.gz: bb0eaeef42beda6c2e9622f5b1d55a3e09f5f793b0fb0d1b0fc36935617937d0b8c8826355cdab218d57b82f6701ab26c84cc831e3092b8effc33e869c39e204
@@ -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
@@ -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.expand_path('~/Library/Developer/CoreSimulator/Devices')
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
- RunLoop::Environment.bundle_id
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.expand_path("~/Library/Developer/Xcode/DerivedData")
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.expand_path('~/Library/Preferences/com.apple.dt.Xcode.plist')
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
@@ -563,10 +563,17 @@ version: #{version}
563
563
  end
564
564
 
565
565
  # @!visibility private
566
- CORE_SIMULATOR_DEVICE_DIR = File.expand_path('~/Library/Developer/CoreSimulator/Devices')
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.expand_path('~/Library/Logs/CoreSimulator')
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)
@@ -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
@@ -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