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.
- data/Rakefile +7 -7
- data/bin/calabash-android +8 -1
- data/bin/calabash-android-build.rb +1 -1
- data/bin/calabash-android-console.rb +4 -4
- data/bin/calabash-android-run.rb +2 -10
- data/bin/testautoa +461 -0
- data/calabash-android.gemspec +3 -1
- data/features-skeleton/support/app_life_cycle_hooks.rb +0 -1
- data/irbrc +3 -1
- data/lib/calabash-android/helpers.rb +45 -17
- data/lib/calabash-android/lib/TestServer.apk +0 -0
- data/lib/calabash-android/lib/unsign.jar +0 -0
- data/lib/calabash-android/operations.rb +150 -66
- data/lib/calabash-android/steps/list_steps.rb +1 -1
- data/lib/calabash-android/steps/time_picker_steps.rb +1 -1
- data/lib/calabash-android/touch_helpers.rb +9 -0
- data/lib/calabash-android/version.rb +1 -1
- data/lib/calabash-android/wait_helpers.rb +93 -0
- data/test-server/AndroidManifest.xml +2 -0
- data/test-server/build.xml +1 -0
- data/test-server/instrumentation-backend/.classpath +0 -1
- data/test-server/instrumentation-backend/AndroidManifest.xml +1 -1
- data/test-server/instrumentation-backend/antlr/UIQuery.g +48 -5
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/Command.java +4 -3
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/FranklyResult.java +95 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/Result.java +7 -1
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/HttpServer.java +14 -29
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/activity/FinishOpenedActivities.java +19 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/activity/GetOpenedActivities.java +31 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/activity/GoBackToActivity.java +67 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/gestures/DragCoordinates.java +28 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/gestures/Swipe.java +11 -5
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/location/FakeGPSLocation.java +13 -10
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/softkey/LeftKey.java +24 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/softkey/RightKey.java +24 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/softkey/UpKey.java +24 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/version/Version.java +31 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/CalabashChromeClient.java +131 -36
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/DumpBodyHtml.java +38 -18
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/DumpHtml.java +38 -16
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/EnterTextByCssSelector.java +94 -66
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/ExecuteAsyncJavascript.java +55 -33
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/ExecuteJavascript.java +53 -31
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/JavaScriptOperation.java +44 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/PressByCssSelector.java +52 -27
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/QueryHelper.java +39 -32
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/ScrollTo.java +56 -41
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/SetPropertyByCssSelector.java +50 -25
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/SetText.java +19 -22
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/CompletedFuture.java +40 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/InvocationOperation.java +222 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/Operation.java +7 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/PropertyOperation.java +56 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/Query.java +151 -43
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/UIQuery.tokens +19 -12
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/UIQueryResultVoid.java +22 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ViewMapper.java +41 -11
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/antlr/UIQueryLexer.java +1010 -242
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/antlr/UIQueryParser.java +406 -98
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/BeginsWithRelation.java +45 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/ComparisonOperator.java +54 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/ContainsRelation.java +41 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/EndsWithRelation.java +42 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/LikeRelation.java +79 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/PartialFutureList.java +100 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryAST.java +1 -1
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryASTClassName.java +54 -25
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryASTPredicate.java +147 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryASTPredicateRelation.java +5 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryASTWith.java +153 -89
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryDirection.java +12 -2
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryEvaluator.java +58 -141
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryUtils.java +162 -7
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryVisibility.java +32 -0
- metadata +130 -97
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/Query.java +0 -24
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/Touch.java +0 -44
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/antlr/UIQuery.tokens +0 -10
- 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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
@
|
|
17
|
+
@SuppressWarnings({ "unchecked", "rawtypes" })
|
|
18
|
+
@Override
|
|
14
19
|
public Result execute(final String... args) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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
|
|
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
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
-
|
|
16
|
+
|
|
17
|
+
@Override
|
|
21
18
|
public Result execute(String... args) {
|
|
22
19
|
//TODO: Should do horizontal scrolling if needed
|
|
23
|
-
String
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
@
|
|
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
|
-
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
+
}
|