- add sources.
[platform/framework/web/crosswalk.git] / src / content / public / test / android / javatests / src / org / chromium / content / browser / test / util / DOMUtils.java
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.content.browser.test.util;
6
7 import android.graphics.Rect;
8 import android.test.ActivityInstrumentationTestCase2;
9 import android.util.JsonReader;
10
11 import java.io.IOException;
12 import java.io.StringReader;
13 import java.util.concurrent.TimeoutException;
14
15 import junit.framework.Assert;
16
17 import org.chromium.content.browser.ContentView;
18
19 /**
20  * Collection of DOM-based utilities.
21  */
22 public class DOMUtils {
23
24     /**
25      * Returns the rect boundaries for a node by its id.
26      */
27     public static Rect getNodeBounds(
28             final ContentView view, TestCallbackHelperContainer viewClient, String nodeId)
29             throws InterruptedException, TimeoutException {
30         StringBuilder sb = new StringBuilder();
31         sb.append("(function() {");
32         sb.append("  var node = document.getElementById('" + nodeId + "');");
33         sb.append("  if (!node) return null;");
34         sb.append("  var width = node.offsetWidth;");
35         sb.append("  var height = node.offsetHeight;");
36         sb.append("  var x = -window.scrollX;");
37         sb.append("  var y = -window.scrollY;");
38         sb.append("  do {");
39         sb.append("    x += node.offsetLeft;");
40         sb.append("    y += node.offsetTop;");
41         sb.append("  } while (node = node.offsetParent);");
42         sb.append("  return [ x, y, width, height ];");
43         sb.append("})();");
44
45         String jsonText = JavaScriptUtils.executeJavaScriptAndWaitForResult(
46                 view, viewClient, sb.toString());
47
48         Assert.assertFalse("Failed to retrieve bounds for " + nodeId,
49                 jsonText.trim().equalsIgnoreCase("null"));
50
51         JsonReader jsonReader = new JsonReader(new StringReader(jsonText));
52         int[] bounds = new int[4];
53         try {
54             jsonReader.beginArray();
55             int i = 0;
56             while (jsonReader.hasNext()) {
57                 bounds[i++] = jsonReader.nextInt();
58             }
59             jsonReader.endArray();
60             Assert.assertEquals("Invalid bounds returned.", 4, i);
61
62             jsonReader.close();
63         } catch (IOException exception) {
64             Assert.fail("Failed to evaluate JavaScript: " + jsonText + "\n" + exception);
65         }
66
67         return new Rect(bounds[0], bounds[1], bounds[0] + bounds[2], bounds[1] + bounds[3]);
68     }
69
70     /**
71      * Focus a DOM node by its id.
72      */
73     public static void focusNode(ActivityInstrumentationTestCase2 activityTestCase,
74             final ContentView view, TestCallbackHelperContainer viewClient, String nodeId)
75             throws InterruptedException, TimeoutException {
76         StringBuilder sb = new StringBuilder();
77         sb.append("(function() {");
78         sb.append("  var node = document.getElementById('" + nodeId + "');");
79         sb.append("  if (node) node.focus();");
80         sb.append("})();");
81
82         JavaScriptUtils.executeJavaScriptAndWaitForResult(view, viewClient, sb.toString());
83     }
84
85     /**
86      * Click a DOM node by its id.
87      */
88     public static void clickNode(ActivityInstrumentationTestCase2 activityTestCase,
89             final ContentView view, TestCallbackHelperContainer viewClient, String nodeId)
90             throws InterruptedException, TimeoutException {
91         int[] clickTarget = getClickTargetForNode(view, viewClient, nodeId);
92         TouchCommon touchCommon = new TouchCommon(activityTestCase);
93         touchCommon.singleClickView(view, clickTarget[0], clickTarget[1]);
94     }
95
96     /**
97      * Long-press a DOM node by its id.
98      */
99     public static void longPressNode(ActivityInstrumentationTestCase2 activityTestCase,
100             final ContentView view, TestCallbackHelperContainer viewClient, String nodeId)
101             throws InterruptedException, TimeoutException {
102         int[] clickTarget = getClickTargetForNode(view, viewClient, nodeId);
103         TouchCommon touchCommon = new TouchCommon(activityTestCase);
104         touchCommon.longPressView(view, clickTarget[0], clickTarget[1]);
105     }
106
107     /**
108      * Scrolls the view to ensure that the required DOM node is visible.
109      */
110     public static void scrollNodeIntoView(final ContentView view,
111             TestCallbackHelperContainer viewClient, String nodeId)
112             throws InterruptedException, TimeoutException {
113         JavaScriptUtils.executeJavaScriptAndWaitForResult(view, viewClient,
114                 "document.getElementById('" + nodeId + "').scrollIntoView()");
115     }
116
117     /**
118      * Returns the contents of the node by its id.
119      */
120     public static String getNodeContents(final ContentView view,
121             TestCallbackHelperContainer viewClient, String nodeId)
122             throws InterruptedException, TimeoutException {
123         return getNodeField("textContent", view, viewClient, nodeId);
124     }
125
126     /**
127      * Returns the value of the node by its id.
128      */
129     public static String getNodeValue(final ContentView view,
130             TestCallbackHelperContainer viewClient, String nodeId)
131             throws InterruptedException, TimeoutException {
132         return getNodeField("value", view, viewClient, nodeId);
133     }
134
135     private static String getNodeField(String fieldName, final ContentView view,
136             TestCallbackHelperContainer viewClient, String nodeId)
137             throws InterruptedException, TimeoutException {
138         StringBuilder sb = new StringBuilder();
139         sb.append("(function() {");
140         sb.append("  var node = document.getElementById('" + nodeId + "');");
141         sb.append("  if (!node) return null;");
142         sb.append("  if (!node." + fieldName +") return null;");
143         sb.append("  return [ node." + fieldName + " ];");
144         sb.append("})();");
145
146         String jsonText = JavaScriptUtils.executeJavaScriptAndWaitForResult(
147                 view, viewClient, sb.toString());
148         Assert.assertFalse("Failed to retrieve contents for " + nodeId,
149                 jsonText.trim().equalsIgnoreCase("null"));
150
151         JsonReader jsonReader = new JsonReader(new StringReader(jsonText));
152         String value = null;
153         try {
154             jsonReader.beginArray();
155             if (jsonReader.hasNext()) value = jsonReader.nextString();
156             jsonReader.endArray();
157             Assert.assertNotNull("Invalid contents returned.", value);
158
159             jsonReader.close();
160         } catch (IOException exception) {
161             Assert.fail("Failed to evaluate JavaScript: " + jsonText + "\n" + exception);
162         }
163         return value;
164     }
165
166     /**
167      * Returns click targets for a given DOM node.
168      */
169     private static int[] getClickTargetForNode(final ContentView view,
170             TestCallbackHelperContainer viewClient, String nodeName)
171             throws InterruptedException, TimeoutException {
172         Rect bounds = getNodeBounds(view, viewClient, nodeName);
173         Assert.assertNotNull("Failed to get DOM element bounds of '" + nodeName + "'.", bounds);
174
175         int clickX = (int) view.getRenderCoordinates().fromLocalCssToPix(bounds.exactCenterX())
176                 + (int) view.getContentViewCore().getViewportSizeOffsetWidthPix();
177         int clickY = (int) view.getRenderCoordinates().fromLocalCssToPix(bounds.exactCenterY())
178                 + (int) view.getContentViewCore().getViewportSizeOffsetHeightPix();
179         return new int[] { clickX, clickY };
180     }
181 }