run_loop 2.1.2 → 2.1.3

Sign up to get free protection for your applications and to get access to all the features.
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