run_loop 2.0.6 → 2.0.7

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: e713b8074f4a98cc789fe39327c63c675d8483cb
4
- data.tar.gz: 98d467c958129c5a33efa0fe654088f38b0b7b0f
3
+ metadata.gz: 48c1c78396cdf8d493ce6d242d09b2a36884fe5e
4
+ data.tar.gz: 83cfc779ce7803e4deae06af1bc7a3a55a299310
5
5
  SHA512:
6
- metadata.gz: 810a32b9c38f9b720129ca06dc8a80cb6d92c4243d8bd7dc4dd62cee55600e19d68f9eb38d7c28643f9ed023d3437e1c9b35beb26a1e9f95a64b8de3a9308a23
7
- data.tar.gz: 0963ce5adff45b9aae3b20cc2635000ea69ef166deef85956461c2808abca49a371140d8a42d911a622a4e88547fbd6e90c713ff63befeaf49087b921ecfb56a
6
+ metadata.gz: 2acc78eed572c025036a5e168b592c0ea00c2ca53cfb8562118a6e603052eccde496fd262ed1c9cb0ab2a1cbefb2d35a306829c8e7725bfc51842c404f172599
7
+ data.tar.gz: 6d0a90bf5529840121434d05ec23948bd0cc50a1be2fa5bf6616d4748154b479e8e1eff07bc7cf35447610a43805649b4a32e3ee76f987a057052bfbf8f1bf44
@@ -14,6 +14,7 @@ require 'run_loop/fifo'
14
14
  require 'run_loop/core'
15
15
  require 'run_loop/version'
16
16
  require 'run_loop/plist_buddy'
17
+ require "run_loop/codesign"
17
18
  require 'run_loop/app'
18
19
  require 'run_loop/ipa'
19
20
  require 'run_loop/sim_control'
@@ -30,6 +31,11 @@ require 'run_loop/simctl/plists'
30
31
  require 'run_loop/template'
31
32
  require "run_loop/locale"
32
33
  require "run_loop/language"
34
+ require "run_loop/xcuitest"
35
+ require "run_loop/http/error"
36
+ require "run_loop/http/server"
37
+ require "run_loop/http/request"
38
+ require "run_loop/http/retriable_client"
33
39
 
34
40
  module RunLoop
35
41
 
@@ -95,6 +95,21 @@ Bundle must:
95
95
  version
96
96
  end
97
97
 
98
+ # @!visibility private
99
+ def codesign_info
100
+ RunLoop::Codesign.info(path)
101
+ end
102
+
103
+ # @!visibility private
104
+ def developer_signed?
105
+ RunLoop::Codesign.developer?(path)
106
+ end
107
+
108
+ # @!visibility private
109
+ def distribution_signed?
110
+ RunLoop::Codesign.distribution?(path)
111
+ end
112
+
98
113
  # @!visibility private
99
114
  # Collects the paths to executables in the bundle.
100
115
  def executables
@@ -4,6 +4,7 @@ require 'run_loop/cli/errors'
4
4
  require 'run_loop/cli/instruments'
5
5
  require 'run_loop/cli/simctl'
6
6
  require "run_loop/cli/locale"
7
+ require "run_loop/cli/codesign"
7
8
 
8
9
  trap 'SIGINT' do
9
10
  puts 'Trapped SIGINT - exiting'
@@ -35,6 +36,9 @@ module RunLoop
35
36
  desc "locale", "Tools for interacting with locales"
36
37
  subcommand "locale", RunLoop::CLI::Locale
37
38
 
39
+ desc "codesign", "Tools for interacting with codesign"
40
+ subcommand "codesign", RunLoop::CLI::Codesign
41
+
38
42
  end
39
43
  end
40
44
  end
@@ -0,0 +1,24 @@
1
+ require "thor"
2
+ require "run_loop"
3
+ require "run_loop/cli/errors"
4
+
5
+ module RunLoop
6
+ module CLI
7
+ class Codesign < Thor
8
+
9
+ desc "info ARTIFACT", "Print codesign information about ARTIFACT (ipa, app, or library)"
10
+
11
+ def info(app_or_ipa)
12
+ extension = File.extname(app_or_ipa)
13
+
14
+ if extension == ".app"
15
+ puts RunLoop::App.new(app_or_ipa).codesign_info
16
+ elsif extension == ".ipa"
17
+ puts RunLoop::Ipa.new(app_or_ipa).codesign_info
18
+ else
19
+ puts RunLoop::Codesign.info(app_or_ipa)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,76 @@
1
+ module RunLoop
2
+ # @!visibility private
3
+ # A wrapper around codesign command line tool
4
+ class Codesign
5
+
6
+ # @!visibility private
7
+ DEV_REGEX = /Authority=iPhone Developer:/
8
+
9
+ # @!visibility private
10
+ APP_STORE_REGEX = /Authority=Apple iPhone OS Application Signing/
11
+
12
+ # @!visibility private
13
+ DISTR_REGEX = /Authority=iPhone Distribution:/
14
+
15
+ # @!visibility private
16
+ NOT_SIGNED_REGEX = /code object is not signed at all/
17
+
18
+ # @!visibility private
19
+ def self.info(path)
20
+ self.expect_path_exists(path)
21
+ self.exec(["--display", "--verbose=4", path])
22
+ end
23
+
24
+ # @!visibility private
25
+ #
26
+ # True if the asset is signed.
27
+ def self.signed?(path)
28
+ info = self.info(path)
29
+ info[NOT_SIGNED_REGEX, 0] == nil
30
+ end
31
+
32
+ # @!visibility private
33
+ #
34
+ # True if the asset is signed with anything other than a dev cert.
35
+ def self.distribution?(path)
36
+ info = self.info(path)
37
+
38
+ info[NOT_SIGNED_REGEX, 0] == nil &&
39
+ info[DEV_REGEX, 0] == nil
40
+ end
41
+
42
+ # @!visibility private
43
+ #
44
+ # True if the asset is signed with a dev cert
45
+ def self.developer?(path)
46
+ info = self.info(path)
47
+ info[DEV_REGEX, 0] != nil
48
+ end
49
+
50
+ private
51
+
52
+ def self.expect_path_exists(path)
53
+ if !File.exist?(path)
54
+ raise ArgumentError,
55
+ %Q{There is no file or directory at path:
56
+
57
+ #{path}
58
+ }
59
+ end
60
+ end
61
+
62
+ def self.exec(args)
63
+ if !args.is_a?(Array)
64
+ raise ArgumentError, "Expected args: '#{args}' to be an Array"
65
+ end
66
+
67
+ xcrun = RunLoop::Xcrun.new
68
+ cmd = ["codesign"] + args
69
+ options = {:log_cmd => true}
70
+ hash = xcrun.exec(cmd, options)
71
+
72
+ hash[:out]
73
+ end
74
+ end
75
+ end
76
+
@@ -500,6 +500,7 @@ $ bundle exec run-loop simctl manage-processes
500
500
  end
501
501
  end
502
502
  end
503
+
503
504
  # Returns the current simulator name.
504
505
  #
505
506
  # @return [String] A String suitable for searching for a pid, quitting, or
@@ -540,8 +541,6 @@ $ bundle exec run-loop simctl manage-processes
540
541
  # @note Will only search for the current Xcode simulator.
541
542
  #
542
543
  # @return [Integer, nil] The pid as a String or nil if no process is found.
543
- #
544
- # @todo Convert this to force UTF8
545
544
  def running_simulator_pid
546
545
  process_name = "MacOS/#{sim_name}"
547
546
 
@@ -28,6 +28,16 @@ module RunLoop
28
28
  ENV['XAMARIN_TEST_CLOUD'] == '1'
29
29
  end
30
30
 
31
+ # Returns the value of DEVICE_TARGET
32
+ def self.device_target
33
+ ENV["DEVICE_TARGET"]
34
+ end
35
+
36
+ # Returns the value of DEVICE_ENDPOINT
37
+ def self.device_endpoint
38
+ ENV["DEVICE_ENDPOINT"]
39
+ end
40
+
31
41
  # Returns the value of TRACE_TEMPLATE; the Instruments template to use
32
42
  # during testing.
33
43
  def self.trace_template
@@ -0,0 +1,15 @@
1
+ module RunLoop
2
+ module HTTP
3
+
4
+ # Raised when there is a problem communicating with the Calabash test
5
+ # server.
6
+ class Error < StandardError
7
+
8
+ end
9
+
10
+ # Raised when there is a problem creating an HTTP request.
11
+ class RequestError < StandardError
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,44 @@
1
+ module RunLoop
2
+ module HTTP
3
+
4
+ # A representation of an HTTP request that can be passed passed to the HTTP
5
+ # client as an argument for `get` or `post`.
6
+ # @!visibility private
7
+ class Request
8
+ attr_reader :route, :params
9
+
10
+ def initialize(route, params={})
11
+ @route = route
12
+ @params = params
13
+ end
14
+
15
+ # Create a new Request from `route` and `parameters`.
16
+ #
17
+ # @param [String] route The http route for the new request.
18
+ # @param [Array, Hash] parameters An Array or Hash of parameters.
19
+ # @return [Request] A new Request for `route` with `parameters`.
20
+ # @raise [RequestError] Raises an error if the parameters cannot be
21
+ # converted to JSON
22
+ def self.request(route, parameters)
23
+ Request.new(route, Request.data(parameters))
24
+ end
25
+
26
+ private
27
+
28
+ # Converts `parameters` to JSON.
29
+ #
30
+ # @param [Array, Hash] parameters An Array or Hash of parameters.
31
+ # @return [String] A JSON formatted string that represents the parameters.
32
+ # @raise [RequestError] Raises an error if the parameters cannot be
33
+ # converted to JSON
34
+ def self.data(parameters)
35
+ begin
36
+ JSON.generate(parameters)
37
+ rescue *[TypeError, JSON::GeneratorError] => e
38
+ raise RequestError, "#{e}: could not generate JSON from '#{parameters}'"
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+
@@ -0,0 +1,162 @@
1
+ module RunLoop
2
+ module HTTP
3
+ require "httpclient"
4
+
5
+ # An HTTP client that retries its connection on errors and can time out.
6
+ # @!visibility private
7
+ class RetriableClient
8
+ attr_reader :client
9
+
10
+ # @!visibility private
11
+ RETRY_ON =
12
+ [
13
+ # The connection, request, or response timed out
14
+ #HTTPClient::TimeoutError,
15
+ # The address is not found. Useful for polling.
16
+ SocketError,
17
+ # The proxy could not connect to the server (Android)
18
+ # or the server is not running (iOS)
19
+ HTTPClient::KeepAliveDisconnected,
20
+ # No proxy has been set up (Android)
21
+ Errno::ECONNREFUSED,
22
+ # The server sent a partial response
23
+ #Errno::ECONNRESET,
24
+ # Client sent TCP reset (RST) before server has accepted the
25
+ # connection requested by client.
26
+ Errno::ECONNABORTED,
27
+ # The foreign function call call timed out
28
+ #Errno::ETIMEDOUT
29
+ ]
30
+
31
+ # @!visibility private
32
+ HEADER =
33
+ {
34
+ 'Content-Type' => 'application/json;charset=utf-8'
35
+ }
36
+
37
+ # Creates a new retriable client.
38
+ #
39
+ # This initializer takes multiple options. If the option is not
40
+ # documented, it should be considered _private_. You use undocumented
41
+ # options at your own risk.
42
+ #
43
+ # @param [RunLoop::HTTP::Server] server The server to make the HTTP request
44
+ # on.
45
+ # @param [Hash] options Control the retry, timeout, and interval.
46
+ # @option options [Number] :retries (5) How often to retry.
47
+ # @option options [Number] :timeout (5) How long to wait for a response
48
+ # before timing out.
49
+ # @option options [Number] :interval (0.5) How long to sleep between
50
+ # retries.
51
+ def initialize(server, options = {})
52
+ @client = options[:client] || ::HTTPClient.new
53
+ @server = server
54
+ @retries = options.fetch(:retries, 5)
55
+ @timeout = options.fetch(:timeout, 5)
56
+ @interval = options.fetch(:interval, 0.5)
57
+ @on_error = {}
58
+ end
59
+
60
+ # @!visibility private
61
+ def on_error(type, &block)
62
+ @on_error[type] = block
63
+ end
64
+
65
+ # @!visibility private
66
+ def change_server(new_server)
67
+ @server = new_server
68
+ end
69
+
70
+ # Make an HTTP get request.
71
+ #
72
+ # This method takes multiple options. If the option is not documented,
73
+ # it should be considered _private_. You use undocumented options at
74
+ # your own risk.
75
+ #
76
+ # @param [RunLoop::HTTP::Request] request The request.
77
+ # @param [Hash] options Control the retry, timeout, and interval.
78
+ # @option options [Number] :retries (5) How often to retry.
79
+ # @option options [Number] :timeout (5) How long to wait for a response
80
+ # before timing out.
81
+ # @option options [Number] :interval (0.5) How long to sleep between
82
+ # retries.
83
+ def get(request, options={})
84
+ request(request, :get, options)
85
+ end
86
+
87
+ # Make an HTTP post request.
88
+ #
89
+ # This method takes multiple options. If the option is not documented,
90
+ # it should be considered _private_. You use undocumented options at
91
+ # your own risk.
92
+ #
93
+ # @param [RunLoop::HTTP::Request] request The request.
94
+ # @param [Hash] options Control the retry, timeout, and interval.
95
+ # @option options [Number] :retries (5) How often to retry.
96
+ # @option options [Number] :timeout (5) How long to wait for a response
97
+ # before timing out.
98
+ # @option options [Number] :interval (0.5) How long to sleep between
99
+ # retries.
100
+ def post(request, options={})
101
+ request(request, :post, options)
102
+ end
103
+
104
+ private
105
+
106
+ def request(request, request_method, options={})
107
+ retries = options.fetch(:retries, @retries)
108
+ timeout = options.fetch(:timeout, @timeout)
109
+ interval = options.fetch(:interval, @interval)
110
+ header = options.fetch(:header, HEADER)
111
+
112
+ RunLoop.log_debug("HTTP: #{@server.endpoint + request.route} #{options}")
113
+
114
+ start_time = Time.now
115
+ last_error = nil
116
+
117
+ client = @client.dup
118
+ client.receive_timeout = timeout
119
+
120
+ retries.times do |i|
121
+ first_try = i == 0
122
+
123
+ # Subtract the aggregate time we've spent thus far to make sure we're
124
+ # not exceeding the request timeout across retries.
125
+ time_diff = start_time + timeout - Time.now
126
+
127
+ if time_diff <= 0
128
+ raise HTTP::Error, 'Timeout exceeded'
129
+ end
130
+
131
+ client.receive_timeout = [time_diff, client.receive_timeout].min
132
+
133
+ begin
134
+ return client.send(request_method, @server.endpoint + request.route,
135
+ request.params, header)
136
+ rescue *RETRY_ON => e
137
+ RunLoop.log_debug("Rescued http error: #{e}")
138
+
139
+ if first_try
140
+ if @on_error[e.class]
141
+ @on_error[e.class].call(@server)
142
+ end
143
+ end
144
+
145
+ last_error = e
146
+ sleep interval
147
+ end
148
+ end
149
+
150
+ # We should raise helpful messages
151
+ if last_error.is_a?(HTTPClient::KeepAliveDisconnected)
152
+ raise HTTP::Error, "#{last_error}: It is likely your server has crashed."
153
+ elsif last_error.is_a?(SocketError)
154
+ raise HTTP::Error, "#{last_error}: Did your server start and is it on the same network?"
155
+ end
156
+
157
+ raise HTTP::Error, last_error
158
+ end
159
+ end
160
+ end
161
+ end
162
+
@@ -0,0 +1,17 @@
1
+ module RunLoop
2
+ module HTTP
3
+
4
+ # A representation of the RunLoop test server.
5
+ # @!visibility private
6
+ class Server
7
+ attr_reader :endpoint
8
+
9
+ # @param [URI] endpoint The endpoint to reach the test server.
10
+ # running on the device. The port should be included in the URI.
11
+ def initialize(endpoint)
12
+ @endpoint = endpoint
13
+ end
14
+ end
15
+ end
16
+ end
17
+
@@ -51,6 +51,21 @@ module RunLoop
51
51
  app.calabash_server_version
52
52
  end
53
53
 
54
+ # @!visibility private
55
+ def codesign_info
56
+ app.codesign_info
57
+ end
58
+
59
+ # @!visibility private
60
+ def developer_signed?
61
+ app.developer_signed?
62
+ end
63
+
64
+ # @!visibility private
65
+ def distribution_signed?
66
+ app.distribution_signed?
67
+ end
68
+
54
69
  private
55
70
 
56
71
  # @!visibility private
@@ -1,5 +1,5 @@
1
1
  module RunLoop
2
- VERSION = "2.0.6"
2
+ VERSION = "2.0.7"
3
3
 
4
4
  # A model of a software release version that can be used to compare two versions.
5
5
  #
@@ -216,13 +216,41 @@ module RunLoop
216
216
  #```
217
217
  #
218
218
  # @return [String] path to current developer directory
219
+ #
220
+ # @raise [RuntimeError] If path to Xcode.app/Contents/Developer
221
+ # cannot be determined.
219
222
  def developer_dir
220
- @xcode_developer_dir ||=
221
- if RunLoop::Environment.developer_dir
222
- RunLoop::Environment.developer_dir
223
- else
224
- xcode_select_path
225
- end
223
+ @xcode_developer_dir ||= lambda do
224
+ if RunLoop::Environment.developer_dir
225
+ path = RunLoop::Environment.developer_dir
226
+ else
227
+ path = xcode_select_path
228
+ end
229
+
230
+ if !File.directory?(path)
231
+ raise RuntimeError,
232
+ %Q{Cannot determine the active Xcode. Expected an Xcode here:
233
+
234
+ #{path}
235
+
236
+ Check the value of xcode-select:
237
+
238
+ # Does this resolve to a valid Xcode.app/Contents/Developer path?
239
+ $ xcode-select --print-path
240
+
241
+ Is the DEVELOPER_DIR variable set in your environment? You would
242
+ only use this if you have multiple Xcode's installed.
243
+
244
+ $ echo $DEVELOPER_DIR
245
+
246
+ See the man pages for xcrun and xcode-select for details.
247
+
248
+ $ man xcrun
249
+ $ man xcode-select
250
+ }
251
+ end
252
+ path
253
+ end.call
226
254
  end
227
255
 
228
256
  private
@@ -0,0 +1,211 @@
1
+ module RunLoop
2
+
3
+ # @!visibility private
4
+ class XCUITest
5
+
6
+ # @!visibility private
7
+ DEFAULTS = {
8
+ :port => 27753,
9
+ :simulator_ip => "127.0.0.1"
10
+ }
11
+
12
+ # @!visibility private
13
+ def self.workspace
14
+ value = ENV["XCUITEST_WORKSPACE"]
15
+ if value.nil? || value == ""
16
+ return nil
17
+ else
18
+ value
19
+ end
20
+ end
21
+
22
+ # @!visibility private
23
+ def self.log_file
24
+ path = File.join(XCUITest.dot_dir, "xcuitest.log")
25
+
26
+ if !File.exist?(path)
27
+ FileUtils.touch(path)
28
+ end
29
+ path
30
+ end
31
+
32
+ # @!visibility private
33
+ def initialize(bundle_id)
34
+ @bundle_id = bundle_id
35
+ end
36
+
37
+ # @!visibility private
38
+ # TODO: move to Device ?
39
+ # TODO: needs tests for device case
40
+ def url
41
+ if target.simulator?
42
+ "http://#{DEFAULTS[:simulator_ip]}:#{DEFAULTS[:port]}"
43
+ else
44
+ calabash_endpoint = RunLoop::Environment.device_endpoint
45
+ if calabash_endpoint
46
+ base = calabash_endpoint.split(":")[0..1].join(":")
47
+ "http://#{base}:#{DEFAULTS[:port]}"
48
+ else
49
+ device_name = target.name.gsub(/[\'\s]/, "")
50
+ encoding_options = {
51
+ :invalid => :replace, # Replace invalid byte sequences
52
+ :undef => :replace, # Replace anything not defined in ASCII
53
+ :replace => '' # Use a blank for those replacements
54
+ }
55
+ encoded = device_name.encode(Encoding.find("ASCII"), encoding_options)
56
+ "http://#{encoded}.local:27753"
57
+ end
58
+ end
59
+ end
60
+
61
+ # @!visibility private
62
+ def launch_calabus_driver
63
+
64
+ driver_url = url
65
+ server = RunLoop::HTTP::Server.new(driver_url)
66
+ request = RunLoop::HTTP::Request.new("/shutdown", {})
67
+ options = {
68
+ :timeout => 0.5,
69
+ :retries => 1
70
+ }
71
+ client = RunLoop::HTTP::RetriableClient.new(server, options)
72
+
73
+ begin
74
+ response = client.post(request)
75
+ RunLoop.log_debug("Calabus driver says, \"#{response.body}\"")
76
+ sleep(2.0)
77
+ rescue => e
78
+ RunLoop.log_debug("Driver shutdown raised #{e}")
79
+ end
80
+
81
+ workspace = XCUITest.workspace
82
+
83
+ if !workspace || !File.directory?(workspace)
84
+ raise RuntimeError, "No workspace found"
85
+ end
86
+
87
+ destination = target.udid
88
+
89
+ # might be nil
90
+ if target.simulator?
91
+ # quits the simulator
92
+ sim = CoreSimulator.new(target, "")
93
+ sim.launch_simulator
94
+ else
95
+
96
+ end
97
+
98
+ args = [
99
+ "xcrun",
100
+ "xcodebuild",
101
+ "-scheme", "CBXAppStub",
102
+ "-workspace", workspace,
103
+ "-config", "Debug",
104
+ "-destination", "id=#{destination}",
105
+ "clean",
106
+ "test"
107
+ ]
108
+
109
+ log_file = XCUITest.log_file
110
+
111
+ options = {
112
+ :out => log_file,
113
+ :err => log_file
114
+ }
115
+
116
+ command = args.join(" ")
117
+ RunLoop.log_unix_cmd("#{command} >& #{log_file}")
118
+
119
+ pid = Process.spawn(*args, options)
120
+ Process.detach(pid)
121
+
122
+ if target.simulator?
123
+ target.simulator_wait_for_stable_state
124
+ end
125
+
126
+ RunLoop.log_debug("Waiting for CBX-Runner to build...")
127
+
128
+ server = RunLoop::HTTP::Server.new(driver_url)
129
+ request = RunLoop::HTTP::Request.new("/health", {})
130
+
131
+ options = {
132
+ :timeout => 60,
133
+ :interval => 0.1,
134
+ :retries => 600
135
+ }
136
+
137
+ client = RunLoop::HTTP::RetriableClient.new(server, options)
138
+ response = client.get(request)
139
+
140
+ RunLoop.log_debug("Calabus driver says, \"#{response.body}\"")
141
+ pid.to_i
142
+ end
143
+
144
+ def launch_app
145
+ server = RunLoop::HTTP::Server.new(url)
146
+ request = RunLoop::HTTP::Request.request("/session", {:bundleID => bundle_id})
147
+ client = RunLoop::HTTP::RetriableClient.new(server)
148
+ response = client.post(request)
149
+
150
+ RunLoop.log_debug("Calabus driver says, \"#{response.body}\"")
151
+ end
152
+
153
+ # @!visibility private
154
+ def target
155
+ @device ||= lambda do
156
+ target = RunLoop::Environment.device_target
157
+
158
+ if !target
159
+ target = RunLoop::Core.default_simulator
160
+ end
161
+
162
+ options = {
163
+ :sim_control => simctl,
164
+ :instruments => instruments
165
+ }
166
+
167
+ device = RunLoop::Device.device_with_identifier(target, options)
168
+
169
+ if !device
170
+ raise RuntimeError, "Could not find a device"
171
+ end
172
+
173
+ device
174
+ end.call
175
+ end
176
+
177
+ # @!visibility private
178
+ def bundle_id
179
+ @bundle_id
180
+ end
181
+
182
+ private
183
+
184
+ # @!visibility private
185
+ def simctl
186
+ @simctl ||= RunLoop::SimControl.new
187
+ end
188
+
189
+ # @!visibility private
190
+ def instruments
191
+ @instruments ||= RunLoop::Instruments.new
192
+ end
193
+
194
+ # @!visibility private
195
+ def xcrun
196
+ RunLoop::Xcrun.new
197
+ end
198
+
199
+ # @!visibility private
200
+ def self.dot_dir
201
+ path = File.join(RunLoop::DotDir.directory, "xcuitest")
202
+
203
+ if !File.exist?(path)
204
+ FileUtils.mkdir_p(path)
205
+ end
206
+
207
+ path
208
+ end
209
+ end
210
+ end
211
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: run_loop
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.6
4
+ version: 2.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Karl Krukow
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-05 00:00:00.000000000 Z
11
+ date: 2016-02-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -86,6 +86,20 @@ dependencies:
86
86
  - - ">="
87
87
  - !ruby/object:Gem::Version
88
88
  version: 0.0.2
89
+ - !ruby/object:Gem::Dependency
90
+ name: httpclient
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '2.6'
96
+ type: :runtime
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '2.6'
89
103
  - !ruby/object:Gem::Dependency
90
104
  name: rspec_junit_formatter
91
105
  requirement: !ruby/object:Gem::Requirement
@@ -274,10 +288,12 @@ files:
274
288
  - lib/run_loop/app.rb
275
289
  - lib/run_loop/cache/cache.rb
276
290
  - lib/run_loop/cli/cli.rb
291
+ - lib/run_loop/cli/codesign.rb
277
292
  - lib/run_loop/cli/errors.rb
278
293
  - lib/run_loop/cli/instruments.rb
279
294
  - lib/run_loop/cli/locale.rb
280
295
  - lib/run_loop/cli/simctl.rb
296
+ - lib/run_loop/codesign.rb
281
297
  - lib/run_loop/core.rb
282
298
  - lib/run_loop/core_simulator.rb
283
299
  - lib/run_loop/device.rb
@@ -287,6 +303,10 @@ files:
287
303
  - lib/run_loop/environment.rb
288
304
  - lib/run_loop/fifo.rb
289
305
  - lib/run_loop/host_cache.rb
306
+ - lib/run_loop/http/error.rb
307
+ - lib/run_loop/http/request.rb
308
+ - lib/run_loop/http/retriable_client.rb
309
+ - lib/run_loop/http/server.rb
290
310
  - lib/run_loop/instruments.rb
291
311
  - lib/run_loop/ipa.rb
292
312
  - lib/run_loop/l10n.rb
@@ -308,6 +328,7 @@ files:
308
328
  - lib/run_loop/version.rb
309
329
  - lib/run_loop/xcode.rb
310
330
  - lib/run_loop/xcrun.rb
331
+ - lib/run_loop/xcuitest.rb
311
332
  - plists/simctl/com.apple.UIAutomation.plist
312
333
  - plists/simctl/com.apple.UIAutomationPlugIn.plist
313
334
  - scripts/calabash_script_uia.js
@@ -342,10 +363,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
342
363
  version: '0'
343
364
  requirements: []
344
365
  rubyforge_project:
345
- rubygems_version: 2.5.1
366
+ rubygems_version: 2.5.2
346
367
  signing_key:
347
368
  specification_version: 4
348
369
  summary: The bridge between Calabash iOS and Xcode command-line tools like instruments
349
370
  and simctl.
350
371
  test_files: []
351
- has_rdoc: