run_loop 2.1.6 → 2.1.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  module RunLoop
2
- VERSION = "2.1.6"
2
+ VERSION = "2.1.7"
3
3
 
4
4
  # A model of a software release version that can be used to compare two versions.
5
5
  #
@@ -14,11 +14,14 @@ module RunLoop
14
14
  class HTTPError < RuntimeError; end
15
15
 
16
16
  # @!visibility private
17
+ #
18
+ # These defaults may change at any time.
17
19
  DEFAULTS = {
18
20
  :port => 27753,
19
21
  :simulator_ip => "127.0.0.1",
20
22
  :http_timeout => RunLoop::Environment.ci? ? 120 : 60,
21
- :version => "1.0"
23
+ :route_version => "1.0",
24
+ :shutdown_device_agent_before_launch => false
22
25
  }
23
26
 
24
27
  # @!visibility private
@@ -49,7 +52,7 @@ module RunLoop
49
52
  cbx_launcher = XCUITest.detect_cbx_launcher(options, device)
50
53
 
51
54
  xcuitest = RunLoop::XCUITest.new(bundle_id, device, cbx_launcher)
52
- xcuitest.launch
55
+ xcuitest.launch(options)
53
56
 
54
57
  if !RunLoop::Environment.xtc?
55
58
  cache = {
@@ -116,9 +119,9 @@ module RunLoop
116
119
  end
117
120
 
118
121
  # @!visibility private
119
- def launch
122
+ def launch(options={})
120
123
  start = Time.now
121
- launch_cbx_runner
124
+ launch_cbx_runner(options)
122
125
  launch_aut
123
126
  elapsed = Time.now - start
124
127
  RunLoop.log_debug("Took #{elapsed} seconds to launch #{bundle_id} on #{device}")
@@ -149,7 +152,7 @@ module RunLoop
149
152
  end
150
153
 
151
154
  # @!visibility private
152
- def runtime
155
+ def device_info
153
156
  options = http_options
154
157
  request = request("device")
155
158
  client = client(options)
@@ -157,6 +160,37 @@ module RunLoop
157
160
  expect_200_response(response)
158
161
  end
159
162
 
163
+ # TODO Legacy API; remove once this branch is merged:
164
+ # https://github.com/calabash/DeviceAgent.iOS/pull/133
165
+ alias_method :runtime, :device_info
166
+
167
+ # @!visibility private
168
+ def server_pid
169
+ options = http_options
170
+ request = request("pid")
171
+ client = client(options)
172
+ response = client.get(request)
173
+ expect_200_response(response)
174
+ end
175
+
176
+ # @!visibility private
177
+ def server_version
178
+ options = http_options
179
+ request = request("version")
180
+ client = client(options)
181
+ response = client.get(request)
182
+ expect_200_response(response)
183
+ end
184
+
185
+ # @!visibility private
186
+ def session_identifier
187
+ options = http_options
188
+ request = request("sessionIdentifier")
189
+ client = client(options)
190
+ response = client.get(request)
191
+ expect_200_response(response)
192
+ end
193
+
160
194
  # @!visibility private
161
195
  def tree
162
196
  options = http_options
@@ -240,7 +274,7 @@ module RunLoop
240
274
 
241
275
  # @!visibility private
242
276
  def rotate_home_button_to(position, sleep_for=1.0)
243
- orientation = orientation_for_position(position)
277
+ orientation = normalize_orientation_position(position)
244
278
  parameters = {
245
279
  :orientation => orientation
246
280
  }
@@ -252,6 +286,26 @@ module RunLoop
252
286
  json
253
287
  end
254
288
 
289
+ # @!visibility private
290
+ def pan_between_coordinates(start_point, end_point, options={})
291
+ default_options = {
292
+ :num_fingers => 1,
293
+ :duration => 0.5
294
+ }
295
+
296
+ merged_options = default_options.merge(options)
297
+
298
+ parameters = {
299
+ :gesture => "drag",
300
+ :specifiers => {
301
+ :coordinates => [start_point, end_point]
302
+ },
303
+ :options => merged_options
304
+ }
305
+
306
+ make_gesture_request(parameters)
307
+ end
308
+
255
309
  # @!visibility private
256
310
  def perform_coordinate_gesture(gesture, x, y, options={})
257
311
  parameters = {
@@ -262,8 +316,14 @@ module RunLoop
262
316
  :options => options
263
317
  }
264
318
 
319
+ make_gesture_request(parameters)
320
+ end
321
+
322
+ # @!visibility private
323
+ def make_gesture_request(parameters)
324
+
265
325
  RunLoop.log_debug(%Q[
266
- Sending request to perform '#{gesture}' with:
326
+ Sending request to perform '#{parameters[:gesture]}' with:
267
327
 
268
328
  #{JSON.pretty_generate(parameters)}
269
329
 
@@ -400,7 +460,7 @@ Sending request to perform '#{gesture}' with:
400
460
 
401
461
  # @!visibility private
402
462
  def versioned_route(route)
403
- "#{DEFAULTS[:version]}/#{route}"
463
+ "#{DEFAULTS[:route_version]}/#{route}"
404
464
  end
405
465
 
406
466
  # @!visibility private
@@ -416,11 +476,20 @@ Sending request to perform '#{gesture}' with:
416
476
 
417
477
  # @!visibility private
418
478
  def http_options
419
- {
420
- :timeout => DEFAULTS[:http_timeout],
421
- :interval => 0.1,
422
- :retries => (DEFAULTS[:http_timeout]/0.1).to_i
423
- }
479
+ if cbx_launcher.name == :xcodebuild
480
+ timeout = DEFAULTS[:http_timeout] * 2
481
+ {
482
+ :timeout => timeout,
483
+ :interval => 0.1,
484
+ :retries => (timeout/0.1).to_i
485
+ }
486
+ else
487
+ {
488
+ :timeout => DEFAULTS[:http_timeout],
489
+ :interval => 0.1,
490
+ :retries => (DEFAULTS[:http_timeout]/0.1).to_i
491
+ }
492
+ end
424
493
  end
425
494
 
426
495
  # @!visibility private
@@ -428,7 +497,7 @@ Sending request to perform '#{gesture}' with:
428
497
  # https://xamarin.atlassian.net/browse/TCFW-255
429
498
  # httpclient is unable to send a valid DELETE
430
499
  args = ["curl", "-X", "DELETE", %Q[#{url}#{versioned_route("session")}]]
431
- run_shell_command(args)
500
+ run_shell_command(args, {:log_cmd => true})
432
501
 
433
502
  # options = ping_options
434
503
  # request = request("session")
@@ -474,21 +543,84 @@ Sending request to perform '#{gesture}' with:
474
543
  body
475
544
  end
476
545
 
546
+
547
+ def cbx_runner_stale?
548
+ if cbx_launcher.name == :xcodebuild
549
+ return false
550
+ end
551
+
552
+ version_info = server_version
553
+ running_bundle_version = RunLoop::Version.new(version_info[:bundle_version])
554
+ bundle_version = RunLoop::App.new(cbx_launcher.runner.runner).bundle_version
555
+
556
+ running_bundle_version < bundle_version
557
+ end
558
+
477
559
  # @!visibility private
478
- def launch_cbx_runner
479
- shutdown
560
+ def launch_cbx_runner(options={})
561
+ merged_options = DEFAULTS.merge(options)
562
+
563
+ if merged_options[:shutdown_device_agent_before_launch]
564
+ RunLoop.log_debug("Launch options insist that the DeviceAgent be shutdown")
565
+ shutdown
566
+
567
+ if cbx_launcher.name == :xcodebuild
568
+ sleep(5.0)
569
+ end
570
+ end
571
+
572
+ if running?
573
+ RunLoop.log_debug("DeviceAgent is already running")
574
+ if cbx_runner_stale?
575
+ shutdown
576
+ else
577
+ # TODO: is it necessary to return the pid? Or can we return true?
578
+ return server_pid
579
+ end
580
+ end
480
581
 
481
- options = {:log_cmd => true}
482
- run_shell_command(["pkill", "iOSDeviceManager"], options)
483
- run_shell_command(["pkill", "testmanagerd"], options)
484
- run_shell_command(["pkill", "xcodebuild"], options)
582
+ if cbx_launcher.name == :xcodebuild
583
+ RunLoop.log_debug("xcodebuild is the launcher - terminating existing xcodebuild processes")
584
+ term_options = { :timeout => 0.5 }
585
+ kill_options = { :timeout => 0.5 }
586
+ RunLoop::ProcessWaiter.new("xcodebuild").pids.each do |pid|
587
+ term = RunLoop::ProcessTerminator.new(pid, 'TERM', "xcodebuild", term_options)
588
+ killed = term.kill_process
589
+ unless killed
590
+ RunLoop::ProcessTerminator.new(pid, 'KILL', "xcodebuild", kill_options)
591
+ end
592
+ end
593
+ sleep(2.0)
594
+ end
485
595
 
486
596
  start = Time.now
487
597
  RunLoop.log_debug("Waiting for CBX-Runner to launch...")
488
598
  pid = cbx_launcher.launch
489
- health
599
+
600
+ if cbx_launcher.name == :xcodebuild
601
+ sleep(2.0)
602
+ end
603
+
604
+ begin
605
+ health
606
+ rescue RunLoop::HTTP::Error => _
607
+ raise %Q[
608
+
609
+ Could not connect to the DeviceAgent service.
610
+
611
+ device: #{device}
612
+ url: #{url}
613
+
614
+ To diagnose the problem tail the launcher log file:
615
+
616
+ $ tail -1000 -F #{cbx_launcher.class.log_file}
617
+
618
+ ]
619
+ end
620
+
490
621
  RunLoop.log_debug("Took #{Time.now - start} launch and respond to /health")
491
622
 
623
+ # TODO: is it necessary to return the pid? Or can we return true?
492
624
  pid
493
625
  end
494
626
 
@@ -556,7 +688,21 @@ Server replied with:
556
688
  end
557
689
 
558
690
  # @!visibility private
559
- def orientation_for_position(position)
691
+ def normalize_orientation_position(position)
692
+ if position.is_a?(Symbol)
693
+ orientation_for_position_symbol(position)
694
+ elsif position.is_a?(Fixnum)
695
+ position
696
+ else
697
+ raise ArgumentError, %Q[
698
+ Expected #{position} to be a Symbol or Fixnum but found #{position.class}
699
+
700
+ ]
701
+ end
702
+ end
703
+
704
+ # @!visibility private
705
+ def orientation_for_position_symbol(position)
560
706
  symbol = position.to_sym
561
707
 
562
708
  case symbol
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.1.6
4
+ version: 2.1.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-07-27 00:00:00.000000000 Z
11
+ date: 2016-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -354,6 +354,7 @@ files:
354
354
  - lib/run_loop/logging.rb
355
355
  - lib/run_loop/otool.rb
356
356
  - lib/run_loop/patches/awesome_print.rb
357
+ - lib/run_loop/physical_device/ios_device_manager.rb
357
358
  - lib/run_loop/physical_device/life_cycle.rb
358
359
  - lib/run_loop/plist_buddy.rb
359
360
  - lib/run_loop/process_terminator.rb