calabash-android 0.2.9 → 0.2.10

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.
@@ -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