testautoa 0.4.0 → 0.4.1

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.
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,48 +1,70 @@
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 ExecuteJavascript 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
+ + " var r;"
33
+ + " try {"
34
+ + " r = (function() {"
35
+ + scriptCode + ";"
36
+ + " }());"
37
+ + " } catch (e) {"
38
+ + " r = 'Exception: ' + e;"
39
+ + " }"
40
+ + " prompt('calabash:'+r);"
41
+ + "}())";
14
42
 
15
- List<CalabashChromeClient> list = CalabashChromeClient.findAndPrepareWebViews();
16
- if (list.isEmpty()) {
17
- return new Result(false, "No WebView component found");
18
- }
19
-
20
- CalabashChromeClient ccc = list.get(0);
21
- WebView webView = ccc.getWebView();
22
- String script = "javascript:(function() {"
23
- + " var r;"
24
- + " try {"
25
- + " r = (function() {"
26
- + args[0] + ";"
27
- + " }());"
28
- + " } catch (e) {"
29
- + " r = 'Exception: ' + e;"
30
- + " }"
31
- + " prompt('calabash:'+r);"
32
- + "}())";
33
-
34
- System.out.println("execute javascript: " + script);
35
- webView.loadUrl(script);
36
-
37
- String r = ccc.getResult();
38
- System.out.println("javascript result: " + r);
39
-
40
- boolean success = true;
41
- if (r.startsWith("Exception:")) {
42
- success = false;
43
- }
43
+ System.out.println("execute javascript: " + script);
44
44
 
45
- return new Result(success, r);
45
+ webView.loadUrl(script);
46
+ webResults.add(ccc.getResult());
47
+ return webResults;
48
+
49
+ }
50
+ });
51
+
52
+ List<String> allResults = new ArrayList<String>(webResults.size());
53
+ boolean success = true;
54
+ for (WebFuture f : webResults) {
55
+ String result = f.getAsString();
56
+ allResults.add(result);
57
+ if (result.startsWith("Exception:")) {
58
+ success = false;
59
+ }
60
+ }
61
+
62
+ if (allResults.size() == 0) {
63
+ return new Result(false, "No WebView found");
64
+ }
65
+ else {
66
+ return new Result(success, allResults);
67
+ }
46
68
  }
47
69
 
48
70
  @Override
@@ -0,0 +1,44 @@
1
+ package sh.calaba.instrumentationbackend.actions.webview;
2
+
3
+ import sh.calaba.instrumentationbackend.query.Operation;
4
+
5
+ public class JavaScriptOperation implements Operation {
6
+
7
+ public final String script;
8
+ public final String arg;
9
+
10
+ public JavaScriptOperation(String script, String args) {
11
+ this.script = script;
12
+ this.arg = args;
13
+ }
14
+
15
+ @SuppressWarnings("unchecked")
16
+ @Override
17
+ public Object apply(Object o) {
18
+ throw new UnsupportedOperationException("asd");
19
+ /*
20
+ Map<String, Object> domEl = (Map<String, Object>) o;
21
+
22
+ WebView webView = (WebView) domEl.get("webView");
23
+
24
+ domEl.remove("class");
25
+ domEl.remove("html");
26
+ domEl.remove("webView");
27
+
28
+ String elJson = QueryHelper.toJsonString(domEl);
29
+
30
+
31
+ WebFuture asyncRes = QueryHelper.executeAsyncJavascriptInWebviews(webView, this.script,
32
+ elJson, this.arg);
33
+ return asyncRes.getAsString();
34
+ */
35
+ }
36
+
37
+ @Override
38
+ public String getName() {
39
+ return "JSOp[script="+this.script+"]";
40
+ }
41
+
42
+
43
+
44
+ }
@@ -1,40 +1,65 @@
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 PressByCssSelector implements Action {
12
16
 
13
- @Override
17
+ @SuppressWarnings({ "unchecked", "rawtypes" })
18
+ @Override
14
19
  public Result execute(final String... args) {
15
- for (CalabashChromeClient ccc : CalabashChromeClient.findAndPrepareWebViews()) {
16
- WebView webView = ccc.getWebView();
17
-
18
- webView.loadUrl("javascript:(function() {" +
19
- "var element = document.querySelector(\"" + args[0] + "\");" +
20
- "if (element != null) {" +
21
- " var oEvent = document.createEvent ('MouseEvent');" +
22
- " oEvent.initMouseEvent('click', true, true,window, 1, 1, 1, 1, 1, false, false, false, false, 0, element);" +
23
- " element.dispatchEvent( oEvent );" +
24
- " prompt('calabash:true');" +
25
- "}" +
26
- "prompt('calabash:false');" +
27
- "})()");
28
-
29
- String r = ccc.getResult();
30
- System.out.println("clickOnSelector: " + r);
31
- if ("true".equals(r)) {
32
- TestHelpers.wait(0.3);
33
- return Result.successResult();
34
- }
35
- }
36
-
37
- return new Result(false,"No WebView Found");
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
+ WebView webView = ccc.getWebView();
27
+
28
+ webView.loadUrl("javascript:(function() {" +
29
+ "var element = document.querySelector(\"" + args[0] + "\");" +
30
+ "if (element != null) {" +
31
+ " var oEvent = document.createEvent ('MouseEvent');" +
32
+ " oEvent.initMouseEvent('click', true, true,window, 1, 1, 1, 1, 1, false, false, false, false, 0, element);" +
33
+ " element.dispatchEvent( oEvent );" +
34
+ " prompt('calabash:true');" +
35
+ " return;" +
36
+ "}" +
37
+ "prompt('calabash:false');" +
38
+ "})()");
39
+
40
+ webResults.add(ccc.getResult());
41
+ }
42
+ return webResults;
43
+
44
+ }
45
+ });
46
+
47
+ List<String> allResults = new ArrayList<String>(webResults.size());
48
+ boolean success = false;
49
+ for (WebFuture f : webResults) {
50
+ String result = f.getAsString();
51
+ allResults.add(result);
52
+ if ("true".equals(result)) {
53
+ success = true;
54
+ }
55
+ }
56
+
57
+ if (allResults.size() == 0) {
58
+ return new Result(false, "No WebView found");
59
+ }
60
+ else {
61
+ return new Result(success, allResults);
62
+ }
38
63
  }
39
64
 
40
65
  @Override
@@ -4,36 +4,17 @@ import java.io.BufferedReader;
4
4
  import java.io.IOException;
5
5
  import java.io.InputStream;
6
6
  import java.io.InputStreamReader;
7
- import java.lang.reflect.Field;
8
7
  import java.util.HashMap;
9
8
  import java.util.List;
10
9
  import java.util.Map;
11
- import java.util.concurrent.atomic.AtomicReference;
12
10
 
13
11
  import sh.calaba.instrumentationbackend.InstrumentationBackend;
12
+ import sh.calaba.instrumentationbackend.actions.webview.CalabashChromeClient.WebFuture;
14
13
  import sh.calaba.org.codehaus.jackson.map.ObjectMapper;
15
14
  import android.webkit.WebView;
16
15
 
17
16
  public class QueryHelper {
18
17
 
19
- public static String executeJavascriptInWebview(String scriptPath, String... args) {
20
-
21
- String script = readJavascriptFromAsset(scriptPath);
22
-
23
- for (String arg : args) {
24
- script = script.replaceFirst("%@", arg);
25
- }
26
-
27
- final String myScript = script;
28
- List<CalabashChromeClient> webViews = CalabashChromeClient.findAndPrepareWebViews();
29
-
30
- for (CalabashChromeClient ccc : webViews) {
31
- WebView webView = ccc.getWebView();
32
- webView.loadUrl("javascript:calabash_result = " + myScript + ";prompt('calabash:' + calabash_result);");
33
- return ccc.getResult();
34
- }
35
- throw new RuntimeException("No webviews found");
36
- }
37
18
 
38
19
  @SuppressWarnings("unchecked")
39
20
  public static Map<String, Object> findFirstVisibleRectangle(List<HashMap<String,Object>> elements) {
@@ -45,25 +26,36 @@ public class QueryHelper {
45
26
  return (Map<String, Object>)elements.get(0);
46
27
  }
47
28
 
48
- public static float[] getScreenCoordinatesForCenter(Map<String, Object> rectangle) {
29
+ public static float translateCoordToScreen(int offset, float scale, Object point) {
30
+ return offset + ((Number)point).floatValue() *scale;
31
+ }
32
+
33
+ public static Map<String, Object> translateRectToScreenCoordinates(WebView webView, Map<String, Object> rectangle) {
49
34
  try {
50
35
 
51
- CalabashChromeClient calabashChromeClient = CalabashChromeClient.findAndPrepareWebViews().get(0);
52
-
53
- WebView webView = calabashChromeClient.getWebView();
54
-
55
-
56
36
  float scale = webView.getScale();
57
37
 
58
-
59
- System.out.println("scale: " + scale);
60
38
  int[] webviewLocation = new int[2];
61
39
  webView.getLocationOnScreen(webviewLocation);
40
+ //center_x, center_y
41
+ //left, top, width, height
42
+ float center_x = translateCoordToScreen(webviewLocation[0], scale,
43
+ rectangle.get("center_x"));
44
+ float center_y = translateCoordToScreen(webviewLocation[1], scale,
45
+ rectangle.get("center_y"));
46
+
47
+ float x = translateCoordToScreen(webviewLocation[0], scale, rectangle.get("left"));
48
+ float y = translateCoordToScreen(webviewLocation[0], scale, rectangle.get("top"));
49
+ Map<String,Object> result = new HashMap<String, Object>(rectangle);
62
50
 
63
- //TODO: Exception if center_x or center_y are not numbers
64
- float x = webviewLocation[0] + ((Number)rectangle.get("center_x")).floatValue() * scale;
65
- float y = webviewLocation[1] + ((Number)rectangle.get("center_y")).floatValue() * scale;
66
- return new float[]{x, y};
51
+ result.put("x",x);
52
+ result.put("y",y);
53
+ result.put("center_x",center_x);
54
+ result.put("center_y",center_y);
55
+
56
+ return result;
57
+
58
+
67
59
  } catch (Exception e) {
68
60
  throw new RuntimeException(e);
69
61
  }
@@ -94,4 +86,19 @@ public class QueryHelper {
94
86
  }
95
87
  return script.toString();
96
88
  }
89
+
90
+ public static WebFuture executeAsyncJavascriptInWebviews(WebView webView,
91
+ String scriptPath, String selector, String type) {
92
+
93
+ String script = readJavascriptFromAsset(scriptPath);
94
+
95
+ script = script.replaceFirst("%@", selector);
96
+ script = script.replaceFirst("%@", type);
97
+
98
+ CalabashChromeClient chromeClient = CalabashChromeClient.prepareWebView(webView);
99
+ webView.loadUrl("javascript:calabash_result = " + script + ";prompt('calabash:' + calabash_result);");
100
+ return chromeClient.getResult();
101
+ }
102
+
103
+
97
104
  }
@@ -1,7 +1,6 @@
1
1
  package sh.calaba.instrumentationbackend.actions.webview;
2
2
 
3
3
 
4
- import java.util.HashMap;
5
4
  import java.util.List;
6
5
  import java.util.Map;
7
6
 
@@ -9,60 +8,76 @@ import sh.calaba.instrumentationbackend.InstrumentationBackend;
9
8
  import sh.calaba.instrumentationbackend.Result;
10
9
  import sh.calaba.instrumentationbackend.actions.Action;
11
10
  import sh.calaba.instrumentationbackend.actions.Actions;
12
- import sh.calaba.org.codehaus.jackson.map.ObjectMapper;
13
- import sh.calaba.org.codehaus.jackson.type.TypeReference;
14
11
  import android.test.TouchUtils;
15
12
  import android.webkit.WebView;
16
13
 
17
14
 
18
15
  public class ScrollTo implements Action {
19
-
20
- @Override
16
+
17
+ @Override
21
18
  public Result execute(String... args) {
22
19
  //TODO: Should do horizontal scrolling if needed
23
- String queryResult = QueryHelper.executeJavascriptInWebview("calabash.js", args[1], args[0]);
24
- CalabashChromeClient calabashChromeClient = CalabashChromeClient.findAndPrepareWebViews().get(0);
25
- final WebView webView = calabashChromeClient.getWebView();
26
- webView.scrollTo(0, 0);
27
- QueryHelper.getScreenCoordinatesForCenter(findFirstRect(queryResult));
28
- int scrolledTo = webView.getScrollY();
29
- while (!isVisible(findFirstRect(queryResult), calabashChromeClient)) {
30
- TouchUtils.dragQuarterScreenUp(Actions.parentTestCase, InstrumentationBackend.solo.getCurrentActivity());
31
- if (scrolledTo != webView.getScrollY()) {
32
- scrolledTo = webView.getScrollY();
33
- } else {
34
- return new Result(false, "Tried scrolling but the center of the element never became visible.");
35
- }
36
- }
37
-
38
- return new Result(true, "");
20
+ final String uiQuery = "android.webkit.WebView " + args[0] + ":'"+ args[1] + "'";
21
+
22
+ CalabashChromeClient calabashChromeClient = CalabashChromeClient.findAndPrepareWebViews().get(0);
23
+ WebView webView = calabashChromeClient.getWebView();
24
+
25
+ scrollToTop(webView);
26
+
27
+ while (keepScrolling(uiQuery, webView)) {
28
+ TouchUtils.dragQuarterScreenUp(Actions.parentTestCase, InstrumentationBackend.solo.getCurrentActivity());
29
+ }
30
+
31
+ return new Result(isVisible(uiQuery, webView), "");
39
32
  }
40
33
 
34
+ private void scrollToTop(final WebView webView) {
35
+ InstrumentationBackend.instrumentation.runOnMainSync(new Runnable() {
36
+ @Override
37
+ public void run() {
38
+ webView.scrollTo(0, 0);
39
+ }
40
+ });
41
+ }
41
42
 
43
+ private boolean keepScrolling(String uiQuery, WebView webView) {
44
+ int centerY = getCenterY(uiQuery, webView);
45
+ System.out.println("Keep scrolling centerY: "+ centerY);
42
46
 
43
- private Map<String, Object> findFirstRect(String queryResult) {
44
- try {
45
- List<HashMap<String,Object>> p = new ObjectMapper().readValue(queryResult, new TypeReference<List<HashMap<String,Object>>>(){});
46
-
47
- if (p.isEmpty()) {
48
- throw new RuntimeException("No element found");
49
- }
50
- System.out.println(p);
51
- final Map<String, Object> firstRect = QueryHelper.findFirstVisibleRectangle(p);
52
- return firstRect;
53
- } catch (Exception e) {
54
- throw new RuntimeException(e);
55
- }
47
+ int[] location = new int[2];
48
+ webView.getLocationOnScreen(location);
49
+ int top = location[1];
50
+ int bottom = top + webView.getHeight();
56
51
 
57
- }
52
+ System.out.println("isVisible top: "+ top);
53
+ System.out.println("isVisible bottom: "+ bottom);
54
+
55
+ return centerY > bottom;
56
+ }
57
+
58
+ private boolean isVisible(String uiQuery, WebView webView) {
59
+ int centerY = getCenterY(uiQuery, webView);
60
+ System.out.println("isVisible centerY: "+ centerY);
61
+
62
+ int[] location = new int[2];
63
+ webView.getLocationOnScreen(location);
64
+ int top = location[1];
65
+ int bottom = top + webView.getHeight();
66
+ System.out.println("isVisible top: "+ top);
67
+ System.out.println("isVisible bottom: "+ bottom);
68
+
69
+ return top < centerY && centerY < bottom;
70
+ }
58
71
 
59
- private boolean isVisible(Map<String, Object> rectangle, CalabashChromeClient calabashChromeClient) {
60
- WebView webView = calabashChromeClient.getWebView();
61
- int windowTop = webView.getScrollY();
62
- int windowBottom = webView.getScrollY() + webView.getHeight();
63
- int centerY = (int) ((Integer)rectangle.get("center_y") * webView.getScale());
72
+ @SuppressWarnings({ "rawtypes", "unchecked" })
73
+ private int getCenterY(String uiQuery, WebView webView) {
74
+ List queryResult = new sh.calaba.instrumentationbackend.query.Query(uiQuery).executeQuery();
75
+ if (queryResult.isEmpty()) {
76
+ throw new RuntimeException("Query found no elements");
77
+ }
78
+ final Map<String, Object> firstVisibleRectangle = QueryHelper.findFirstVisibleRectangle(queryResult);
64
79
 
65
- return windowTop < centerY && centerY < windowBottom;
80
+ return Math.round((Float)firstVisibleRectangle.get("center_y"));
66
81
  }
67
82
 
68
83
  @Override
@@ -1,42 +1,67 @@
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
 
11
15
  public class SetPropertyByCssSelector implements Action {
12
16
 
13
- @Override
17
+ @SuppressWarnings({ "unchecked", "rawtypes" })
18
+ @Override
14
19
  public Result execute(String... args) {
15
- String cssSelector = args[0];
16
- String propertyName = args[1];
17
- String value = args[2];
18
-
19
- for (CalabashChromeClient ccc : CalabashChromeClient.findAndPrepareWebViews()) {
20
- WebView webView = ccc.getWebView();
20
+ final String cssSelector = args[0];
21
+ final String propertyName = args[1];
22
+ final String value = args[2];
23
+
24
+ List<WebFuture> webResults = (List<WebFuture>) UIQueryUtils.evaluateSyncInMainThread(new Callable() {
21
25
 
22
- final String assignment = "document.querySelector(\"" + cssSelector + "\")." + propertyName + " = " + value + ";";
23
- System.out.println(assignment);
24
- webView.loadUrl("javascript:(function() {" +
25
- assignment +
26
- "prompt('calabash:true');" +
27
- "})()");
28
- String r = ccc.getResult();
29
- System.out.println("setPropertyByCssSelector: " + r);
30
- if ("true".equals(r)) {
31
- TestHelpers.wait(0.3);
32
- return Result.successResult();
33
- }
34
- }
26
+ public Object call() throws Exception {
27
+
28
+ List<WebFuture> webResults = new ArrayList();
29
+ for (CalabashChromeClient ccc : CalabashChromeClient.findAndPrepareWebViews()) {
30
+ WebView webView = ccc.getWebView();
31
+
32
+ final String assignment = "document.querySelector(\"" + cssSelector + "\")." + propertyName + " = " + value + ";";
33
+ System.out.println(assignment);
34
+ webView.loadUrl("javascript:(function() {" +
35
+ assignment +
36
+ "prompt('calabash:true');" +
37
+ "})()");
38
+ webResults.add(ccc.getResult());
39
+ }
35
40
 
36
- return new Result(false,"No WebView found");
37
- }
41
+ return webResults;
42
+
43
+ }
44
+ });
45
+
46
+ List<String> allResults = new ArrayList<String>(webResults.size());
47
+ boolean success = false;
48
+ for (WebFuture f : webResults) {
49
+ String result = f.getAsString();
50
+ allResults.add(result);
51
+ if ("true".equals(result)) {
52
+ success = true;
53
+ }
54
+ }
55
+
56
+ if (allResults.size() == 0) {
57
+ return new Result(false, "No WebView found");
58
+ }
59
+ else {
60
+ return new Result(success, allResults);
61
+ }
62
+ }
38
63
 
39
- @Override
64
+ @Override
40
65
  public String key() {
41
66
  return "set_property_by_css_selector";
42
67
  }
@@ -1,14 +1,12 @@
1
1
  package sh.calaba.instrumentationbackend.actions.webview;
2
2
 
3
3
 
4
- import java.util.HashMap;
5
4
  import java.util.List;
6
5
  import java.util.Map;
7
6
 
8
7
  import sh.calaba.instrumentationbackend.Result;
9
8
  import sh.calaba.instrumentationbackend.actions.Action;
10
- import sh.calaba.org.codehaus.jackson.map.ObjectMapper;
11
- import sh.calaba.org.codehaus.jackson.type.TypeReference;
9
+ import sh.calaba.instrumentationbackend.actions.webview.CalabashChromeClient.WebFuture;
12
10
 
13
11
 
14
12
  public class SetText implements Action {
@@ -18,26 +16,25 @@ public class SetText implements Action {
18
16
  * args[1]: xpath or css selector
19
17
  * args[2]: text to enter into the first selected element
20
18
  */
21
- @Override
22
- public Result execute(String... args) {
23
- try {
24
- String queryResult = QueryHelper.executeJavascriptInWebview("calabash.js", args[1], args[0]);
25
- List<HashMap<String,Object>> p = new ObjectMapper().readValue(queryResult, new TypeReference<List<HashMap<String,Object>>>(){});
26
-
27
- if (p.isEmpty()) {
28
- throw new RuntimeException("No element found");
29
- }
30
- Map<String, Object> firstElement = QueryHelper.findFirstVisibleElement(p);
31
- //TODO: Hack! Should be serialized instead of removed
32
- firstElement.remove("class");
33
- firstElement.remove("html");
34
- String firstElementJson = QueryHelper.toJsonString(firstElement);
35
-
36
- String result = QueryHelper.executeJavascriptInWebview("set_text.js", firstElementJson, args[2]);
37
- return new Result(true, result);
38
- } catch (Exception e) {
39
- throw new RuntimeException(e);
19
+ @SuppressWarnings({ "rawtypes", "unchecked"})
20
+ @Override
21
+ public Result execute(final String... args) {
22
+ final String uiQuery = "android.webkit.WebView " + args[0] + ":'"+ args[1] + "'";
23
+ List queryResult = new sh.calaba.instrumentationbackend.query.Query(uiQuery).executeQuery();
24
+ if (queryResult.isEmpty()) {
25
+ throw new RuntimeException("No element found");
40
26
  }
27
+ Map<String, Object> firstElement = QueryHelper.findFirstVisibleElement(queryResult);
28
+ //TODO: Hack! Should be serialized instead of removed
29
+ CalabashChromeClient client = CalabashChromeClient.findAndPrepareWebViews().get(0);
30
+ firstElement.remove("class");
31
+ firstElement.remove("webView");
32
+ firstElement.remove("html");
33
+ String firstElementJson = QueryHelper.toJsonString(firstElement);
34
+
35
+ WebFuture result = QueryHelper.executeAsyncJavascriptInWebviews(client.getWebView(),"set_text.js", firstElementJson, args[2]);
36
+
37
+ return new Result(true,result.getAsString());
41
38
  }
42
39
 
43
40
  @Override
@@ -0,0 +1,40 @@
1
+ package sh.calaba.instrumentationbackend.query;
2
+
3
+ import java.util.concurrent.ExecutionException;
4
+ import java.util.concurrent.Future;
5
+ import java.util.concurrent.TimeUnit;
6
+ import java.util.concurrent.TimeoutException;
7
+
8
+ public class CompletedFuture<T> implements Future<T> {
9
+ private final T result;
10
+
11
+ public CompletedFuture(final T result) {
12
+ this.result = result;
13
+ }
14
+
15
+ @Override
16
+ public boolean cancel(final boolean b) {
17
+ return false;
18
+ }
19
+
20
+ @Override
21
+ public boolean isCancelled() {
22
+ return false;
23
+ }
24
+
25
+ @Override
26
+ public boolean isDone() {
27
+ return true;
28
+ }
29
+
30
+ @Override
31
+ public T get() throws InterruptedException, ExecutionException {
32
+ return this.result;
33
+ }
34
+
35
+ @Override
36
+ public T get(long timeout, TimeUnit unit) throws InterruptedException,
37
+ ExecutionException, TimeoutException {
38
+ return get();
39
+ }
40
+ }