testautoa 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. data/Rakefile +7 -7
  2. data/bin/calabash-android +8 -1
  3. data/bin/calabash-android-build.rb +1 -1
  4. data/bin/calabash-android-console.rb +4 -4
  5. data/bin/calabash-android-run.rb +2 -10
  6. data/bin/testautoa +461 -0
  7. data/calabash-android.gemspec +3 -1
  8. data/features-skeleton/support/app_life_cycle_hooks.rb +0 -1
  9. data/irbrc +3 -1
  10. data/lib/calabash-android/helpers.rb +45 -17
  11. data/lib/calabash-android/lib/TestServer.apk +0 -0
  12. data/lib/calabash-android/lib/unsign.jar +0 -0
  13. data/lib/calabash-android/operations.rb +150 -66
  14. data/lib/calabash-android/steps/list_steps.rb +1 -1
  15. data/lib/calabash-android/steps/time_picker_steps.rb +1 -1
  16. data/lib/calabash-android/touch_helpers.rb +9 -0
  17. data/lib/calabash-android/version.rb +1 -1
  18. data/lib/calabash-android/wait_helpers.rb +93 -0
  19. data/test-server/AndroidManifest.xml +2 -0
  20. data/test-server/build.xml +1 -0
  21. data/test-server/instrumentation-backend/.classpath +0 -1
  22. data/test-server/instrumentation-backend/AndroidManifest.xml +1 -1
  23. data/test-server/instrumentation-backend/antlr/UIQuery.g +48 -5
  24. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/Command.java +4 -3
  25. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/FranklyResult.java +95 -0
  26. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/Result.java +7 -1
  27. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/HttpServer.java +14 -29
  28. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/activity/FinishOpenedActivities.java +19 -0
  29. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/activity/GetOpenedActivities.java +31 -0
  30. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/activity/GoBackToActivity.java +67 -0
  31. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/gestures/DragCoordinates.java +28 -0
  32. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/gestures/Swipe.java +11 -5
  33. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/location/FakeGPSLocation.java +13 -10
  34. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/softkey/LeftKey.java +24 -0
  35. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/softkey/RightKey.java +24 -0
  36. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/softkey/UpKey.java +24 -0
  37. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/version/Version.java +31 -0
  38. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/CalabashChromeClient.java +131 -36
  39. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/DumpBodyHtml.java +38 -18
  40. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/DumpHtml.java +38 -16
  41. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/EnterTextByCssSelector.java +94 -66
  42. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/ExecuteAsyncJavascript.java +55 -33
  43. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/ExecuteJavascript.java +53 -31
  44. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/JavaScriptOperation.java +44 -0
  45. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/PressByCssSelector.java +52 -27
  46. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/QueryHelper.java +39 -32
  47. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/ScrollTo.java +56 -41
  48. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/SetPropertyByCssSelector.java +50 -25
  49. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/SetText.java +19 -22
  50. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/CompletedFuture.java +40 -0
  51. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/InvocationOperation.java +222 -0
  52. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/Operation.java +7 -0
  53. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/PropertyOperation.java +56 -0
  54. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/Query.java +151 -43
  55. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/UIQuery.tokens +19 -12
  56. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/UIQueryResultVoid.java +22 -0
  57. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ViewMapper.java +41 -11
  58. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/antlr/UIQueryLexer.java +1010 -242
  59. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/antlr/UIQueryParser.java +406 -98
  60. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/BeginsWithRelation.java +45 -0
  61. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/ComparisonOperator.java +54 -0
  62. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/ContainsRelation.java +41 -0
  63. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/EndsWithRelation.java +42 -0
  64. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/LikeRelation.java +79 -0
  65. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/PartialFutureList.java +100 -0
  66. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryAST.java +1 -1
  67. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryASTClassName.java +54 -25
  68. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryASTPredicate.java +147 -0
  69. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryASTPredicateRelation.java +5 -0
  70. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryASTWith.java +153 -89
  71. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryDirection.java +12 -2
  72. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryEvaluator.java +58 -141
  73. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryUtils.java +162 -7
  74. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryVisibility.java +32 -0
  75. metadata +130 -97
  76. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/Query.java +0 -24
  77. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/Touch.java +0 -44
  78. data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/antlr/UIQuery.tokens +0 -10
  79. data/test-server/instrumentation-backend/tests/sh/calaba/instrumentationbackend/query/tests/UIQueryTest.java +0 -134
@@ -1,11 +1,16 @@
1
1
  package sh.calaba.instrumentationbackend.actions.webview;
2
2
 
3
- import java.lang.reflect.Field;
4
3
  import java.lang.reflect.Method;
5
4
  import java.util.ArrayList;
5
+ import java.util.HashMap;
6
6
  import java.util.List;
7
- import java.util.concurrent.atomic.AtomicReference;
7
+ import java.util.Map;
8
+ import java.util.concurrent.ExecutionException;
9
+ import java.util.concurrent.Future;
10
+ import java.util.concurrent.TimeUnit;
11
+ import java.util.concurrent.TimeoutException;
8
12
 
13
+ import android.os.Looper;
9
14
  import sh.calaba.instrumentationbackend.InstrumentationBackend;
10
15
  import android.os.Build;
11
16
  import android.os.ConditionVariable;
@@ -14,72 +19,162 @@ import android.webkit.JsPromptResult;
14
19
  import android.webkit.WebChromeClient;
15
20
  import android.webkit.WebView;
16
21
 
17
-
18
22
  public class CalabashChromeClient extends WebChromeClient {
19
- private final ConditionVariable eventHandled = new ConditionVariable();
20
- private final Result result = new Result();
21
23
  private WebChromeClient mWebChromeClient;
22
24
  private final WebView webView;
25
+ private final WebFuture scriptFuture;
23
26
 
24
- public CalabashChromeClient(WebView webView) {
27
+ public CalabashChromeClient(final WebView webView) {
25
28
  this.webView = webView;
26
- if (Build.VERSION.SDK_INT < 16) { // jelly bean
27
- try {
28
- Method methodGetConfiguration = webView.getClass().getMethod("getWebChromeClient");
29
- mWebChromeClient = (WebChromeClient)methodGetConfiguration.invoke(webView);
30
- } catch(Exception e) {
31
- throw new RuntimeException(e);
32
- }
29
+ this.scriptFuture = new WebFuture(webView);
30
+ if (Build.VERSION.SDK_INT < 16) { // jelly bean
31
+ try {
32
+ Method methodGetConfiguration = webView.getClass().getMethod(
33
+ "getWebChromeClient");
34
+ mWebChromeClient = (WebChromeClient) methodGetConfiguration
35
+ .invoke(webView);
36
+ } catch (Exception e) {
37
+ throw new RuntimeException(e);
38
+ }
33
39
  }
34
- webView.setWebChromeClient(this);
40
+
41
+ if ( Looper.getMainLooper().getThread() == Thread.currentThread()) {
42
+ webView.setWebChromeClient(this);
43
+ } else {
44
+ InstrumentationBackend.instrumentation.runOnMainSync(new Runnable() {
45
+ @Override
46
+ public void run() {
47
+ webView.setWebChromeClient(CalabashChromeClient.this);
48
+ }
49
+ });
50
+ }
35
51
  }
36
52
 
37
53
  @Override
38
- public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult r) {
54
+ public boolean onJsPrompt(WebView view, String url, String message,
55
+ String defaultValue, JsPromptResult r) {
39
56
  if (message != null && message.startsWith("calabash:")) {
40
57
  r.confirm("CALABASH_ACK");
41
58
  System.out.println("onJsPrompt: " + message);
42
- result.message = message.replaceFirst("calabash:", "");
43
- eventHandled.open();
44
-
59
+ String jsonResponse = message.replaceFirst("calabash:", "");
60
+ scriptFuture.setResult(jsonResponse);
45
61
  return true;
46
62
  } else {
47
63
  if (mWebChromeClient == null) {
48
64
  r.confirm("CALABASH_ERROR");
65
+ scriptFuture.complete();
49
66
  return true;
50
67
  } else {
51
- return mWebChromeClient.onJsPrompt(view, url, message, defaultValue, r);
68
+ // TODO I'm not what this case does...
69
+ return mWebChromeClient.onJsPrompt(view, url, message,
70
+ defaultValue, r);
52
71
  }
53
72
  }
54
73
  }
55
74
 
56
- public WebView getWebView() {
57
- return webView;
58
- }
59
-
60
- public String getResult() {
61
- eventHandled.block(3000);
62
- if (result.message == null) {
63
- throw new RuntimeException("Timed out waiting for result for JavaScript");
64
- }
65
- return result.message;
75
+ public WebView getWebView() {
76
+ return webView;
66
77
  }
67
78
 
68
- private class Result {
69
- String message;
79
+ public static CalabashChromeClient prepareWebView(WebView webView) {
80
+ CalabashChromeClient calabashChromeClient = new CalabashChromeClient(
81
+ webView);
82
+ webView.getSettings().setJavaScriptEnabled(true);
83
+ return calabashChromeClient;
70
84
  }
71
85
 
72
86
  public static List<CalabashChromeClient> findAndPrepareWebViews() {
73
87
  List<CalabashChromeClient> webViews = new ArrayList<CalabashChromeClient>();
74
88
  ArrayList<View> views = InstrumentationBackend.solo.getCurrentViews();
75
89
  for (View view : views) {
76
- if ( view instanceof WebView) {
77
- WebView webView = (WebView)view;
78
- webViews.add(new CalabashChromeClient(webView));
79
- webView.getSettings().setJavaScriptEnabled(true);
80
- System.out.println("Setting CalabashChromeClient");
90
+ if (view instanceof WebView) {
91
+ WebView webView = (WebView) view;
92
+ webViews.add(prepareWebView(webView));
81
93
  }
82
94
  }
83
95
  return webViews;
96
+
97
+ }
98
+
99
+ public WebFuture getResult() {
100
+ return scriptFuture;
101
+ }
102
+
103
+ @SuppressWarnings("rawtypes")
104
+ public static class WebFuture implements Future {
105
+ private final ConditionVariable eventHandled;
106
+ private volatile boolean complete;
107
+ private String result;
108
+ private final WebView webView;
109
+
110
+ public WebView getWebView() {
111
+ return webView;
112
+ }
113
+
114
+ public void complete() {
115
+ this.complete = true;
116
+ this.eventHandled.open();
117
+ }
118
+
119
+ public WebFuture(WebView webView) {
120
+ this.webView = webView;
121
+ eventHandled = new ConditionVariable();
122
+ result = null;
123
+ }
124
+
125
+ public synchronized void setResult(String result) {
126
+ this.result = result;
127
+ this.complete();
128
+ }
129
+
130
+ public synchronized String getResult() {
131
+ return this.result;
132
+ }
133
+
134
+ public boolean cancel(boolean mayInterruptIfRunning) {
135
+ return false;
136
+ }
137
+
138
+ @Override
139
+ public Object get() throws InterruptedException, ExecutionException {
140
+ eventHandled.block();
141
+ return asMap();
142
+ }
143
+
144
+ @Override
145
+ public Object get(long timeout, TimeUnit unit)
146
+ throws InterruptedException, ExecutionException,
147
+ TimeoutException {
148
+ eventHandled.block(unit.convert(timeout, TimeUnit.MILLISECONDS));
149
+ return asMap();
150
+ }
151
+
152
+ @Override
153
+ public boolean isCancelled() {
154
+ return false;
155
+ }
156
+
157
+ @Override
158
+ public boolean isDone() {
159
+ return complete;
160
+ }
161
+
162
+ public String getAsString() {
163
+ try {
164
+ get(10,TimeUnit.SECONDS);
165
+ return getResult();
166
+ } catch (Exception e) {
167
+ e.printStackTrace();
168
+ throw new RuntimeException(e);
169
+ }
170
+ }
171
+
172
+ @SuppressWarnings("unchecked")
173
+ public Map asMap() {
174
+ HashMap m = new HashMap();
175
+ m.put("webView", webView);
176
+ m.put("result",getResult());
177
+ return m;
178
+ }
84
179
  }
85
180
  }
@@ -1,31 +1,51 @@
1
1
  package sh.calaba.instrumentationbackend.actions.webview;
2
2
 
3
3
 
4
- import sh.calaba.instrumentationbackend.InstrumentationBackend;
4
+ import java.util.ArrayList;
5
+ import java.util.List;
6
+ import java.util.concurrent.Callable;
7
+
5
8
  import sh.calaba.instrumentationbackend.Result;
6
9
  import sh.calaba.instrumentationbackend.actions.Action;
10
+ import sh.calaba.instrumentationbackend.actions.webview.CalabashChromeClient.WebFuture;
11
+ import sh.calaba.instrumentationbackend.query.ast.UIQueryUtils;
7
12
  import android.webkit.WebView;
8
13
 
14
+ @Deprecated
9
15
  public class DumpBodyHtml implements Action {
10
16
 
11
- @Override
17
+ @SuppressWarnings({ "rawtypes", "unchecked" })
18
+ @Override
12
19
  public Result execute(String... args) {
13
-
14
- final Result result = Result.successResult();
15
- for (CalabashChromeClient ccc : CalabashChromeClient.findAndPrepareWebViews()) {
16
- WebView webView = ccc.getWebView();
17
- webView.loadUrl("javascript:(function() {" +
18
- "prompt('calabash:' + document.body.innerHTML);" +
19
- "})()");
20
- String r = ccc.getResult();
21
- System.out.println("Html:");
22
- System.out.println("" + r);
23
- result.addBonusInformation(r);
24
-
25
- return result;
26
-
27
- }
28
- return new Result(false, "No WebView found");
20
+
21
+ List<WebFuture> webResults = (List<WebFuture>) UIQueryUtils.evaluateSyncInMainThread(new Callable() {
22
+ public Object call() throws Exception {
23
+
24
+ List<WebFuture> webResults = new ArrayList();
25
+ for (CalabashChromeClient ccc : CalabashChromeClient.findAndPrepareWebViews()) {
26
+ WebView webView = ccc.getWebView();
27
+ webView.loadUrl("javascript:(function() {" +
28
+ "prompt('calabash:' + document.body.innerHTML);" +
29
+ "})()");
30
+ webResults.add(ccc.getResult());
31
+ }
32
+ return webResults;
33
+
34
+ }
35
+ });
36
+
37
+ List<String> allResults = new ArrayList<String>(webResults.size());
38
+ for (WebFuture f : webResults) {
39
+ allResults.add(f.getAsString());
40
+ }
41
+
42
+ if (allResults.size() == 0) {
43
+ return new Result(false, "No WebView found");
44
+ }
45
+ else {
46
+ return new Result(true, allResults);
47
+ }
48
+
29
49
  }
30
50
  public String key() {
31
51
  return "dump_body_html";
@@ -1,32 +1,54 @@
1
1
  package sh.calaba.instrumentationbackend.actions.webview;
2
2
 
3
3
 
4
- import sh.calaba.instrumentationbackend.InstrumentationBackend;
4
+ import java.util.ArrayList;
5
+ import java.util.List;
6
+ import java.util.concurrent.Callable;
7
+
5
8
  import sh.calaba.instrumentationbackend.Result;
6
9
  import sh.calaba.instrumentationbackend.actions.Action;
10
+ import sh.calaba.instrumentationbackend.actions.webview.CalabashChromeClient.WebFuture;
11
+ import sh.calaba.instrumentationbackend.query.ast.UIQueryUtils;
7
12
  import android.webkit.WebView;
8
13
 
9
14
  public class DumpHtml implements Action {
10
15
 
11
- @Override
16
+ @SuppressWarnings({ "unchecked", "rawtypes" })
17
+ @Override
12
18
  public Result execute(String... args) {
13
-
14
- Result result = Result.successResult();
15
- for (CalabashChromeClient ccc : CalabashChromeClient.findAndPrepareWebViews()) {
16
- final WebView webView = ccc.getWebView();
17
- webView.loadUrl("javascript:(function() {" +
18
- "prompt('calabash:' + document.body.parentNode.innerHTML);" +
19
- "})()");
20
- String r = ccc.getResult();
21
- System.out.println("Html:");
22
- System.out.println("" + r);
23
- result.addBonusInformation(r);
24
- }
19
+
20
+ List<WebFuture> webResults = (List<WebFuture>) UIQueryUtils.evaluateSyncInMainThread(new Callable() {
21
+
22
+ public Object call() throws Exception {
23
+
24
+ List<WebFuture> webResults = new ArrayList();
25
+ for (CalabashChromeClient ccc : CalabashChromeClient.findAndPrepareWebViews()) {
26
+ final WebView webView = ccc.getWebView();
27
+ webView.loadUrl("javascript:(function() {" +
28
+ "prompt('calabash:' + document.body.parentNode.innerHTML);" +
29
+ "})()");
30
+ webResults.add(ccc.getResult());
31
+ }
32
+ return webResults;
33
+
34
+ }
35
+ });
36
+
37
+ List<String> allResults = new ArrayList<String>(webResults.size());
38
+ for (WebFuture f : webResults) {
39
+ allResults.add(f.getAsString());
40
+ }
41
+
42
+ if (allResults.size() == 0) {
43
+ return new Result(false, "No WebView found");
44
+ }
45
+ else {
46
+ return new Result(true, allResults);
47
+ }
25
48
 
26
- return result;
27
49
  }
28
50
 
29
- @Override
51
+ @Override
30
52
  public String key() {
31
53
  return "dump_html";
32
54
  }
@@ -1,88 +1,116 @@
1
1
  package sh.calaba.instrumentationbackend.actions.webview;
2
2
 
3
3
 
4
- import sh.calaba.instrumentationbackend.InstrumentationBackend;
4
+ import java.util.ArrayList;
5
+ import java.util.List;
6
+ import java.util.concurrent.Callable;
7
+
5
8
  import sh.calaba.instrumentationbackend.Result;
6
- import sh.calaba.instrumentationbackend.TestHelpers;
7
9
  import sh.calaba.instrumentationbackend.actions.Action;
10
+ import sh.calaba.instrumentationbackend.actions.webview.CalabashChromeClient.WebFuture;
11
+ import sh.calaba.instrumentationbackend.query.ast.UIQueryUtils;
8
12
  import android.webkit.WebView;
9
13
 
10
-
14
+ @Deprecated
11
15
  public class EnterTextByCssSelector implements Action {
12
16
 
13
- @Override
17
+ @SuppressWarnings({ "unchecked", "rawtypes" })
18
+ @Override
14
19
  public Result execute(String... args) {
15
20
  final String cssSelector = args[0];
16
21
  final String value = args[1];
22
+
23
+ List<WebFuture> webResults = (List<WebFuture>) UIQueryUtils.evaluateSyncInMainThread(new Callable() {
24
+
25
+ public Object call() throws Exception {
26
+
27
+ List<WebFuture> webResults = new ArrayList();
28
+ for (CalabashChromeClient ccc : CalabashChromeClient.findAndPrepareWebViews()) {
29
+ WebView webView = ccc.getWebView();
17
30
 
18
- for (CalabashChromeClient ccc : CalabashChromeClient.findAndPrepareWebViews()) {
19
- WebView webView = ccc.getWebView();
20
-
21
- String functions = " function simulateKeyEvent(elem, character) {\n" +
22
- " var ch = character.charCodeAt(0);\n" +
23
- "\n" +
24
- " var evt;\n" +
25
- "\n" +
26
- " evt = document.createEvent('KeyboardEvent');\n" +
27
- " evt.initKeyboardEvent('keydown', true, true, window, 0, 0, 0, 0, 0, ch);\n" +
28
- " elem.dispatchEvent(evt);\n" +
29
- "\n" +
30
- " evt = document.createEvent('KeyboardEvent');\n" +
31
- " evt.initKeyboardEvent('keyup', true, true, window, 0, 0, 0, 0, 0, ch);\n" +
32
- " elem.dispatchEvent(evt);\n" +
33
- "\n" +
34
- " evt = document.createEvent('KeyboardEvent');\n" +
35
- " evt.initKeyboardEvent('keypress', true, true, window, 0, 0, 0, 0, 0, ch);\n" +
36
- " elem.dispatchEvent(evt);\n" +
37
- " }\n" +
38
- "";
31
+ String functions = " function simulateKeyEvent(elem, character) {\n" +
32
+ " var ch = character.charCodeAt(0);\n" +
33
+ "\n" +
34
+ " var evt;\n" +
35
+ "\n" +
36
+ " evt = document.createEvent('KeyboardEvent');\n" +
37
+ " evt.initKeyboardEvent('keydown', true, true, window, 0, 0, 0, 0, 0, ch);\n" +
38
+ " elem.dispatchEvent(evt);\n" +
39
+ "\n" +
40
+ " evt = document.createEvent('KeyboardEvent');\n" +
41
+ " evt.initKeyboardEvent('keyup', true, true, window, 0, 0, 0, 0, 0, ch);\n" +
42
+ " elem.dispatchEvent(evt);\n" +
43
+ "\n" +
44
+ " evt = document.createEvent('KeyboardEvent');\n" +
45
+ " evt.initKeyboardEvent('keypress', true, true, window, 0, 0, 0, 0, 0, ch);\n" +
46
+ " elem.dispatchEvent(evt);\n" +
47
+ " }\n" +
48
+ "";
39
49
 
40
- functions +=
41
- " function enterTextIntoInputField(elem, text) {\n" +
42
- " for (var i = 0; i < text.length; i++) {\n" +
43
- " var ch = text.charAt(i);\n" +
44
- " elem.value += ch;\n" +
45
- " simulateKeyEvent(elem, ch);\n" +
46
- " }\n" +
47
- " }\n" +
48
- "";
50
+ functions +=
51
+ " function enterTextIntoInputField(elem, text) {\n" +
52
+ " for (var i = 0; i < text.length; i++) {\n" +
53
+ " var ch = text.charAt(i);\n" +
54
+ " elem.value += ch;\n" +
55
+ " simulateKeyEvent(elem, ch);\n" +
56
+ " }\n" +
57
+ " }\n" +
58
+ "";
49
59
 
50
- functions +=
51
- " function fireHTMLEvent(elem, eventName) {\n" +
52
- " var evt = document.createEvent(\"HTMLEvents\");\n" +
53
- " evt.initEvent(eventName, true, true );\n" +
54
- " return !elem.dispatchEvent(evt);\n" +
55
- " }\n" +
56
- "";
60
+ functions +=
61
+ " function fireHTMLEvent(elem, eventName) {\n" +
62
+ " var evt = document.createEvent(\"HTMLEvents\");\n" +
63
+ " evt.initEvent(eventName, true, true );\n" +
64
+ " return !elem.dispatchEvent(evt);\n" +
65
+ " }\n" +
66
+ "";
57
67
 
58
- functions +=
59
- " function selectInputField(elem) {\n" +
60
- " elem.click();\n" +
61
- " elem.focus();\n" +
62
- " }\n" +
63
- "";
68
+ functions +=
69
+ " function selectInputField(elem) {\n" +
70
+ " elem.click();\n" +
71
+ " elem.focus();\n" +
72
+ " }\n" +
73
+ "";
64
74
 
65
- functions +=
66
- " function deselectInputField(elem) {\n" +
67
- " fireHTMLEvent(elem, 'change');\n" +
68
- " fireHTMLEvent(elem, 'blur');\n" +
69
- " }\n" +
70
- "";
75
+ functions +=
76
+ " function deselectInputField(elem) {\n" +
77
+ " fireHTMLEvent(elem, 'change');\n" +
78
+ " fireHTMLEvent(elem, 'blur');\n" +
79
+ " }\n" +
80
+ "";
71
81
 
72
- webView.loadUrl("javascript:(function() {" +
73
- functions +
74
- "var elem = document.querySelector(\"" + cssSelector + "\"); selectInputField(elem); enterTextIntoInputField(elem, '" + value + "'); deselectInputField(elem); " +
75
- "prompt('calabash:true');" +
76
- "})()");
82
+ webView.loadUrl("javascript:(function() {" +
83
+ functions +
84
+ "var elem = document.querySelector(\"" + cssSelector + "\"); selectInputField(elem); enterTextIntoInputField(elem, '" + value + "'); deselectInputField(elem); " +
85
+ "prompt('calabash:true');" +
86
+ "})()");
87
+
88
+ webResults.add(ccc.getResult());
89
+ }
90
+
91
+ return webResults;
92
+
93
+ }
94
+ });
95
+
96
+ List<String> allResults = new ArrayList<String>(webResults.size());
97
+ boolean allSucceed = true;
98
+ for (WebFuture f : webResults) {
99
+ String result = f.getAsString();
100
+ allResults.add(result);
101
+ if (!"true".equals(result)) {
102
+ allSucceed = false;
103
+ }
104
+ }
77
105
 
78
- String r = ccc.getResult();
79
- System.out.println("enterTextIntoInputField: " + r);
80
- if ("true".equals(r)) {
81
- TestHelpers.wait(0.3);
82
- return Result.successResult();
83
- }
84
- }
85
- return new Result(false, "");
106
+
107
+ if (allResults.size() == 0) {
108
+ return new Result(false, "No WebView found");
109
+ }
110
+ else {
111
+ return new Result(allSucceed, allResults);
112
+ }
113
+
86
114
  }
87
115
 
88
116
  @Override
@@ -1,50 +1,72 @@
1
1
  package sh.calaba.instrumentationbackend.actions.webview;
2
2
 
3
+ import java.util.ArrayList;
3
4
  import java.util.List;
5
+ import java.util.concurrent.Callable;
4
6
 
5
- import sh.calaba.instrumentationbackend.InstrumentationBackend;
6
7
  import sh.calaba.instrumentationbackend.Result;
7
8
  import sh.calaba.instrumentationbackend.actions.Action;
9
+ import sh.calaba.instrumentationbackend.actions.webview.CalabashChromeClient.WebFuture;
10
+ import sh.calaba.instrumentationbackend.query.ast.UIQueryUtils;
8
11
  import android.webkit.WebView;
9
12
 
10
13
  public class ExecuteAsyncJavascript implements Action {
11
14
 
15
+ @SuppressWarnings({ "unchecked", "rawtypes" })
12
16
  @Override
13
17
  public Result execute(String... args) {
18
+ final String scriptCode = args[0];
19
+ List<WebFuture> webResults = (List<WebFuture>) UIQueryUtils.evaluateSyncInMainThread(new Callable() {
20
+
21
+ public Object call() throws Exception {
22
+
23
+ List<WebFuture> webResults = new ArrayList();
24
+ List<CalabashChromeClient> list = CalabashChromeClient.findAndPrepareWebViews();
25
+ if (list.isEmpty()) {
26
+ return webResults;
27
+ }
28
+
29
+ CalabashChromeClient ccc = list.get(0);
30
+ WebView webView = ccc.getWebView();
31
+ final String script = "javascript:(function() {"
32
+ + " function cb(ret) {"
33
+ + " prompt('calabash:'+ret);"
34
+ + " }"
35
+ + " try {"
36
+ + " (function(returnValue) {"
37
+ + scriptCode + ";"
38
+ + " }(cb));"
39
+ + " } catch (e) {"
40
+ + " prompt('calabash:Exception: ' + e);"
41
+ + " }"
42
+ + "}())";
14
43
 
15
- List<CalabashChromeClient> list = CalabashChromeClient.findAndPrepareWebViews();
16
- if (list.isEmpty()) {
17
- return new Result(false, "No WebView component found");
18
- }
44
+ System.out.println("execute javascript: " + script);
45
+
46
+ webView.loadUrl(script);
47
+ webResults.add(ccc.getResult());
48
+ return webResults;
49
+
50
+ }
51
+ });
52
+
53
+ List<String> allResults = new ArrayList<String>(webResults.size());
54
+ boolean success = true;
55
+ for (WebFuture f : webResults) {
56
+ String result = f.getAsString();
57
+ allResults.add(result);
58
+ if (result.startsWith("Exception:")) {
59
+ success = false;
60
+ }
61
+ }
62
+
63
+ if (allResults.size() == 0) {
64
+ return new Result(false, "No WebView found");
65
+ }
66
+ else {
67
+ return new Result(success, allResults);
68
+ }
19
69
 
20
- CalabashChromeClient ccc = list.get(0);
21
- WebView webView = ccc.getWebView();
22
- final String script = "javascript:(function() {"
23
- + " function cb(ret) {"
24
- + " prompt('calabash:'+ret);"
25
- + " }"
26
- + " try {"
27
- + " (function(returnValue) {"
28
- + args[0] + ";"
29
- + " }(cb));"
30
- + " } catch (e) {"
31
- + " prompt('calabash:Exception: ' + e);"
32
- + " }"
33
- + "}())";
34
-
35
- System.out.println("execute javascript: " + script);
36
-
37
- webView.loadUrl(script);
38
-
39
- String r = ccc.getResult();
40
- System.out.println("javascript result: " + r);
41
-
42
- boolean success = true;
43
- if (r.startsWith("Exception:")) {
44
- success = false;
45
- }
46
-
47
- return new Result(success, r);
48
70
  }
49
71
 
50
72
  @Override