calabash-android 0.2.9 → 0.2.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,13 @@
1
+ 0.2.10:
2
+ Various small improvements and bug fixes.
3
+
4
+ Default behavior is now to shutdown the test server after scenario.
5
+ calabash-android now waits for the test server to be ready before sending
6
+ the first command.
7
+
8
+ If the environment variable RESET_BETWEEN_SCENARIOS is "1" the app will
9
+ be reinstalled between scenarios and not just between features.
10
+
1
11
  0.2.9:
2
12
  Moving to the new http screenshot method.
3
13
  screenshottaker.jar and the use of ddmlib will be phased out.
@@ -56,8 +56,4 @@ def read_keystore_info
56
56
  "keystore_alias_password" => "android"
57
57
  }
58
58
  end
59
- end
60
-
61
- def is_windows?
62
- ENV["OS"] == "Windows_NT"
63
59
  end
@@ -19,5 +19,6 @@ Gem::Specification.new do |s|
19
19
  s.add_dependency( "cucumber" )
20
20
  s.add_dependency( "json" )
21
21
  s.add_dependency( "slowhandcuke" )
22
+ s.add_dependency( "retriable" )
22
23
 
23
24
  end
@@ -6,8 +6,13 @@ end
6
6
 
7
7
  Before do |scenario|
8
8
  feature_name = scenario.feature.name
9
- if FeatureNameMemory.feature_name != feature_name
10
- log "Is first scenario - reinstalling apps"
9
+ if FeatureNameMemory.feature_name != feature_name \
10
+ or ENV["RESET_BETWEEN_SCENARIOS"] == "1"
11
+ if ENV["RESET_BETWEEN_SCENARIOS"] == "1"
12
+ log "New scenario - reinstalling apps"
13
+ else
14
+ log "First scenario in feature - reinstalling apps"
15
+ end
11
16
 
12
17
  uninstall_apps
13
18
  install_app(ENV["TEST_APP_PATH"])
@@ -16,11 +21,6 @@ Before do |scenario|
16
21
  end
17
22
  end
18
23
 
19
- at_exit do
20
- require 'net/http'
21
- Net::HTTP.get(URI.parse("http://127.0.0.1:34777/kill"))
22
- end
23
-
24
24
  FeatureNameMemory = Class.new
25
25
  class << FeatureNameMemory
26
26
  @feature_name = nil
@@ -4,4 +4,8 @@ Before do |scenario|
4
4
 
5
5
  return if scenario.failed? #No need to start the server is anything before this has failed.
6
6
  start_test_server_in_background
7
- end
7
+ end
8
+
9
+ After do
10
+ shutdown_test_server
11
+ end
@@ -159,6 +159,10 @@ Waits for the current dialog to close.
159
159
  Then /^I wait to see "([^\"]*)"$/
160
160
  Waits for the specified text to appear.
161
161
 
162
+ Then /^I wait up to (\d+) seconds for "([^\"]*)" to appear$/
163
+ Then /^I wait up to (\d+) seconds to see "([^\"]*)"$/
164
+ Waits for the specified text to appear, with a custom timeout
165
+
162
166
  Then /^I wait for the "([^\"]*)" button to appear$/
163
167
  Waits for a button with the specified text to appear.
164
168
 
@@ -170,6 +174,7 @@ Waits for a view view that id to appear.
170
174
  Note that use the short name and not the fully quantified name. That means if your id
171
175
  is 'com.foo.R.id.bar_label' you would use 'I press view with id "bar_label"'.
172
176
 
177
+ Then /^I wait up to (\d+) seconds for the "([^\"]*)" screen to appear$/
173
178
  Then /^I wait upto (\d+) seconds for the "([^\"]*)" screen to appear$/
174
179
  Waits for a particular screen (Android Activity) to appear with a timeout.
175
180
 
@@ -50,4 +50,9 @@ def test_server_path(apk_file_path)
50
50
  "test_servers/#{checksum(apk_file_path)}_#{Calabash::Android::VERSION}.apk"
51
51
  end
52
52
 
53
+ def is_windows?
54
+ require 'rbconfig'
55
+ (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/)
56
+ end
57
+
53
58
 
@@ -6,6 +6,7 @@ require 'json'
6
6
  require 'socket'
7
7
  require 'timeout'
8
8
  require 'calabash-android/helpers'
9
+ require 'retriable'
9
10
 
10
11
 
11
12
  module Calabash module Android
@@ -29,6 +30,10 @@ module Operations
29
30
  end
30
31
  end
31
32
 
33
+ def shutdown_test_server
34
+ Device.default_device.shutdown_test_server
35
+ end
36
+
32
37
  def performAction(action, *arguments)
33
38
  Device.default_device.perform_action(action, *arguments)
34
39
  end
@@ -76,9 +81,6 @@ module Operations
76
81
  raise "Not yet implemented."
77
82
  end
78
83
 
79
- def is_windows?
80
- ENV["OS"] == "Windows_NT"
81
- end
82
84
  ###
83
85
 
84
86
  ### app life cycle
@@ -144,6 +146,10 @@ module Operations
144
146
  log `#{adb_command} uninstall #{package_name}`
145
147
  end
146
148
 
149
+ def shutdown_test_server
150
+ http("/kill")
151
+ end
152
+
147
153
  def perform_action(action, *arguments)
148
154
  log "Action: #{action} - Params: #{arguments.join(', ')}"
149
155
 
@@ -222,10 +228,6 @@ module Operations
222
228
  end
223
229
  end
224
230
 
225
- def is_windows?
226
- ENV["OS"] == "Windows_NT"
227
- end
228
-
229
231
  def start_test_server_in_background
230
232
  test_server_package = package_name(@test_server_path)
231
233
  cmd = "#{adb_command} shell am instrument -w -e class sh.calaba.instrumentationbackend.InstrumentationBackend #{test_server_package}/sh.calaba.instrumentationbackend.CalabashInstrumentationTestRunner"
@@ -238,10 +240,19 @@ module Operations
238
240
  end
239
241
 
240
242
  begin
241
- Timeout::timeout(15) do
242
- puts http("/ping")
243
+ retriable :tries => 10, :interval => 3 do
244
+ log "Checking if instrumentation backend is ready"
245
+ ready = http("/ready")
246
+
247
+ if ready != "true"
248
+ log "Instrumentation backend not yet ready"
249
+ raise "Not ready"
250
+ else
251
+ log "Instrumentation backend is ready!"
252
+ end
243
253
  end
244
- rescue Timeout::Error
254
+
255
+ rescue
245
256
  msg = "Unable to make connection to Calabash Test Server at http://127.0.0.1:#{@server_port}/\n"
246
257
  msg << "Please check the logcat output for more info about what happened\n"
247
258
  raise msg
@@ -28,10 +28,18 @@ Then /^I wait for "([^\"]*)" to appear$/ do |text|
28
28
  performAction('wait_for_text', text)
29
29
  end
30
30
 
31
+ Then /^I wait up to (\d+) seconds for "([^\"]*)" to appear$/ do |timeout, text|
32
+ performAction('wait_for_text', text, timeout)
33
+ end
34
+
31
35
  Then /^I wait to see "([^\"]*)"$/ do |text|
32
36
  performAction('wait_for_text', text)
33
37
  end
34
38
 
39
+ Then /^I wait up to (\d+) seconds to see "([^\"]*)"$/ do |timeout, text|
40
+ performAction('wait_for_text', text, timeout)
41
+ end
42
+
35
43
  Then /^I wait for the "([^\"]*)" button to appear$/ do |text|
36
44
  performAction('wait_for_button', text)
37
45
  end
@@ -40,6 +48,11 @@ Then /^I wait for the view with id "([^\"]*)" to appear$/ do |text|
40
48
  performAction('wait_for_view_by_id', text)
41
49
  end
42
50
 
51
+ Then /^I wait for the "([^\"]*)" view to appear$/ do |text|
52
+ performAction('wait_for_view', text)
53
+ end
54
+
55
+
43
56
  Then /^I wait for the "([^\"]*)" screen to appear$/ do |text|
44
57
  performAction('wait_for_screen', text)
45
58
  end
@@ -47,3 +60,7 @@ end
47
60
  Then /^I wait upto (\d+) seconds for the "([^\"]*)" screen to appear$/ do |timeout, text|
48
61
  performAction('wait_for_screen', text, timeout)
49
62
  end
63
+
64
+ Then /^I wait up to (\d+) seconds for the "([^\"]*)" screen to appear$/ do |timeout, text|
65
+ performAction('wait_for_screen', text, timeout)
66
+ end
@@ -1,6 +1,6 @@
1
1
  module Calabash
2
2
  module Android
3
- VERSION = "0.2.9"
4
- FRAMEWORK_VERSION = "0.2.9"
3
+ VERSION = "0.2.10"
4
+ FRAMEWORK_VERSION = "0.2.10"
5
5
  end
6
6
  end
@@ -5,6 +5,7 @@ import java.lang.reflect.Method;
5
5
  import android.content.Context;
6
6
  import android.os.Bundle;
7
7
  import android.test.InstrumentationTestRunner;
8
+ import sh.calaba.instrumentationbackend.actions.HttpServer;
8
9
 
9
10
  public class CalabashInstrumentationTestRunner extends InstrumentationTestRunner {
10
11
  @Override
@@ -18,6 +19,10 @@ public class CalabashInstrumentationTestRunner extends InstrumentationTestRunner
18
19
  } catch (Exception e) {
19
20
  System.out.println("Calabash could not load Mono");
20
21
  }
22
+
23
+ // Start the HttpServer as soon as possible in a not-ready state
24
+ HttpServer.instantiate();
25
+
21
26
  super.onCreate(arguments);
22
27
  }
23
28
  }
@@ -12,13 +12,12 @@ public class InstrumentationBackend extends ActivityInstrumentationTestCase2 {
12
12
  public static final String TARGET_PACKAGE = "#ACTIVITY_PACKAGE#"; //Set from Ant at compile time
13
13
  private static final String LAUNCHER_ACTIVITY_FULL_CLASSNAME = "#ACTIVITY_QUALIFIED_NAME#"; //Set from Ant at compile time
14
14
 
15
- private static final String TAG = "IntrumentationBackend";
15
+ private static final String TAG = "InstrumentationBackend";
16
16
 
17
17
  public static Instrumentation instrumentation;
18
18
  public static Solo solo;
19
19
  public static Actions actions;
20
- private HttpServer httpServer;
21
-
20
+
22
21
  private static Class getActivityClass() {
23
22
  try {
24
23
  return Class.forName(LAUNCHER_ACTIVITY_FULL_CLASSNAME);
@@ -45,18 +44,17 @@ public class InstrumentationBackend extends ActivityInstrumentationTestCase2 {
45
44
  * Here to have JUnit3 start the instrumentationBackend
46
45
  */
47
46
  public void testHook() throws Exception {
48
- httpServer = new HttpServer();
49
- while(httpServer.isRunning()) {
50
- Thread.sleep(500);
51
- }
47
+ HttpServer httpServer = HttpServer.getInstance();
48
+ httpServer.setReady();
49
+ httpServer.waitUntilShutdown();
50
+ solo.finishOpenedActivities();
52
51
  }
53
52
 
54
53
  @Override
55
54
  public void tearDown() throws Exception {
56
-
57
- if (httpServer != null) {
58
- httpServer.stop();
59
- }
55
+ HttpServer httpServer = HttpServer.getInstance();
56
+ httpServer.stop();
57
+
60
58
  System.out.println("Finishing");
61
59
  try {
62
60
  solo.finalize();
@@ -4,6 +4,9 @@ import java.io.ByteArrayInputStream;
4
4
  import java.io.ByteArrayOutputStream;
5
5
  import java.io.File;
6
6
  import java.util.Properties;
7
+ import java.util.concurrent.locks.Condition;
8
+ import java.util.concurrent.locks.Lock;
9
+ import java.util.concurrent.locks.ReentrantLock;
7
10
 
8
11
  import android.graphics.Bitmap;
9
12
  import android.view.View;
@@ -15,12 +18,43 @@ import sh.calaba.org.codehaus.jackson.map.ObjectMapper;
15
18
  import android.util.Log;
16
19
 
17
20
  public class HttpServer extends NanoHTTPD {
18
- private static final String TAG = "IntrumentationBackend";
19
- private boolean running = true;
20
-
21
+ private static final String TAG = "InstrumentationBackend";
22
+ private boolean running = true;
23
+ private boolean ready = false;
24
+
25
+ private final Lock lock = new ReentrantLock();
26
+ private final Condition shutdownCondition = lock.newCondition();
27
+
21
28
  private final ObjectMapper mapper = createJsonMapper();
22
29
 
23
- public HttpServer() {
30
+ private static HttpServer instance;
31
+
32
+ /**
33
+ * Creates and returns the singleton instance for HttpServer.
34
+ *
35
+ * Can only be called once. Otherwise, you'll get an IllegalStateException.
36
+ */
37
+ public synchronized static HttpServer instantiate() {
38
+ if(instance != null) {
39
+ throw new IllegalStateException("Can only instantiate once!");
40
+ }
41
+ instance = new HttpServer();
42
+ return instance;
43
+ }
44
+
45
+ /**
46
+ * Returns the singleton instance for HttpServer.
47
+ *
48
+ * If {@link #instantiate()} hasn't already been called, an IllegalStateException is thrown.
49
+ */
50
+ public synchronized static HttpServer getInstance() {
51
+ if(instance == null) {
52
+ throw new IllegalStateException("Must be initialized!");
53
+ }
54
+ return instance;
55
+ }
56
+
57
+ private HttpServer() {
24
58
  super(7102, new File("/"));
25
59
  }
26
60
 
@@ -29,11 +63,23 @@ public class HttpServer extends NanoHTTPD {
29
63
  System.out.println("URI: " + uri);
30
64
  if (uri.endsWith("/ping")) {
31
65
  return new NanoHTTPD.Response( HTTP_OK, MIME_HTML, "pong");
32
- } else if (uri.endsWith("/kill")) {
33
- running = false;
34
- System.out.println("Stopping test server");
35
- stop();
36
- return new NanoHTTPD.Response( HTTP_OK, MIME_HTML, "Affirmative!");
66
+
67
+ } else if (uri.endsWith("/kill")) {
68
+ lock.lock();
69
+ try {
70
+ running = false;
71
+ System.out.println("Stopping test server");
72
+ stop();
73
+
74
+ shutdownCondition.signal();
75
+ return new NanoHTTPD.Response( HTTP_OK, MIME_HTML, "Affirmative!");
76
+ } finally {
77
+ lock.unlock();
78
+ }
79
+
80
+ } else if ("/ready".equals(uri)) {
81
+ return new Response(HTTP_OK, MIME_HTML, Boolean.toString(ready));
82
+
37
83
 
38
84
  } else if (uri.endsWith("/screenshot")) {
39
85
  Bitmap bitmap;
@@ -80,11 +126,22 @@ public class HttpServer extends NanoHTTPD {
80
126
  }
81
127
  }
82
128
 
83
- public boolean isRunning() {
84
- return running;
85
- }
129
+ public void waitUntilShutdown() throws InterruptedException {
130
+ lock.lock();
131
+ try {
132
+ while(running) {
133
+ shutdownCondition.await();
134
+ }
135
+ } finally {
136
+ lock.unlock();
137
+ }
138
+ }
86
139
 
87
140
  public static void log(String message) {
88
141
  Log.i(TAG, message);
89
142
  }
143
+
144
+ public void setReady() {
145
+ ready = true;
146
+ }
90
147
  }
@@ -0,0 +1,30 @@
1
+ package sh.calaba.instrumentationbackend.actions.text;
2
+
3
+ import android.view.View;
4
+ import android.widget.EditText;
5
+ import sh.calaba.instrumentationbackend.InstrumentationBackend;
6
+ import sh.calaba.instrumentationbackend.Result;
7
+ import sh.calaba.instrumentationbackend.TestHelpers;
8
+ import sh.calaba.instrumentationbackend.actions.Action;
9
+
10
+ public class ClearTextById implements Action {
11
+
12
+ @Override
13
+ public Result execute(String... args) {
14
+ final View view = TestHelpers.getViewById(args[0]);
15
+ if(view == null) {
16
+ return new Result(false, "No view found with id: '" + args[0] + "'");
17
+ } else if (!(view instanceof EditText)) {
18
+ return new Result(false, "Expected EditText found: '" + view.getClass() + "'");
19
+ } else {
20
+ InstrumentationBackend.solo.clearEditText((EditText)view);
21
+ return Result.successResult();
22
+ }
23
+ }
24
+
25
+ @Override
26
+ public String key() {
27
+ return "clear_id_field";
28
+ }
29
+
30
+ }
@@ -0,0 +1,30 @@
1
+ package sh.calaba.instrumentationbackend.actions.text;
2
+
3
+ import android.view.View;
4
+ import android.widget.EditText;
5
+ import sh.calaba.instrumentationbackend.InstrumentationBackend;
6
+ import sh.calaba.instrumentationbackend.Result;
7
+ import sh.calaba.instrumentationbackend.TestHelpers;
8
+ import sh.calaba.instrumentationbackend.actions.Action;
9
+
10
+ public class EnterTextById implements Action {
11
+
12
+ @Override
13
+ public Result execute(String... args) {
14
+ final View view = TestHelpers.getViewById(args[1]);
15
+ if(view == null) {
16
+ return new Result(false, "No view found with id: '" + args[1] + "'");
17
+ } else if (!(view instanceof EditText)) {
18
+ return new Result(false, "Expected EditText found: '" + view.getClass() + "'");
19
+ } else {
20
+ InstrumentationBackend.solo.enterText((EditText)view, args[0]);
21
+ return Result.successResult();
22
+ }
23
+ }
24
+
25
+ @Override
26
+ public String key() {
27
+ return "enter_text_into_id_field";
28
+ }
29
+
30
+ }
@@ -0,0 +1,43 @@
1
+ package sh.calaba.instrumentationbackend.actions.view;
2
+
3
+ import sh.calaba.instrumentationbackend.InstrumentationBackend;
4
+ import sh.calaba.instrumentationbackend.Result;
5
+ import sh.calaba.instrumentationbackend.TestHelpers;
6
+ import sh.calaba.instrumentationbackend.actions.Action;
7
+ import android.view.View;
8
+
9
+ public class WaitForView implements Action {
10
+
11
+ @Override
12
+ public Result execute(String... args) {
13
+ String text = args[0];
14
+ long endTime = System.currentTimeMillis() + 60000;
15
+ while (System.currentTimeMillis() < endTime) {
16
+ if (InstrumentationBackend.solo.searchButton(text) || searchForViewWithContentDescription(text)) {
17
+ return Result.successResult();
18
+ } else {
19
+ try {
20
+ Thread.sleep(500);
21
+ } catch (InterruptedException e) {
22
+ return Result.fromThrowable(e);
23
+ }
24
+ }
25
+ }
26
+ return new Result(false, "Timed out while waiting for view with text or contentDescription:'" + text + "'");
27
+ }
28
+
29
+ @Override
30
+ public String key() {
31
+ return "wait_for_view";
32
+ }
33
+
34
+ private boolean searchForViewWithContentDescription(String description) {
35
+ View view = TestHelpers.getViewByDescription(description);
36
+ if (view != null) {
37
+ return true;
38
+ } else {
39
+ return false;
40
+ }
41
+ }
42
+
43
+ }
@@ -25,7 +25,8 @@ public class WaitForScreen implements Action {
25
25
  int timeout = DEFAULT_TIMEOUT;
26
26
 
27
27
  try {
28
- timeout = Integer.parseInt(args[1]);
28
+ // given seconds; want milliseconds
29
+ timeout = 1000 * Integer.parseInt(args[1]);
29
30
  } catch (NumberFormatException e) {
30
31
  return new Result(false, "Invalid timeout supplied. Should be an integer!");
31
32
  }
@@ -46,4 +47,4 @@ public class WaitForScreen implements Action {
46
47
  return "wait_for_screen";
47
48
  }
48
49
 
49
- }
50
+ }
@@ -10,13 +10,24 @@ public class WaitForText implements Action {
10
10
 
11
11
  @Override
12
12
  public Result execute(String... args) {
13
- boolean timedOut = !InstrumentationBackend.solo.waitForText(args[0], 1, 90000);
13
+
14
+ int timeout = 90 * 1000;
15
+ if (args.length > 1) { // a second argument is a timeout
16
+ try {
17
+ // the argument is in seconds but robotium takes milliseconds
18
+ timeout = 1000 * Integer.parseInt(args[1]);
19
+ } catch (NumberFormatException e) {
20
+ return new Result(false, "Invalid timeout supplied. Should be an integer.");
21
+ }
22
+ }
23
+
24
+ boolean timedOut = !InstrumentationBackend.solo.waitForText(args[0], 1, timeout);
14
25
  if(timedOut) {
15
26
  return new Result(false, "Time out while waiting for text:" + args[0]);
16
27
  } else {
17
28
  return Result.successResult();
18
29
  }
19
-
30
+
20
31
  }
21
32
 
22
33
  @Override
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: calabash-android
3
3
  version: !ruby/object:Gem::Version
4
- hash: 5
4
+ hash: 3
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 9
10
- version: 0.2.9
9
+ - 10
10
+ version: 0.2.10
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jonas Maturana Larsen
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-08-09 00:00:00 +02:00
18
+ date: 2012-08-13 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -60,6 +60,20 @@ dependencies:
60
60
  version: "0"
61
61
  type: :runtime
62
62
  version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: retriable
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ type: :runtime
76
+ version_requirements: *id004
63
77
  description: "calabash-android drives tests for native and hybrid Android apps. "
64
78
  email:
65
79
  - jonas@lesspainful.com
@@ -171,10 +185,12 @@ files:
171
185
  - test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/spinner/SelectSpinnerItemByContentDescription.java
172
186
  - test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/AssertText.java
173
187
  - test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/AssertTextOfSpecificTextViewByContentDescription.java
188
+ - test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/ClearTextById.java
174
189
  - test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/ClearTextByIndex.java
175
190
  - test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/ClearTextFieldByContentDescription.java
176
191
  - test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/ClickOnText.java
177
192
  - test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/EnterTextByContentDescription.java
193
+ - test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/EnterTextById.java
178
194
  - test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/EnterTextByIndex.java
179
195
  - test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/time/SetDateByContentDescription.java
180
196
  - test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/time/SetDateByIndex.java
@@ -183,6 +199,7 @@ files:
183
199
  - test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/ClickOnViewById.java
184
200
  - test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/LongPressOnViewById.java
185
201
  - test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/Press.java
202
+ - test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/WaitForView.java
186
203
  - test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/WaitForViewById.java
187
204
  - test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/wait/Wait.java
188
205
  - test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/wait/WaitForDialogClose.java