calabash-android 0.4.22.pre1 → 0.4.22.pre3

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: bc93d1240918ff9a76dae74dde0855edb68a05b6
4
- data.tar.gz: 9622711e7861d7402da6865b2dbc94a954251a13
3
+ metadata.gz: 6d221e4c80dd7613507106fb29b003b973f7bb90
4
+ data.tar.gz: 00acef8ea096b2fadd7d4d78a3351fdc14e080f6
5
5
  SHA512:
6
- metadata.gz: dda85df8ba2995fad39966ed162ad282cb3d20dd2c208bd2cd1267cc3de9c0303426ca72ab6a4d0dfb66c3655ce61fc531a61f77cc5d4913c0e4e83c188095f2
7
- data.tar.gz: 526469c307c9e51a7a76c46ebc4f308bdf04e954d144e1bd691ec5642841057b07e7bdd847f8287eb022dd8d99eabee7a62378d03f26906418f5e61282973fe7
6
+ metadata.gz: ca7532fbf81f589c0a34b889db471ac9ce0730240dcd2cfde663271f937319e0784194575d4feb1993271f1c3936cc88be175fe4a2114507ee1113901ba0e0e7
7
+ data.tar.gz: 1e5a8fceb981f4508120066a950ffde01fbb2744f1b501429162f2a36609ebc0c54f171f450b6ccf4647d3ba1ab9f521e3206e3bf73a1ccc6d1aeeee08d3d651
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- calabash-android (0.4.20)
4
+ calabash-android (0.4.22.pre1)
5
5
  awesome_print
6
6
  cucumber
7
7
  escape (~> 0.0.4)
@@ -17,7 +17,7 @@ GEM
17
17
  specs:
18
18
  awesome_print (1.2.0)
19
19
  builder (3.2.2)
20
- cucumber (1.3.10)
20
+ cucumber (1.3.11)
21
21
  builder (>= 2.1.2)
22
22
  diff-lcs (>= 1.1.3)
23
23
  gherkin (~> 2.12)
@@ -30,7 +30,7 @@ GEM
30
30
  httpclient (2.3.4.1)
31
31
  json (1.8.1)
32
32
  mime-types (1.25.1)
33
- multi_json (1.8.4)
33
+ multi_json (1.9.0)
34
34
  multi_test (0.0.3)
35
35
  rake (10.1.0)
36
36
  rest-client (1.6.7)
@@ -40,7 +40,7 @@ GEM
40
40
  slowhandcuke (0.0.3)
41
41
  cucumber
42
42
  thor (0.18.1)
43
- xamarin-test-cloud (0.9.28)
43
+ xamarin-test-cloud (0.9.29)
44
44
  bundler (>= 1.3.0, < 2.0)
45
45
  json
46
46
  mime-types (< 2.0)
@@ -722,6 +722,16 @@ module Operations
722
722
  performAction("touch_coordinate", center_x, center_y)
723
723
  end
724
724
 
725
+ def keyboard_enter_text(text, options = {})
726
+ performAction('keyboard_enter_text', text)
727
+ end
728
+
729
+ def enter_text(uiquery, text, options = {})
730
+ touch(uiquery, options)
731
+ sleep 0.5
732
+ keyboard_enter_text(text, options)
733
+ end
734
+
725
735
  def find_coordinate(uiquery)
726
736
  raise "Cannot find nil" unless uiquery
727
737
 
@@ -1,5 +1,5 @@
1
1
  module Calabash
2
2
  module Android
3
- VERSION = "0.4.22.pre1"
3
+ VERSION = "0.4.22.pre3"
4
4
  end
5
5
  end
@@ -7,26 +7,32 @@ module Calabash
7
7
  class WaitError < RuntimeError
8
8
  end
9
9
 
10
+ # 'post_timeout' is the time to wait after a wait function returns true
11
+ DEFAULT_OPTS = {
12
+ :timeout => 30,
13
+ :retry_frequency => 0.3,
14
+ :post_timeout => 0,
15
+ :timeout_message => 'Timed out waiting...',
16
+ :screenshot_on_error => true
17
+ }.freeze
10
18
 
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)
19
+ def wait_for(options_or_timeout=DEFAULT_OPTS, &block)
17
20
  #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
+ default_timeout = 30
22
+ timeout = options_or_timeout || default_timeout
23
+ post_timeout=0
24
+ retry_frequency=0.3
21
25
  timeout_message = nil
22
26
  screenshot_on_error = true
23
27
 
24
28
  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
29
+ timeout = options_or_timeout[:timeout] || default_timeout
30
+ retry_frequency = options_or_timeout[:retry_frequency] || retry_frequency
31
+ post_timeout = options_or_timeout[:post_timeout] || post_timeout
28
32
  timeout_message = options_or_timeout[:timeout_message]
29
- screenshot_on_error = options_or_timeout[:screenshot_on_error] || true
33
+ if options_or_timeout.key?(:screenshot_on_error)
34
+ screenshot_on_error = options_or_timeout[:screenshot_on_error]
35
+ end
30
36
  end
31
37
 
32
38
  begin
@@ -35,12 +41,31 @@ module Calabash
35
41
  end
36
42
  sleep(post_timeout) if post_timeout > 0
37
43
  rescue WaitError => e
38
- handle_error_with_options(e, timeout_message, screenshot_on_error)
44
+ msg = timeout_message || e
45
+ if screenshot_on_error
46
+ sleep(retry_frequency)
47
+ return screenshot_and_retry(msg, &block)
48
+ else
49
+ raise wait_error(msg)
50
+ end
39
51
  rescue Exception => e
40
52
  handle_error_with_options(e, nil, screenshot_on_error)
41
53
  end
42
54
  end
43
55
 
56
+ def screenshot_and_retry(msg, &block)
57
+ path = screenshot
58
+ res = yield
59
+ # Validate after taking screenshot
60
+ if res
61
+ FileUtils.rm_f(path)
62
+ return res
63
+ else
64
+ embed(path, 'image/png', msg)
65
+ raise wait_error(msg)
66
+ end
67
+ end
68
+
44
69
  def wait_poll(opts, &block)
45
70
  test = opts[:until]
46
71
  if test.nil?
@@ -58,16 +83,21 @@ module Calabash
58
83
  end
59
84
  end
60
85
 
61
- #options for wait_for apply
86
+ #options for wait_for apply
62
87
  def wait_for_elements_exist(elements_arr, options={})
88
+ if elements_arr.is_a?(String) || elements_arr.is_a?(Symbol)
89
+ elements_arr = [elements_arr.to_s]
90
+ end
63
91
  options[:timeout_message] = options[:timeout_message] || "Timeout waiting for elements: #{elements_arr.join(",")}"
64
92
  wait_for(options) do
65
93
  elements_arr.all? { |q| element_exists(q) }
66
94
  end
67
95
  end
68
-
69
- #options for wait_for apply
96
+ #options for wait_for apply
70
97
  def wait_for_elements_do_not_exist(elements_arr, options={})
98
+ if elements_arr.is_a?(String)
99
+ elements_arr = [elements_arr]
100
+ end
71
101
  options[:timeout_message] = options[:timeout_message] || "Timeout waiting for no elements matching: #{elements_arr.join(",")}"
72
102
  wait_for(options) do
73
103
  elements_arr.none? { |q| element_exists(q) }
@@ -86,6 +116,60 @@ module Calabash
86
116
  end
87
117
  end
88
118
 
119
+ def wait_error(msg)
120
+ (msg.is_a?(String) ? WaitError.new(msg) : msg)
121
+ end
122
+
123
+ # Performs a lambda action until the element (a query string) appears.
124
+ # The default action is to do nothing.
125
+ #
126
+ # Raises an error if no uiquery is specified. Same options as wait_for
127
+ # which are timeout, retry frequency, post_timeout, timeout_message, and
128
+ # screenshot on error.
129
+ #
130
+ # Example usage:
131
+ # until_element_exists("Button", :action => lambda { swipe("up") })
132
+ def until_element_exists(uiquery, opts = {})
133
+ extra_opts = { :until_exists => uiquery, :action => lambda { ; } }
134
+ opts = DEFAULT_OPTS.merge(extra_opts).merge(opts)
135
+ wait_poll(opts) do
136
+ opts[:action].call
137
+ end
138
+ end
139
+
140
+ # Performs a lambda action until the element (a query string) disappears.
141
+ # The default action is to do nothing.
142
+ #
143
+ # Raises an error if no uiquery is specified. Same options as wait_for
144
+ # which are timeout, retry frequency, post_timeout, timeout_message, and
145
+ # screenshot on error.
146
+ #
147
+ # Example usage:
148
+ # until_element_does_not_exist("Button", :action => lambda { swipe("up") })
149
+ def until_element_does_not_exist(uiquery, opts = {})
150
+ condition = lambda { element_exists(uiquery) ? false : true }
151
+ extra_opts = { :until => condition, :action => lambda { ; } }
152
+ opts = DEFAULT_OPTS.merge(extra_opts).merge(opts)
153
+ wait_poll(opts) do
154
+ opts[:action].call
155
+ end
156
+ end
157
+
158
+ # Performs a lambda action once the element exists.
159
+ # The default behavior is to touch the specified element.
160
+ #
161
+ # Raises an error if no uiquery is specified. Same options as wait_for
162
+ # which are timeout, retry frequency, post_timeout, timeout_message, and
163
+ # screenshot on error.
164
+ #
165
+ # Example usage: when_element_exists("Button", :timeout => 10)
166
+ def when_element_exists(uiquery, opts = {})
167
+ action = { :action => lambda { touch uiquery } }
168
+ opts = DEFAULT_OPTS.merge(action).merge(opts)
169
+ wait_for_elements_exist([uiquery], opts)
170
+ opts[:action].call
171
+ end
172
+
89
173
 
90
174
  end
91
175
  end
@@ -78,4 +78,8 @@ public class SoloEnhanced extends Solo {
78
78
  clicker.clickOnScreen(x,y);
79
79
  clicker.clickOnScreen(x,y);
80
80
  }
81
+
82
+ public void runOnMainSync(Runnable runner) {
83
+ instrumentation.runOnMainSync(runner);
84
+ }
81
85
  }
@@ -12,7 +12,7 @@ public class CalabashInstrumentationTestRunner extends InstrumentationTestRunner
12
12
  @Override
13
13
  public void onCreate(Bundle arguments) {
14
14
  try {
15
- Context context = getTargetContext ();
15
+ Context context = getTargetContext();
16
16
  Class<?> c = Class.forName("mono.MonoPackageManager");
17
17
  Method method = c.getDeclaredMethod ("LoadApplication", Context.class, String.class, String[].class);
18
18
  method.invoke (null, context, null, new String[]{context.getApplicationInfo ().sourceDir});
@@ -28,8 +28,8 @@ public class CalabashInstrumentationTestRunner extends InstrumentationTestRunner
28
28
  InstrumentationBackend.extras = arguments;
29
29
 
30
30
  try {
31
- InstrumentationBackend.mainActivity = Class.forName(arguments.getString("main_activity")).asSubclass(Activity.class);
32
- } catch (ClassNotFoundException e) {
31
+ InstrumentationBackend.mainActivity = arguments.getString("main_activity");
32
+ } catch (Exception e) {
33
33
  throw new RuntimeException(e);
34
34
  }
35
35
 
@@ -24,7 +24,7 @@ import java.util.concurrent.atomic.AtomicReference;
24
24
 
25
25
  public class InstrumentationBackend extends ActivityInstrumentationTestCase2<Activity> {
26
26
  public static String testPackage;
27
- public static Class<? extends Activity> mainActivity;
27
+ public static String mainActivity;
28
28
  public static Bundle extras;
29
29
 
30
30
  private static final String TAG = "InstrumentationBackend";
@@ -34,16 +34,36 @@ public class InstrumentationBackend extends ActivityInstrumentationTestCase2<Act
34
34
  public static PublicViewFetcher viewFetcher;
35
35
  public static Actions actions;
36
36
 
37
- @SuppressWarnings({ "deprecation", "unchecked" })
38
37
  public InstrumentationBackend() {
39
- super(testPackage, (Class<Activity>) mainActivity);
38
+ super(null);
39
+ }
40
+
41
+ @Override
42
+ public Activity getActivity() {
43
+ try {
44
+ setMainActivity(Class.forName(mainActivity).asSubclass(Activity.class));
45
+ return super.getActivity();
46
+ } catch (ClassNotFoundException e) {
47
+ throw new RuntimeException(e);
48
+ }
49
+ }
50
+
51
+ private void setMainActivity(Class<? extends Activity> mainActivity) {
52
+ try {
53
+ Field mActivityClass = ActivityInstrumentationTestCase2.class.getDeclaredField("mActivityClass");
54
+ mActivityClass.setAccessible(true);
55
+ mActivityClass.set(this, mainActivity);
56
+ } catch (Exception e) {
57
+ throw new RuntimeException(e);
58
+ }
40
59
  }
41
60
 
42
61
  @Override
43
62
  protected void setUp() throws Exception {
44
63
  super.setUp();
45
- Intent i = new Intent();
46
- i.setClassName(testPackage, mainActivity.getName());
64
+ Intent i = new Intent(Intent.ACTION_MAIN);
65
+ i.setClassName(testPackage, mainActivity);
66
+ i.addCategory("android.intent.category.LAUNCHER");
47
67
  i.putExtras(extras);
48
68
  setActivityIntent(i);
49
69
 
@@ -0,0 +1,62 @@
1
+ package sh.calaba.instrumentationbackend.actions.text;
2
+
3
+ import android.app.Activity;
4
+ import android.content.Context;
5
+ import android.view.View;
6
+ import android.view.inputmethod.InputConnection;
7
+ import android.view.inputmethod.InputMethodManager;
8
+
9
+ import java.lang.Character;
10
+ import java.lang.reflect.Field;
11
+
12
+ import sh.calaba.instrumentationbackend.InstrumentationBackend;
13
+ import sh.calaba.instrumentationbackend.Result;
14
+ import sh.calaba.instrumentationbackend.actions.Action;
15
+
16
+ public class KeyboardEnterText implements Action {
17
+ @Override
18
+ public Result execute(String... args) {
19
+ if (args.length != 1) {
20
+ return Result.failedResult("This action takes one argument ([String] text).");
21
+ }
22
+
23
+ final InputConnection inputConnection = getInputConnection();
24
+
25
+ final String textToEnter = args[0];
26
+ InstrumentationBackend.solo.runOnMainSync(new Runnable() {
27
+ @Override
28
+ public void run() {
29
+ for (char c : textToEnter.toCharArray()) {
30
+ inputConnection.commitText(Character.toString(c), 0);
31
+ }
32
+ }
33
+ });
34
+
35
+ return Result.successResult();
36
+ }
37
+
38
+ @Override
39
+ public String key() {
40
+ return "keyboard_enter_text";
41
+ }
42
+
43
+ InputConnection getInputConnection() {
44
+ Activity currentActivity = InstrumentationBackend.solo.getCurrentActivity();
45
+ final View view = currentActivity.getCurrentFocus();
46
+
47
+ Context context = view.getContext();
48
+
49
+ if (context == null) {
50
+ context = currentActivity.getApplicationContext();
51
+ }
52
+
53
+ try {
54
+ InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
55
+ Field servedInputConnectionField = InputMethodManager.class.getDeclaredField("mServedInputConnection");
56
+ servedInputConnectionField.setAccessible(true);
57
+ return (InputConnection)servedInputConnectionField.get(inputMethodManager);
58
+ } catch (Exception e) {
59
+ throw new RuntimeException(e);
60
+ }
61
+ }
62
+ }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: calabash-android
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.22.pre1
4
+ version: 0.4.22.pre3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonas Maturana Larsen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-12 00:00:00.000000000 Z
11
+ date: 2014-04-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cucumber
@@ -399,6 +399,7 @@ files:
399
399
  - test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/EnterTextById.java
400
400
  - test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/EnterTextByIndex.java
401
401
  - test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/GetTextById.java
402
+ - test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/KeyboardEnterText.java
402
403
  - test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/time/SetDateByContentDescription.java
403
404
  - test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/time/SetDateByIndex.java
404
405
  - test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/time/SetTimeByContentDescription.java