calabash 2.0.0.pre10 → 2.0.0.pre11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -17
  3. data/bin/calabash +3 -4
  4. data/lib/calabash.rb +53 -10
  5. data/lib/calabash/android.rb +89 -28
  6. data/lib/calabash/android/adb.rb +32 -20
  7. data/lib/calabash/android/application.rb +1 -1
  8. data/lib/calabash/android/build/builder.rb +1 -1
  9. data/lib/calabash/android/build/java_keystore.rb +1 -1
  10. data/lib/calabash/android/build/resigner.rb +1 -1
  11. data/lib/calabash/android/device.rb +22 -66
  12. data/lib/calabash/android/device/helper_application.rb +95 -0
  13. data/lib/calabash/android/environment.rb +14 -1
  14. data/lib/calabash/android/gestures.rb +6 -22
  15. data/lib/calabash/android/interactions.rb +14 -17
  16. data/lib/calabash/android/lib/.irbrc +9 -1
  17. data/lib/calabash/android/lib/AndroidManifest.xml +23 -2
  18. data/lib/calabash/android/lib/HelperApplication.apk +0 -0
  19. data/lib/calabash/android/lib/HelperApplicationTestServer.apk +0 -0
  20. data/lib/calabash/android/lib/TestServer.apk +0 -0
  21. data/lib/calabash/android/life_cycle.rb +3 -3
  22. data/lib/calabash/android/orientation.rb +8 -8
  23. data/lib/calabash/android/physical_buttons.rb +19 -16
  24. data/lib/calabash/android/server.rb +1 -1
  25. data/lib/calabash/android/text.rb +12 -12
  26. data/lib/calabash/android/web.rb +12 -0
  27. data/lib/calabash/application.rb +3 -0
  28. data/lib/calabash/cli/generate.rb +8 -18
  29. data/lib/calabash/cli/helpers.rb +4 -9
  30. data/lib/calabash/cli/run.rb +1 -1
  31. data/lib/calabash/console_helpers.rb +179 -11
  32. data/lib/calabash/device.rb +4 -19
  33. data/lib/calabash/gestures.rb +292 -198
  34. data/lib/calabash/interactions.rb +3 -40
  35. data/lib/calabash/internal.rb +48 -0
  36. data/lib/calabash/ios.rb +76 -16
  37. data/lib/calabash/ios/automator.rb +9 -0
  38. data/lib/calabash/ios/automator/automator.rb +217 -0
  39. data/lib/calabash/ios/automator/coordinates.rb +37 -0
  40. data/lib/calabash/ios/automator/device_agent.rb +379 -0
  41. data/lib/calabash/ios/conditions.rb +1 -1
  42. data/lib/calabash/ios/console_helpers.rb +2 -2
  43. data/lib/calabash/ios/date_picker.rb +10 -8
  44. data/lib/calabash/ios/device.rb +0 -1
  45. data/lib/calabash/ios/device/device_implementation.rb +9 -21
  46. data/lib/calabash/ios/device/gestures_mixin.rb +53 -55
  47. data/lib/calabash/ios/device/keyboard_mixin.rb +21 -0
  48. data/lib/calabash/ios/device/rotation_mixin.rb +3 -65
  49. data/lib/calabash/ios/gestures.rb +24 -90
  50. data/lib/calabash/ios/interactions.rb +1 -6
  51. data/lib/calabash/ios/lib/.irbrc +9 -2
  52. data/lib/calabash/ios/orientation.rb +8 -8
  53. data/lib/calabash/ios/runtime.rb +14 -14
  54. data/lib/calabash/ios/scroll.rb +25 -17
  55. data/lib/calabash/ios/slider.rb +11 -18
  56. data/lib/calabash/ios/text.rb +20 -74
  57. data/lib/calabash/ios/uia.rb +1 -1
  58. data/lib/calabash/ios/web.rb +10 -0
  59. data/lib/calabash/lib/skeleton/{Gemfile → Gemfile.skeleton} +0 -0
  60. data/lib/calabash/lib/skeleton/config/{cucumber.yml → cucumber.yml.skeleton} +0 -0
  61. data/lib/calabash/lib/skeleton/features/{sample.feature → sample.feature.skeleton} +0 -0
  62. data/lib/calabash/lib/skeleton/features/step_definitions/{calabash_steps.rb → sample_steps.rb.skeleton} +8 -8
  63. data/lib/calabash/lib/skeleton/features/support/{dry_run.rb → dry_run.rb.skeleton} +2 -5
  64. data/lib/calabash/lib/skeleton/features/support/{env.rb → env.rb.skeleton} +2 -8
  65. data/lib/calabash/lib/skeleton/features/support/hooks.rb.skeleton +34 -0
  66. data/lib/calabash/life_cycle.rb +16 -8
  67. data/lib/calabash/location.rb +14 -15
  68. data/lib/calabash/orientation.rb +8 -8
  69. data/lib/calabash/page.rb +1 -4
  70. data/lib/calabash/retry.rb +33 -0
  71. data/lib/calabash/screenshot.rb +3 -3
  72. data/lib/calabash/stubs.rb +21 -0
  73. data/lib/calabash/text.rb +31 -19
  74. data/lib/calabash/utility.rb +41 -8
  75. data/lib/calabash/version.rb +1 -1
  76. data/lib/calabash/wait.rb +177 -192
  77. data/lib/calabash/web.rb +44 -0
  78. metadata +39 -32
  79. data/lib/calabash/ios/device/text_mixin.rb +0 -21
  80. data/lib/calabash/lib/skeleton/features/support/hooks.rb +0 -83
@@ -5,6 +5,10 @@ module Calabash
5
5
  # A representation of a Calabash Android device.
6
6
  # @!visibility private
7
7
  class Device < ::Calabash::Device
8
+ require 'calabash/android/device/helper_application'
9
+
10
+ include Calabash::Android::Device::HelperApplication
11
+
8
12
  attr_reader :adb
9
13
 
10
14
  def initialize(identifier, server)
@@ -475,12 +479,16 @@ module Calabash
475
479
  if installed_packages.include?(application.test_server.identifier)
476
480
  parameters =
477
481
  {
478
- packageName: application.test_server.identifier,
479
- className: 'sh.calaba.instrumentationbackend.StatusReporterActivity',
480
- extras:
481
- {
482
+ intent: {
483
+ flags: 0x10000000,
484
+ component: {
485
+ packageName: application.test_server.identifier,
486
+ className: 'sh.calaba.instrumentationbackend.StatusReporterActivity',
487
+ },
488
+ extras: {
482
489
  method: 'clear'
483
490
  }
491
+ }
484
492
  }
485
493
 
486
494
  ensure_helper_application_started
@@ -568,7 +576,7 @@ module Calabash
568
576
  end
569
577
 
570
578
  begin
571
- Retriable.retriable(tries: 30, interval: 1, timeout: 30, on: RetryError) do
579
+ Calabash::Retry.retry(retries: 30, interval: 1, timeout: 30, on_errors: [RetryError]) do
572
580
  unless test_server_responding?
573
581
  # Read any message the test-server might have
574
582
  if calabash_server_failure_exists?(application)
@@ -587,7 +595,7 @@ module Calabash
587
595
  end
588
596
 
589
597
  begin
590
- Retriable.retriable(tries: 10, interval: 1, timeout: 10) do
598
+ Calabash::Retry.retry(retries: 10, interval: 1, timeout: 10, on_errors: [RetryError]) do
591
599
  unless test_server_ready?
592
600
  raise RetryError
593
601
  end
@@ -620,7 +628,7 @@ module Calabash
620
628
 
621
629
  # @!visibility private
622
630
  def _stop_app
623
- Retriable.retriable(tries: 5, interval: 1) do
631
+ Calabash::Retry.retry(retries: 5, interval: 1) do
624
632
  begin
625
633
  http_client.post(HTTP::Request.new('kill'), retries: 1, interval: 0)
626
634
  rescue HTTP::Error => _
@@ -764,8 +772,12 @@ module Calabash
764
772
  def ts_clear_app_data(application)
765
773
  parameters =
766
774
  {
767
- className: 'sh.calaba.instrumentationbackend.ClearAppData2',
768
- packageName: application.test_server.identifier,
775
+ intent: {
776
+ component: {
777
+ className: 'sh.calaba.instrumentationbackend.ClearAppData2',
778
+ packageName: application.test_server.identifier
779
+ }
780
+ }
769
781
  }
770
782
 
771
783
  begin
@@ -857,7 +869,7 @@ module Calabash
857
869
  installed_app_md5_checksum = md5_checksum_for_app_package(application.identifier)
858
870
 
859
871
  if application.md5_checksum != installed_app_md5_checksum
860
- @logger.log("The md5 checksum has changed (#{application.md5_checksum} != #{installed_app_md5_checksum}).", :info)
872
+ @logger.log("The md5 checksum has changed for '#{application.identifier}' (#{application.md5_checksum} != #{installed_app_md5_checksum}).", :info)
861
873
  _install_app(application)
862
874
  end
863
875
  else
@@ -1157,62 +1169,6 @@ module Calabash
1157
1169
  true
1158
1170
  end
1159
1171
 
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
-
1216
1172
  # @!visibility private
1217
1173
  def params_for_request(parameters)
1218
1174
  {json: parameters.to_json}
@@ -0,0 +1,95 @@
1
+ require 'json'
2
+
3
+ module Calabash
4
+ module Android
5
+ class Device
6
+ module HelperApplication
7
+ def ensure_helper_application_started
8
+ unless $_calabash_helper_application_started
9
+ $stdout.puts "NEW DEBUG: IN HERE"
10
+ $stdout.puts "NEW DEBUG: INSTALLING"
11
+ install_helper_application
12
+ $stdout.puts "NEW DEBUG: STARTING"
13
+ begin
14
+ start_helper_application
15
+ rescue => e
16
+ $stdout.puts "NEW DEBUG EXCERPICON: #{e.backtrace.join("\n")}"
17
+ raise e
18
+ end
19
+
20
+ $stdout.puts "NEW DEBUG: DONE STARTING"
21
+ $_calabash_helper_application_started = true
22
+ end
23
+ end
24
+
25
+ def helper_application_server
26
+ Calabash::Android::Server.default_helper
27
+ end
28
+
29
+ def helper_application
30
+ Calabash::Android::Application.new(Calabash::Android::HELPER_APPLICATION,
31
+ Calabash::Android::HELPER_APPLICATION_TEST_SERVER)
32
+ end
33
+
34
+ def helper_application_http_client
35
+ @helper_application_http_client ||= lambda do
36
+ server = Calabash::HTTP::RetriableClient.new(helper_application_server)
37
+ port_forward(helper_application_server.endpoint, helper_application_server.test_server_port)
38
+
39
+ server.on_error(Errno::ECONNREFUSED) do |s|
40
+ port_forward(s.endpoint.port, s.test_server_port)
41
+ end
42
+
43
+ server
44
+ end.call
45
+ end
46
+
47
+ # @!visibility private
48
+ def install_helper_application
49
+ begin
50
+ @logger.log "Ensuring helper application is installed"
51
+ ensure_app_installed(helper_application)
52
+ rescue => e
53
+ @logger.log("Unable to install helper application!", :error)
54
+ raise e
55
+ end
56
+
57
+ $_calabash_helper_application_installed = true
58
+ end
59
+
60
+ # @!visibility private
61
+ def has_installed_helper_application?
62
+ $_calabash_helper_application_installed
63
+ end
64
+
65
+ # @!visibility private
66
+ def helper_application_responding?
67
+ begin
68
+ helper_application_http_client.post(HTTP::Request.new('ping'), retries: 1).body == 'pong'
69
+ rescue HTTP::Error => e
70
+ $stdout.puts "SH NEW DEBUG: PING ERROR #{e.backtrace.join("\n")}"
71
+ false
72
+ end
73
+ end
74
+
75
+ def start_helper_application
76
+ cmd = ["am start",
77
+ "-e testServerPort 0",
78
+ "-e port 8081",
79
+ "sh.calaba.calabashhelper/sh.calaba.calabashhelper.MainActivity"].join(" ")
80
+
81
+ adb.shell(cmd)
82
+
83
+ 100.times do |i|
84
+ if i == 99
85
+ raise "Unable to start helper application"
86
+ end
87
+
88
+ break if helper_application_responding?
89
+ sleep 1
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -1,6 +1,11 @@
1
1
  require 'rexml/document'
2
2
  require 'timeout'
3
- require 'luffa'
3
+
4
+ # We sometimes want to require a Ruby gem without having our IDE auto-complete
5
+ # using it. For example awesome_print adds a ton of methods to 'Object'
6
+ alias :cal_require_without_documentation :require
7
+ cal_require_without_documentation 'luffa'
8
+
4
9
  require 'timeout'
5
10
 
6
11
  if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
@@ -25,6 +30,14 @@ module Calabash
25
30
  # @todo Maybe rename this to CAL_SERVER_URL or CAL_SERVER?
26
31
  DEVICE_ENDPOINT = URI.parse((variable('CAL_ENDPOINT') || 'http://127.0.0.1:34777'))
27
32
 
33
+ # A URI that points to the helper server on the device.
34
+ #
35
+ # The default value is 'http://localhost:34778'.
36
+ #
37
+ # You can control the value of this variable by setting the `CAL_HELPER_ENDPOINT`
38
+ # variable.
39
+ DEVICE_HELPER_ENDPOINT = URI.parse((variable('CAL_HELPER_ENDPOINT') || 'http://127.0.0.1:34778'))
40
+
28
41
  private
29
42
 
30
43
  def self.set_android_dependencies(android_dependencies)
@@ -314,7 +314,7 @@ module Calabash
314
314
  end
315
315
 
316
316
  # @!visibility private
317
- def _pan_screen_up(options={})
317
+ define_method(:_pan_screen_up) do |options={}|
318
318
  from = {x: 50, y: 90}
319
319
  to = {x: 50, y: 10}
320
320
 
@@ -322,7 +322,7 @@ module Calabash
322
322
  end
323
323
 
324
324
  # @!visibility private
325
- def _pan_screen_down(options={})
325
+ define_method(:_pan_screen_down) do |options={}|
326
326
  from = {x: 50, y: 10}
327
327
  to = {x: 50, y: 90}
328
328
 
@@ -330,7 +330,7 @@ module Calabash
330
330
  end
331
331
 
332
332
  # @!visibility private
333
- def _flick_screen_up(options={})
333
+ define_method(:_flick_screen_up) do |options={}|
334
334
  from = {x: 50, y: 90}
335
335
  to = {x: 50, y: 10}
336
336
 
@@ -338,7 +338,7 @@ module Calabash
338
338
  end
339
339
 
340
340
  # @!visibility private
341
- def _flick_screen_down(options={})
341
+ define_method(:_flick_screen_down) do |options={}|
342
342
  from = {x: 50, y: 10}
343
343
  to = {x: 50, y: 90}
344
344
 
@@ -346,24 +346,8 @@ module Calabash
346
346
  end
347
347
 
348
348
  # @!visibility private
349
- def _pinch_screen(direction, options={})
350
- Device.default.pinch(direction, "* id:'content'", options)
351
- end
352
-
353
- # @!visibility private
354
- def _pinch_to_zoom(direction, query, options={})
355
- if direction == :out
356
- Device.default.pinch(:in, query, options)
357
- elsif direction == :in
358
- Device.default.pinch(:out, query, options)
359
- else
360
- raise "Invalid direction '#{direction}'"
361
- end
362
- end
363
-
364
- # @!visibility private
365
- def _pinch_screen_to_zoom(direction, options={})
366
- _pinch_to_zoom(direction, "* id:'content'", options)
349
+ define_method(:_pinch_screen) do |options={}|
350
+ Calabash::Internal.with_default_device(required_os: :android) {|device| device.pinch(direction, "* id:'content'", options)}
367
351
  end
368
352
  end
369
353
  end
@@ -8,13 +8,16 @@ module Calabash
8
8
  module Interactions
9
9
  # Go back. If the keyboard is shown, it will be dismissed.
10
10
  def go_back
11
- Device.default.perform_action('hide_soft_keyboard')
12
- press_back_button
11
+ Calabash::Internal.with_default_device(required_os: :android) do |device|
12
+ device.perform_action('hide_soft_keyboard')
13
+ end
14
+
15
+ press_physical_back_button
13
16
  end
14
17
 
15
18
  # Go to the home screen.
16
19
  def go_home
17
- Device.default.go_home
20
+ Calabash::Internal.with_default_device(required_os: :android) {|device| device.go_home}
18
21
 
19
22
  true
20
23
  end
@@ -22,33 +25,33 @@ module Calabash
22
25
  # Get the name of the currently focused activity
23
26
  #
24
27
  # @example
25
- # puts focused_activity
28
+ # puts cal_android.focused_activity
26
29
  # # => com.example.MainActivity
27
30
  #
28
31
  # @return [String] The name of the currently focused activity.
29
32
  def focused_activity
30
- Device.default.current_focus[:activity]
33
+ Calabash::Internal.with_default_device(required_os: :android) {|device| device.current_focus[:activity]}
31
34
  end
32
35
 
33
36
  # Get the name of the currently focused package
34
37
  #
35
38
  # @example
36
- # puts focused_package
39
+ # puts cal_android.focused_package
37
40
  # # => com.example
38
41
  #
39
42
  # @return [String] The name of the currently focused package
40
43
  def focused_package
41
- Device.default.current_focus[:package]
44
+ Calabash::Internal.with_default_device(required_os: :android) {|device| device.current_focus[:package]}
42
45
  end
43
46
 
44
47
  # Sets the date of the first visible date picker widget.
45
48
  #
46
49
  # @example
47
- # set_date('2012-04-24')
50
+ # cal_android.set_date('2012-04-24')
48
51
  #
49
52
  # @example
50
53
  # date = Date.parse('3rd Feb 2012')
51
- # set_date(date)
54
+ # cal_android.set_date(date)
52
55
  #
53
56
  # @param [Date, String] date The date to set. If given a String,
54
57
  # `Date.parse` is called on the string.
@@ -88,11 +91,11 @@ module Calabash
88
91
  # Sets the time of the first visible time picker widget.
89
92
  #
90
93
  # @example
91
- # set_time('14:42')
94
+ # cal_android.set_time('14:42')
92
95
  #
93
96
  # @example
94
97
  # time = Time.parse('8:30 AM')
95
- # set_time(time)
98
+ # cal_android.set_time(time)
96
99
  #
97
100
  # @param [Time, String] time The time to set. If given a String,
98
101
  # `Time.parse` is called on the string.
@@ -138,12 +141,6 @@ module Calabash
138
141
 
139
142
  true
140
143
  end
141
-
142
-
143
- # @!visibility private
144
- def _evaluate_javascript_in(query, javascript)
145
- Device.default.evaluate_javascript_in(query, javascript)
146
- end
147
144
  end
148
145
  end
149
146
  end
@@ -39,7 +39,15 @@ end
39
39
  begin
40
40
  require 'calabash/android'
41
41
 
42
- extend Calabash::Android
42
+ IRB.conf[:PROMPT][:CALABASH] = {
43
+ :PROMPT_I => "calabash #{Calabash::VERSION}> ",
44
+ :PROMPT_S => "%03n> ",
45
+ :PROMPT_C => "%03n> ",
46
+ :RETURN => "%s\n"
47
+ }
48
+
49
+ IRB.conf[:PROMPT_MODE] = :CALABASH
50
+
43
51
  extend Calabash::ConsoleHelpers
44
52
 
45
53
  Calabash::Android.setup_defaults!
@@ -3,7 +3,9 @@
3
3
  package="#testPackage#"
4
4
  android:versionCode="3"
5
5
  android:versionName="0.3.0">
6
- <application android:label="instrumentation_backend">
6
+ <application android:label="instrumentation_backend"
7
+ android:largeHeap="true">
8
+
7
9
  <uses-library android:name="android.test.runner" />
8
10
  <uses-library android:name="com.google.android.maps" android:required="false" />
9
11
  <activity
@@ -31,8 +33,26 @@
31
33
  android:stateNotNeeded="true"
32
34
  android:noHistory="true"
33
35
  android:excludeFromRecents="true"/>
36
+ <activity
37
+ android:name="sh.calaba.instrumentationbackend.FakeCameraActivity"
38
+ android:label="FakeCameraActivity"
39
+ android:exported="true"
40
+ android:finishOnTaskLaunch="true"
41
+ android:stateNotNeeded="true"
42
+ android:noHistory="true"
43
+ android:excludeFromRecents="true"
44
+ android:theme="@android:style/Theme.NoTitleBar.Fullscreen"/>
45
+ <activity
46
+ android:name="sh.calaba.instrumentationbackend.FakePickerActivity"
47
+ android:label="FakePickerActivity"
48
+ android:exported="true"
49
+ android:finishOnTaskLaunch="true"
50
+ android:stateNotNeeded="true"
51
+ android:noHistory="true"
52
+ android:excludeFromRecents="true"/>
34
53
  </application>
35
- <uses-sdk android:minSdkVersion="4" />
54
+ <uses-sdk android:minSdkVersion="4"
55
+ android:targetSdkVersion="21"/>
36
56
  <instrumentation android:targetPackage="#targetPackage#" android:name="sh.calaba.instrumentationbackend.CalabashInstrumentationTestRunner" />
37
57
  <instrumentation android:targetPackage="#targetPackage#" android:name="sh.calaba.instrumentationbackend.ClearAppData" />
38
58
  <instrumentation android:targetPackage="#targetPackage#" android:name="sh.calaba.instrumentationbackend.ClearAppData2" />
@@ -47,5 +67,6 @@
47
67
  <uses-permission android:name="android.permission.INTERNET" />
48
68
  <uses-permission android:name="android.permission.GET_TASKS" />
49
69
  <uses-permission android:name="android.permission.REORDER_TASKS" />
70
+ <uses-permission android:name="android.permission.CAMERA" />
50
71
 
51
72
  </manifest>