calabash-android 0.4.0.pre11 → 0.4.0.pre15

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -3,7 +3,7 @@ load 'lib/calabash-android/helpers.rb'
3
3
 
4
4
  def build
5
5
  test_server_template_dir = File.join(File.dirname(__FILE__), 'test-server')
6
-
6
+
7
7
  Dir.mktmpdir do |workspace_dir|
8
8
 
9
9
  @test_server_dir = File.join(workspace_dir, 'test-server')
@@ -34,8 +34,32 @@ def build
34
34
  end
35
35
 
36
36
 
37
+ desc "Update server version to expected server version"
38
+ task :match_versions do
39
+ test_server_template_dir = File.join(File.dirname(__FILE__), 'test-server')
40
+
41
+ version_command = File.join(test_server_template_dir,
42
+ "instrumentation-backend",
43
+ "src",
44
+ "sh",
45
+ "calaba",
46
+ "instrumentationbackend",
47
+ "actions",
48
+ "version",
49
+ "Version.java" )
50
+
51
+ unless File.exist?(version_command)
52
+ raise "Unable to find version file at: #{version_command}"
53
+ end
54
+
55
+ text = File.read(version_command)
56
+ text.gsub!(/public static final String VERSION=".*";/,%Q[public static final String VERSION="#{Calabash::Android::SERVER_VERSION}";])
57
+ File.open(version_command, 'w') { |f| f.write(text) }
58
+
59
+ end
37
60
 
38
- task :build do
61
+
62
+ task :build => :match_versions do
39
63
  unless File.exists? "test-server/calabash-js/src"
40
64
  puts "calabash-js not found!"
41
65
  puts "For instuctions see: https://github.com/calabash/calabash-android/wiki/Building-calabash-android"
@@ -48,4 +72,5 @@ task :build do
48
72
 
49
73
  end
50
74
 
75
+
51
76
  Bundler::GemHelper.install_tasks
@@ -59,7 +59,7 @@ def sign_apk(app_path, dest_path)
59
59
  jarsigner_path = "jarsigner"
60
60
  end
61
61
 
62
- cmd = "#{jarsigner_path} -sigalg MD5withRSA -digestalg SHA1 -signedjar #{dest_path} -storepass #{keystore["keystore_password"]} -keystore \"#{File.expand_path keystore["keystore_location"]}\" #{app_path} #{keystore["keystore_alias"]}"
62
+ cmd = "#{jarsigner_path} -sigalg MD5withRSA -digestalg SHA1 -signedjar #{dest_path} -storepass #{keystore["keystore_password"]} -keystore #{keystore["keystore_location"]} #{app_path} #{keystore["keystore_alias"]}"
63
63
  log cmd
64
64
  unless system(cmd)
65
65
  puts "jarsigner command: #{cmd}"
@@ -69,10 +69,12 @@ end
69
69
 
70
70
  def read_keystore_info
71
71
  if File.exist? ".calabash_settings"
72
- JSON.parse(IO.read(".calabash_settings"))
72
+ keystore = JSON.parse(IO.read(".calabash_settings"))
73
+ keystore["keystore_location"] = '"' + File.expand_path(keystore["keystore_location"]) + '"' if keystore["keystore_location"]
74
+ keystore
73
75
  else
74
76
  {
75
- "keystore_location" => "#{ENV["HOME"]}/.android/debug.keystore",
77
+ "keystore_location" => %Q("#{File.expand_path(File.join(ENV["HOME"], "/.android/debug.keystore"))}\"),
76
78
  "keystore_password" => "android",
77
79
  "keystore_alias" => "androiddebugkey",
78
80
  }
@@ -6,12 +6,16 @@ require 'json'
6
6
  require 'socket'
7
7
  require 'timeout'
8
8
  require 'calabash-android/helpers'
9
+ require 'calabash-android/wait_helpers'
10
+ require 'calabash-android/version'
9
11
  require 'retriable'
12
+ require 'cucumber'
10
13
 
11
14
 
12
15
  module Calabash module Android
13
16
 
14
17
  module Operations
18
+ include Calabash::Android::WaitHelpers
15
19
 
16
20
  def log(message)
17
21
  $stdout.puts "#{Time.now.strftime("%Y-%m-%d %H:%M:%S")} - #{message}" if (ARGV.include? "-v" or ARGV.include? "--verbose")
@@ -86,19 +90,19 @@ module Operations
86
90
  default_device.set_gps_coordinates(latitude, longitude)
87
91
  end
88
92
 
89
- def wait_for(timeout, &block)
90
- value = nil
91
- begin
92
- Timeout::timeout(timeout) do
93
- until (value = block.call)
94
- sleep 0.3
95
- end
96
- end
97
- rescue Exception => e
98
- raise e
99
- end
100
- value
101
- end
93
+ #def wait_for(timeout, &block)
94
+ # value = nil
95
+ # begin
96
+ # Timeout::timeout(timeout) do
97
+ # until (value = block.call)
98
+ # sleep 0.3
99
+ # end
100
+ # end
101
+ # rescue Exception => e
102
+ # raise e
103
+ # end
104
+ # value
105
+ #end
102
106
 
103
107
  def query(uiquery, *args)
104
108
  converted_args = []
@@ -177,7 +181,7 @@ module Operations
177
181
  succeeded = `#{adb_command} shell pm list packages`.include?("package:#{pn}")
178
182
 
179
183
  unless succeeded
180
- Cucumber.wants_to_quit = true
184
+ ::Cucumber.wants_to_quit = true
181
185
  raise "#{pn} did not get installed. Aborting!"
182
186
  end
183
187
  end
@@ -325,7 +329,7 @@ module Operations
325
329
  end
326
330
 
327
331
  def start_test_server_in_background(options={})
328
- raise "Will not start test server because of previous failures." if Cucumber.wants_to_quit
332
+ raise "Will not start test server because of previous failures." if ::Cucumber.wants_to_quit
329
333
 
330
334
  if keyguard_enabled?
331
335
  wake_up
@@ -369,12 +373,39 @@ module Operations
369
373
  log "Instrumentation backend is ready!"
370
374
  end
371
375
  end
376
+ rescue Exception => e
372
377
 
373
- rescue
374
378
  msg = "Unable to make connection to Calabash Test Server at http://127.0.0.1:#{@server_port}/\n"
375
379
  msg << "Please check the logcat output for more info about what happened\n"
376
380
  raise msg
377
381
  end
382
+
383
+ log "Checking client-server version match..."
384
+ response = perform_action('version')
385
+ unless response['success']
386
+ msg = ["Unable to obtain Test Server version. "]
387
+ msg << "Please delete your test_servers"
388
+ msg << "and re-run calabash-android run..."
389
+ msg_s = msg.join("\n")
390
+ log(msg_s)
391
+ raise msg_s
392
+ end
393
+ unless response['message'] == Calabash::Android::SERVER_VERSION
394
+
395
+ msg = ["Calabash Client and Test-server version mismatch."]
396
+ msg << "Client version #{Calabash::Android::VERSION}"
397
+ msg << "Test-server version #{response['message']}"
398
+ msg << "Expected Test-server version #{Calabash::Android::SERVER_VERSION}"
399
+ msg << "\n\nSolution:\n\n"
400
+ msg << "Please delete your test_servers"
401
+ msg << "and re-run calabash-android run..."
402
+ msg_s = msg.join("\n")
403
+ log(msg_s)
404
+ raise msg_s
405
+ end
406
+ log("Client and server versions match. Proceeding...")
407
+
408
+
378
409
  end
379
410
 
380
411
  def shutdown_test_server
@@ -408,7 +439,6 @@ module Operations
408
439
 
409
440
  def screenshot_and_raise(msg)
410
441
  screenshot_embed
411
- sleep 5
412
442
  raise(msg)
413
443
  end
414
444
 
@@ -1,5 +1,6 @@
1
1
  module Calabash
2
2
  module Android
3
- VERSION = "0.4.0.pre11"
3
+ SERVER_VERSION = "0.4.0.pre15"
4
+ VERSION = "0.4.0.pre15"
4
5
  end
5
6
  end
@@ -0,0 +1,93 @@
1
+ module Calabash
2
+ module Android
3
+
4
+ module WaitHelpers
5
+
6
+
7
+ class WaitError < RuntimeError
8
+ end
9
+
10
+
11
+ def wait_for(options_or_timeout=
12
+ {:timeout => 10,
13
+ :retry_frequency => 0.2,
14
+ :post_timeout => 0.1,
15
+ :timeout_message => "Timed out waiting...",
16
+ :screenshot_on_error => true}, &block)
17
+ #note Hash is preferred, number acceptable for backwards compat
18
+ timeout=options_or_timeout
19
+ post_timeout=0.1
20
+ retry_frequency=0.2
21
+ timeout_message = nil
22
+ screenshot_on_error = true
23
+
24
+ if options_or_timeout.is_a?(Hash)
25
+ timeout = options_or_timeout[:timeout] || 10
26
+ retry_frequency = options_or_timeout[:retry_frequency] || 0.2
27
+ post_timeout = options_or_timeout[:post_timeout] || 0.1
28
+ timeout_message = options_or_timeout[:timeout_message]
29
+ screenshot_on_error = options_or_timeout[:screenshot_on_error] || true
30
+ end
31
+
32
+ begin
33
+ Timeout::timeout(timeout, WaitError) do
34
+ sleep(retry_frequency) until yield
35
+ end
36
+ sleep(post_timeout) if post_timeout > 0
37
+ rescue WaitError => e
38
+ handle_error_with_options(e, timeout_message, screenshot_on_error)
39
+ rescue Exception => e
40
+ handle_error_with_options(e, nil, screenshot_on_error)
41
+ end
42
+ end
43
+
44
+ def wait_poll(opts, &block)
45
+ test = opts[:until]
46
+ if test.nil?
47
+ cond = opts[:until_exists]
48
+ raise "Must provide :until or :until_exists" unless cond
49
+ test = lambda { element_exists(cond) }
50
+ end
51
+ wait_for(opts) do
52
+ if test.call()
53
+ true
54
+ else
55
+ yield
56
+ false
57
+ end
58
+ end
59
+ end
60
+
61
+ #options for wait_for apply
62
+ def wait_for_elements_exist(elements_arr, options={})
63
+ options[:timeout_message] = options[:timeout_message] || "Timeout waiting for elements: #{elements_arr.join(",")}"
64
+ wait_for(options) do
65
+ elements_arr.all? { |q| element_exists(q) }
66
+ end
67
+ end
68
+
69
+ #options for wait_for apply
70
+ def wait_for_elements_do_not_exist(elements_arr, options={})
71
+ options[:timeout_message] = options[:timeout_message] || "Timeout waiting for no elements matching: #{elements_arr.join(",")}"
72
+ wait_for(options) do
73
+ elements_arr.none? { |q| element_exists(q) }
74
+ end
75
+ end
76
+
77
+ def handle_error_with_options(ex, timeout_message, screenshot_on_error)
78
+ msg = (timeout_message || ex)
79
+ if ex
80
+ msg = "#{msg} (#{ex.class})"
81
+ end
82
+ if screenshot_on_error
83
+ screenshot_and_raise msg
84
+ else
85
+ raise msg
86
+ end
87
+ end
88
+
89
+
90
+ end
91
+ end
92
+ end
93
+
@@ -12,7 +12,7 @@ options {
12
12
  package sh.calaba.instrumentationbackend.query.antlr;
13
13
  }
14
14
 
15
- @members {
15
+ @lexer::members {
16
16
  public String getErrorMessage(RecognitionException e, String[] tokenNames)
17
17
  {
18
18
  List stack = getRuleInvocationStack(e, this.getClass().getName());
@@ -20,6 +20,7 @@ options {
20
20
  if ( e instanceof NoViableAltException ) {
21
21
  NoViableAltException nvae = (NoViableAltException)e;
22
22
  msg = " no viable alt; token="+e.token+" (decision="+nvae.decisionNumber+" state "+nvae.stateNumber+")"+" decision=<<"+nvae.grammarDecisionDescription+">>";
23
+ throw new RuntimeException(msg, e);
23
24
  }
24
25
  else {
25
26
  msg = super.getErrorMessage(e, tokenNames);
@@ -0,0 +1,19 @@
1
+ package sh.calaba.instrumentationbackend.actions.activity;
2
+
3
+ import sh.calaba.instrumentationbackend.InstrumentationBackend;
4
+ import sh.calaba.instrumentationbackend.Result;
5
+ import sh.calaba.instrumentationbackend.actions.Action;
6
+
7
+ public class FinishOpenedActivities implements Action {
8
+
9
+ @Override
10
+ public Result execute(String... args) {
11
+ InstrumentationBackend.solo.finishOpenedActivities();
12
+ return Result.successResult();
13
+ }
14
+
15
+ @Override
16
+ public String key() {
17
+ return "finish_opened_activities";
18
+ }
19
+ }
@@ -0,0 +1,31 @@
1
+ package sh.calaba.instrumentationbackend.actions.activity;
2
+
3
+ import java.util.ArrayList;
4
+
5
+ import sh.calaba.instrumentationbackend.InstrumentationBackend;
6
+ import sh.calaba.instrumentationbackend.Result;
7
+ import sh.calaba.instrumentationbackend.actions.Action;
8
+ import android.app.Activity;
9
+
10
+ public class GetOpenedActivities implements Action {
11
+
12
+ @Override
13
+ public Result execute(String... args) {
14
+ final ArrayList<Activity> activities = InstrumentationBackend.solo
15
+ .getAllOpenedActivities();
16
+ final ArrayList<String> opened = new ArrayList<String>(
17
+ activities.size());
18
+
19
+ for (final Activity activity : activities) {
20
+ opened.add(activity.getClass().getSimpleName());
21
+ }
22
+
23
+ // opened is attached to bonusInformation
24
+ return new Result(true, opened);
25
+ }
26
+
27
+ @Override
28
+ public String key() {
29
+ return "get_opened_activities";
30
+ }
31
+ }
@@ -0,0 +1,67 @@
1
+ package sh.calaba.instrumentationbackend.actions.activity;
2
+
3
+ import java.util.ArrayList;
4
+
5
+ import android.app.Activity;
6
+ import android.view.KeyEvent;
7
+ import sh.calaba.instrumentationbackend.InstrumentationBackend;
8
+ import sh.calaba.instrumentationbackend.Result;
9
+ import sh.calaba.instrumentationbackend.actions.Action;
10
+ import sh.calaba.instrumentationbackend.actions.Actions;
11
+
12
+ public class GoBackToActivity implements Action {
13
+
14
+ @Override
15
+ public Result execute(String... args) {
16
+
17
+ if (args == null) {
18
+ return Result
19
+ .failedResult("Target activity name must not be null.");
20
+ }
21
+
22
+ if (args.length != 1) {
23
+ return Result.failedResult("Must pass exactly one argument.");
24
+ }
25
+
26
+ if (args[0].trim().length() == 0) {
27
+ return Result.failedResult("Argument must not be whitespace.");
28
+ }
29
+
30
+ final String targetActivityName = args[0];
31
+
32
+ final ArrayList<Activity> activities = InstrumentationBackend.solo
33
+ .getAllOpenedActivities();
34
+ boolean success = false;
35
+
36
+ final ArrayList<String> opened = new ArrayList<String>(
37
+ activities.size());
38
+
39
+ for (final Activity activity : activities) {
40
+ final String name = activity.getClass().getSimpleName();
41
+ if (name.contentEquals(targetActivityName)) {
42
+ success = true;
43
+ }
44
+ opened.add(name);
45
+ }
46
+
47
+ if (!success) {
48
+ return new Result(false, opened);
49
+ }
50
+
51
+ while (!InstrumentationBackend.solo.getCurrentActivity().getClass()
52
+ .getSimpleName().contentEquals(targetActivityName)) {
53
+ try {
54
+ Actions.parentInstrumentation
55
+ .sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
56
+ } catch (Exception exception) {
57
+ }
58
+ }
59
+
60
+ return new Result(true, opened);
61
+ }
62
+
63
+ @Override
64
+ public String key() {
65
+ return "go_back_to_activity";
66
+ }
67
+ }
@@ -0,0 +1,28 @@
1
+ package sh.calaba.instrumentationbackend.actions.gestures;
2
+
3
+ import sh.calaba.instrumentationbackend.InstrumentationBackend;
4
+ import sh.calaba.instrumentationbackend.Result;
5
+ import sh.calaba.instrumentationbackend.actions.Action;
6
+
7
+ public class DragCoordinates implements Action {
8
+
9
+ @Override
10
+ public Result execute(String... args) {
11
+
12
+ Float fromX = new Float(args[0]);
13
+ Float fromY = new Float(args[1]);
14
+ Float toX = new Float(args[2]);
15
+ Float toY = new Float(args[3]);
16
+ Integer stepCount = 40;
17
+
18
+ InstrumentationBackend.solo.drag(fromX, toX, fromY, toY, stepCount);
19
+
20
+ return Result.successResult();
21
+ }
22
+
23
+ @Override
24
+ public String key() {
25
+ return "drag_coordinates";
26
+ }
27
+
28
+ }