calabash 2.0.0.pre9 → 2.0.0.pre10

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: d018a4059fbc167401a00153fe9d5dd8a7660684
4
- data.tar.gz: c7d01f02885927df13058ec9417dbdad8f254fc2
3
+ metadata.gz: 1788f3f3e1bfd128768042749d0b7d5dbdebb8ab
4
+ data.tar.gz: 68d92c0989f89f7b4d4cf55a23a0daed83fa25e1
5
5
  SHA512:
6
- metadata.gz: b776516069ecd91364f819286532ea841d4eb1b25ab4ed364033a7faf50f406546fd986ffbd2e64484efb9df4045911232b95c9f670a7be883c3e2cdc5633d5f
7
- data.tar.gz: a973bee5a42a306303f4ac7c8304b961488e14a11f0348358fb006c6d0fb3c385c62fdbadd290a154157f202a59ae63f2e9352a6471958e8bb41708605d1648a
6
+ metadata.gz: f46b1426f57a039bebe2ac8e59c015f6ad2720217cb37b0e8df118614fa958a4d2cb2ec62890dee52dbb41980c5111c435567c7756ae746487bf69797ceae898
7
+ data.tar.gz: 5ed96dfbd5603d13ba3dbbc4a976bb7839641b74d514c178c71f0c2fe6f26f9f8e1cae7bd11b5acc6b5f1bbbf7ffd58037c95180ba0fcb3d99b5a384565061a9
@@ -7,6 +7,10 @@ module Calabash
7
7
  UNSIGNED_TEST_SERVER_APK = File.join(File.dirname(__FILE__), 'android', 'lib', 'TestServer.apk')
8
8
  # @!visibility private
9
9
  ANDROID_MANIFEST_PATH = File.join(File.dirname(__FILE__), 'android', 'lib', 'AndroidManifest.xml')
10
+ # @!visibility private
11
+ HELPER_APPLICATION = File.join(File.dirname(__FILE__), 'android', 'lib', 'HelperApplication.apk')
12
+ # @!visibility private
13
+ HELPER_APPLICATION_TEST_SERVER = File.join(File.dirname(__FILE__), 'android', 'lib', 'HelperApplicationTestServer.apk')
10
14
 
11
15
  require 'calabash'
12
16
  include Calabash
@@ -66,22 +66,22 @@ module Calabash
66
66
 
67
67
  # @!visibility private
68
68
  def installed_packages
69
- adb.shell('pm list packages').lines.map do |line|
70
- line.sub('package:', '').chomp
71
- end
69
+ installed_apps.map{|e| e[:package]}
72
70
  end
73
71
 
74
72
  # @!visibility private
75
73
  def installed_apps
76
- adb.shell('pm list packages -f').lines.map do |line|
77
- # line will be package:<path>=<package>
78
- # e.g. "package:/system/app/GoogleEars.apk=com.google.android.ears"
79
- info = line.sub("package:", "")
74
+ @installed_apps_cache ||= lambda do
75
+ adb.shell('pm list packages -f').lines.map do |line|
76
+ # line will be package:<path>=<package>
77
+ # e.g. "package:/system/app/GoogleEars.apk=com.google.android.ears"
78
+ info = line.sub("package:", "")
80
79
 
81
- app_path, app_id = info.split('=').map(&:chomp)
80
+ app_path, app_id = info.split('=').map(&:chomp)
82
81
 
83
- {package: app_id, path: app_path}
84
- end
82
+ {package: app_id, path: app_path}
83
+ end
84
+ end.call
85
85
  end
86
86
 
87
87
  # @!visibility private
@@ -420,25 +420,71 @@ module Calabash
420
420
  adb.shell(cmd, no_exit_code_check: true).chomp == file
421
421
  end
422
422
 
423
+ def file_exists?(file)
424
+ ensure_helper_application_started
425
+
426
+ request = HTTP::Request.new('file-exists', params_for_request(fileName: file))
427
+ response = helper_application_http_client.post(request)
428
+
429
+ if response.status != 200
430
+ result = JSON.parse(response.body)
431
+ raise "Failed to find out if file exists #{result['reason']}"
432
+ end
433
+
434
+ case response.body
435
+ when 'true'
436
+ return true
437
+ when 'false'
438
+ return false
439
+ else
440
+ raise "Invalid resposne '#{response.body}'"
441
+ end
442
+ end
443
+
444
+ def read_file(file)
445
+ ensure_helper_application_started
446
+
447
+ request = HTTP::Request.new('read-file', params_for_request(fileName: file))
448
+ response = helper_application_http_client.post(request)
449
+
450
+ if response.status != 200
451
+ result = JSON.parse(response.body)
452
+ raise "Failed to read file. Reason: #{result['reason']}"
453
+ end
454
+
455
+ response.body
456
+ end
457
+
423
458
  def calabash_server_failure_exists?(application)
424
- adb_file_exists?(calabash_server_failure_file_path(application))
459
+ file_exists?(calabash_server_failure_file_path(application))
425
460
  end
426
461
 
427
462
  def calabash_server_finished_exists?(application)
428
- adb_file_exists?(calabash_server_finished_file_path(application))
463
+ file_exists?(calabash_server_finished_file_path(application))
429
464
  end
430
465
 
431
466
  def read_calabash_sever_failure(application)
432
- adb.shell("cat #{calabash_server_failure_file_path(application)}")
467
+ read_file(calabash_server_failure_file_path(application))
433
468
  end
434
469
 
435
470
  def read_calabash_sever_finished(application)
436
- adb.shell("cat #{calabash_server_finished_file_path(application)}")
471
+ read_file(calabash_server_finished_file_path(application))
437
472
  end
438
473
 
439
474
  def clear_calabash_server_report(application)
440
475
  if installed_packages.include?(application.test_server.identifier)
441
- adb.shell("am start -e method clear -n #{application.test_server.identifier}/sh.calaba.instrumentationbackend.StatusReporterActivity")
476
+ parameters =
477
+ {
478
+ packageName: application.test_server.identifier,
479
+ className: 'sh.calaba.instrumentationbackend.StatusReporterActivity',
480
+ extras:
481
+ {
482
+ method: 'clear'
483
+ }
484
+ }
485
+
486
+ ensure_helper_application_started
487
+ start_activity(parameters)
442
488
  end
443
489
  end
444
490
 
@@ -450,7 +496,6 @@ module Calabash
450
496
  end
451
497
 
452
498
  env_options[:test_server_port] = server.test_server_port
453
- env_options[:target_package] = application.identifier
454
499
 
455
500
  env_options[:class] = options.fetch(:class, 'sh.calaba.instrumentationbackend.InstrumentationBackend')
456
501
 
@@ -486,9 +531,6 @@ module Calabash
486
531
 
487
532
  ensure_screen_on
488
533
 
489
- # Clear any old error reports
490
- clear_calabash_server_report(application)
491
-
492
534
  # We have to forward the port ourselves, as an old test-server could be
493
535
  # running on the old port. If the retriable client was able to
494
536
  # determine if the port had been forwarded, we would not need this.
@@ -508,6 +550,9 @@ module Calabash
508
550
  end
509
551
  end
510
552
 
553
+ # Clear any old error reports
554
+ clear_calabash_server_report(application)
555
+
511
556
  extras = ''
512
557
 
513
558
  env_options.each_pair do |key, val|
@@ -515,7 +560,7 @@ module Calabash
515
560
  end
516
561
 
517
562
  begin
518
- instrument(application,
563
+ adb_instrument(application,
519
564
  'sh.calaba.instrumentationbackend.CalabashInstrumentationTestRunner',
520
565
  extras)
521
566
  rescue ADB::ADBCallError => e
@@ -553,10 +598,26 @@ module Calabash
553
598
  raise 'Test-server was never ready'
554
599
  end
555
600
 
601
+ start_application(options[:intent])
602
+
556
603
  # Return true to avoid cluttering the console
557
604
  true
558
605
  end
559
606
 
607
+ # @!visibility private
608
+ def start_application(intent)
609
+ request = HTTP::Request.new('start-application', params_for_request(intent: intent))
610
+ body = http_client.post(request).body
611
+
612
+ result = JSON.parse(body)
613
+
614
+ if result['outcome'] != 'SUCCESS'
615
+ raise "Failed to start application. Reason: #{result['reason']}"
616
+ end
617
+
618
+ result['result']
619
+ end
620
+
560
621
  # @!visibility private
561
622
  def _stop_app
562
623
  Retriable.retriable(tries: 5, interval: 1) do
@@ -605,7 +666,7 @@ module Calabash
605
666
  end
606
667
 
607
668
  # @!visibility private
608
- def instrument(application, test_server_activity, extras = '')
669
+ def adb_instrument(application, test_server_activity, extras = '')
609
670
  unless application.is_a?(Android::Application)
610
671
  raise ArgumentError, "Invalid application type '#{application.class}'"
611
672
  end
@@ -633,11 +694,45 @@ module Calabash
633
694
  class EnsureInstrumentActionError < RuntimeError; end
634
695
 
635
696
  # @!visibility private
636
- def ensure_instrument_action(application, test_server_activity, extras = '')
697
+ def ensure_adb_instrument_action(application, test_server_activity, extras = '')
698
+ clear_calabash_server_report(application)
699
+
700
+ begin
701
+ adb_instrument(application, test_server_activity, extras)
702
+ rescue ADB::ADBCallError => e
703
+ raise EnsureInstrumentActionError, e
704
+ end
705
+
706
+ begin
707
+ Timeout.timeout(10) do
708
+ loop do
709
+ if calabash_server_failure_exists?(application)
710
+ failure_message = read_calabash_sever_failure(application)
711
+
712
+ raise EnsureInstrumentActionError, parse_failure_message(failure_message)
713
+ end
714
+
715
+ if calabash_server_finished_exists?(application)
716
+ output = read_calabash_sever_finished(application)
717
+
718
+ if output == 'SUCCESSFUL'
719
+ break
720
+ end
721
+ end
722
+ end
723
+ end
724
+ rescue Timeout::Error => _
725
+ raise EnsureInstrumentActionError, 'Timed out waiting for status'
726
+ end
727
+ end
728
+
729
+ # @!visibility private
730
+ def ensure_instrument_action(application, parameters)
731
+ ensure_helper_application_started
637
732
  clear_calabash_server_report(application)
638
733
 
639
734
  begin
640
- instrument(application, test_server_activity, extras)
735
+ instrument(parameters)
641
736
  rescue ADB::ADBCallError => e
642
737
  raise EnsureInstrumentActionError, e
643
738
  end
@@ -667,8 +762,14 @@ module Calabash
667
762
 
668
763
  # @!visibility private
669
764
  def ts_clear_app_data(application)
765
+ parameters =
766
+ {
767
+ className: 'sh.calaba.instrumentationbackend.ClearAppData2',
768
+ packageName: application.test_server.identifier,
769
+ }
770
+
670
771
  begin
671
- ensure_instrument_action(application, 'sh.calaba.instrumentationbackend.ClearAppData2')
772
+ ensure_instrument_action(application, parameters)
672
773
  rescue EnsureInstrumentActionError => e
673
774
  raise "Failed to clear app data: #{e.message}"
674
775
  end
@@ -914,6 +1015,7 @@ module Calabash
914
1015
 
915
1016
  # @!visibility private
916
1017
  def adb_uninstall_app(package)
1018
+ @installed_apps_cache = nil
917
1019
  @logger.log "Uninstalling #{package}"
918
1020
  result = adb.command('uninstall', package, timeout: 60).lines.last
919
1021
 
@@ -928,6 +1030,7 @@ module Calabash
928
1030
 
929
1031
  # @!visibility private
930
1032
  def adb_install_app(application)
1033
+ @installed_apps_cache = nil
931
1034
  # Because of a bug in the latest version of ADB
932
1035
  # https://github.com/android/platform_system_core/blob/0f91887868e51de67bdf9aedc97fbcb044dc1969/adb/commandline.cpp#L1466
933
1036
  # ADB now uses rm -f ... to remove the temporary application on the
@@ -1024,6 +1127,92 @@ module Calabash
1024
1127
  end
1025
1128
  end
1026
1129
 
1130
+ class InstrumentationError < RuntimeError; end
1131
+
1132
+ def instrument(parameters, http_client = helper_application_http_client)
1133
+ request = HTTP::Request.new('instrument', params_for_request(parameters))
1134
+
1135
+ body = http_client.post(request).body
1136
+ result = JSON.parse(body)
1137
+
1138
+ if result['outcome'] != 'SUCCESS'
1139
+ raise InstrumentationError, "Failed to instrument. Reason: #{result['reason']}"
1140
+ end
1141
+
1142
+ true
1143
+ end
1144
+
1145
+ class StartActivityError < RuntimeError; end
1146
+
1147
+ def start_activity(parameters, http_client = helper_application_http_client)
1148
+ request = HTTP::Request.new('start-activity', params_for_request(parameters))
1149
+
1150
+ body = http_client.post(request).body
1151
+ result = JSON.parse(body)
1152
+
1153
+ if result['outcome'] != 'SUCCESS'
1154
+ raise StartActivityError, "Failed to start activity. Reason: #{result['reason']}"
1155
+ end
1156
+
1157
+ true
1158
+ end
1159
+
1160
+ def ensure_helper_application_started
1161
+ unless $_calabash_helper_application_started
1162
+ install_helper_application
1163
+ start_helper_application
1164
+ $_calabash_helper_application_started = true
1165
+ end
1166
+ end
1167
+
1168
+ def helper_application
1169
+ Calabash::Android::Application.new(Calabash::Android::HELPER_APPLICATION,
1170
+ Calabash::Android::HELPER_APPLICATION_TEST_SERVER)
1171
+ end
1172
+
1173
+ def helper_application_http_client
1174
+ @helper_application_http_client ||= Calabash::HTTP::ForwardingClient.new(http_client, 8451)
1175
+ end
1176
+
1177
+ # @!visibility private
1178
+ def install_helper_application
1179
+ begin
1180
+ @logger.log "Ensuring helper application is installed"
1181
+ ensure_app_installed(helper_application)
1182
+ rescue => e
1183
+ @logger.log("Unable to install helper application!", :error)
1184
+ raise e
1185
+ end
1186
+
1187
+ $_calabash_helper_application_installed = true
1188
+ end
1189
+
1190
+ # @!visibility private
1191
+ def has_installed_helper_application?
1192
+ $_calabash_helper_application_installed
1193
+ end
1194
+
1195
+ # @!visibility private
1196
+ def helper_application_responding?
1197
+ begin
1198
+ helper_application_http_client.post(HTTP::Request.new('ping'), retries: 1).body == 'pong'
1199
+ rescue HTTP::Error => _
1200
+ false
1201
+ end
1202
+ end
1203
+
1204
+ def start_helper_application
1205
+ extras = "-e test_server_port 8451"
1206
+ name = "#{helper_application.test_server.identifier}/sh.calaba.instrumentationbackend.CalabashInstrumentationTestRunner"
1207
+ cmd = "am instrument #{extras} #{name}"
1208
+ Logger.debug("Starting global helper application using #{cmd}")
1209
+ adb.shell(cmd)
1210
+
1211
+ cmd = "am start -e port #{server.test_server_port} -e testServerPort 0 -n #{helper_application.identifier}/.MainActivity"
1212
+ Logger.debug("Starting helper application using #{cmd}")
1213
+ adb.shell(cmd)
1214
+ end
1215
+
1027
1216
  # @!visibility private
1028
1217
  def params_for_request(parameters)
1029
1218
  {json: parameters.to_json}
@@ -1036,6 +1225,9 @@ module Calabash
1036
1225
  else
1037
1226
  if adb.shell('md5', no_exit_code_check: true).chomp == 'md5 file ...'
1038
1227
  @md5_binary = 'md5'
1228
+ elsif (r = adb.shell('md5sum _cal_no_such_file', no_exit_code_check: true)) && r.chomp.start_with?('md5sum:') &&
1229
+ !r.include?('permission denied')
1230
+ @md5_binary = 'md5sum'
1039
1231
  else
1040
1232
  # The device does not have 'md5'
1041
1233
  calmd5 = Calabash::Android.binary_location('calmd5', info[:cpu_architecture], can_handle_pie_binaries?)
@@ -7,6 +7,11 @@ module Calabash
7
7
  endpoint = Environment::DEVICE_ENDPOINT
8
8
  Server.new(endpoint, 7102)
9
9
  end
10
+
11
+ def self.default_helper
12
+ endpoint = Environment::DEVICE_HELPER_ENDPOINT
13
+ Server.new(endpoint, 8102)
14
+ end
10
15
  end
11
16
  end
12
17
  end
data/lib/calabash/http.rb CHANGED
@@ -2,6 +2,7 @@ module Calabash
2
2
  # @!visibility private
3
3
  module HTTP
4
4
  require 'calabash/http/retriable_client'
5
+ require 'calabash/http/forwarding_client'
5
6
  require 'calabash/http/request'
6
7
  require 'calabash/http/error'
7
8
  end
@@ -0,0 +1,23 @@
1
+ module Calabash
2
+ module HTTP
3
+ class ForwardingClient
4
+ HEADER_FORWARD = 'X-FORWARD-PORT'
5
+ ROUTES = [:get, :post, :put, :delete]
6
+
7
+ def initialize(client, forward_to_port)
8
+ @client = client
9
+ @forward_to_port = forward_to_port
10
+ end
11
+
12
+ ROUTES.each do |route|
13
+ define_method(route) do |request, options = {}|
14
+ new_options = options.clone
15
+ new_options[:header] ||= {}
16
+ new_options[:header][HEADER_FORWARD] = @forward_to_port.to_s
17
+
18
+ @client.send(route, request, new_options)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -33,6 +33,9 @@ module Calabash
33
33
  'Content-Type' => 'application/json;charset=utf-8'
34
34
  }
35
35
 
36
+ # @!visibility private
37
+ attr_accessor :port_forward
38
+
36
39
  # Creates a new retriable client.
37
40
  #
38
41
  # This initializer takes multiple options. If the option is not
@@ -107,7 +110,7 @@ module Calabash
107
110
  retries = options.fetch(:retries, @retries)
108
111
  timeout = options.fetch(:timeout, @timeout)
109
112
  interval = options.fetch(:interval, @interval)
110
- header = options.fetch(:header, HEADER)
113
+ header = HEADER.merge(options.fetch(:header, {}))
111
114
 
112
115
  @logger.log "Getting: #{@server.endpoint + request.route} #{options}"
113
116
 
@@ -1,5 +1,5 @@
1
1
  module Calabash
2
2
 
3
3
  # @!visibility private
4
- VERSION = "2.0.0.pre9"
4
+ VERSION = "2.0.0.pre10"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: calabash
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.pre9
4
+ version: 2.0.0.pre10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonas Maturana Larsen
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2016-03-17 00:00:00.000000000 Z
14
+ date: 2016-04-07 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: edn
@@ -392,6 +392,8 @@ files:
392
392
  - lib/calabash/android/legacy.rb
393
393
  - lib/calabash/android/lib/.irbrc
394
394
  - lib/calabash/android/lib/AndroidManifest.xml
395
+ - lib/calabash/android/lib/HelperApplication.apk
396
+ - lib/calabash/android/lib/HelperApplicationTestServer.apk
395
397
  - lib/calabash/android/lib/TestServer.apk
396
398
  - lib/calabash/android/lib/calmd5/arm64-v8a/calmd5
397
399
  - lib/calabash/android/lib/calmd5/arm64-v8a/calmd5-pie
@@ -432,6 +434,7 @@ files:
432
434
  - lib/calabash/gestures.rb
433
435
  - lib/calabash/http.rb
434
436
  - lib/calabash/http/error.rb
437
+ - lib/calabash/http/forwarding_client.rb
435
438
  - lib/calabash/http/request.rb
436
439
  - lib/calabash/http/retriable_client.rb
437
440
  - lib/calabash/interactions.rb