OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.content.browser.test.util; | 5 package org.chromium.content.browser.test.util; |
6 | 6 |
7 import android.graphics.Rect; | 7 import android.graphics.Rect; |
8 import android.test.ActivityInstrumentationTestCase2; | 8 import android.test.ActivityInstrumentationTestCase2; |
9 import android.util.JsonReader; | 9 import android.util.JsonReader; |
10 | 10 |
11 import junit.framework.Assert; | 11 import junit.framework.Assert; |
12 | 12 |
13 import org.chromium.content.browser.ContentViewCore; | 13 import org.chromium.content.browser.ContentViewCore; |
| 14 import org.chromium.content_public.browser.WebContents; |
14 | 15 |
15 import java.io.IOException; | 16 import java.io.IOException; |
16 import java.io.StringReader; | 17 import java.io.StringReader; |
17 import java.util.concurrent.TimeoutException; | 18 import java.util.concurrent.TimeoutException; |
18 | 19 |
19 /** | 20 /** |
20 * Collection of DOM-based utilities. | 21 * Collection of DOM-based utilities. |
21 */ | 22 */ |
22 public class DOMUtils { | 23 public class DOMUtils { |
23 | 24 |
24 /** | 25 /** |
25 * Returns whether the video with given {@code nodeId} has ended. | 26 * Returns whether the video with given {@code nodeId} has ended. |
26 */ | 27 */ |
27 public static boolean hasVideoEnded(final ContentViewCore viewCore, final St
ring nodeId) | 28 public static boolean hasVideoEnded(final WebContents webContents, final Str
ing nodeId) |
28 throws InterruptedException, TimeoutException { | 29 throws InterruptedException, TimeoutException { |
29 return getNodeField("ended", viewCore, nodeId, Boolean.class); | 30 return getNodeField("ended", webContents, nodeId, Boolean.class); |
30 } | 31 } |
31 | 32 |
32 /** | 33 /** |
33 * Wait until the end of the video with given {@code nodeId}. | 34 * Wait until the end of the video with given {@code nodeId}. |
34 * @return Whether the video has ended. | 35 * @return Whether the video has ended. |
35 */ | 36 */ |
36 public static boolean waitForEndOfVideo(final ContentViewCore viewCore, fina
l String nodeId) | 37 public static boolean waitForEndOfVideo(final WebContents webContents, final
String nodeId) |
37 throws InterruptedException { | 38 throws InterruptedException { |
38 return CriteriaHelper.pollForCriteria(new Criteria() { | 39 return CriteriaHelper.pollForCriteria(new Criteria() { |
39 @Override | 40 @Override |
40 public boolean isSatisfied() { | 41 public boolean isSatisfied() { |
41 try { | 42 try { |
42 return DOMUtils.hasVideoEnded(viewCore, nodeId); | 43 return DOMUtils.hasVideoEnded(webContents, nodeId); |
43 } catch (InterruptedException e) { | 44 } catch (InterruptedException e) { |
44 // Intentionally do nothing | 45 // Intentionally do nothing |
45 return false; | 46 return false; |
46 } catch (TimeoutException e) { | 47 } catch (TimeoutException e) { |
47 // Intentionally do nothing | 48 // Intentionally do nothing |
48 return false; | 49 return false; |
49 } | 50 } |
50 } | 51 } |
51 }); | 52 }); |
52 } | 53 } |
53 | 54 |
54 /** | 55 /** |
55 * Makes the document exit fullscreen. | 56 * Makes the document exit fullscreen. |
56 */ | 57 */ |
57 public static void exitFullscreen(final ContentViewCore viewCore) { | 58 public static void exitFullscreen(final WebContents webContents) { |
58 StringBuilder sb = new StringBuilder(); | 59 StringBuilder sb = new StringBuilder(); |
59 sb.append("(function() {"); | 60 sb.append("(function() {"); |
60 sb.append(" if (document.webkitExitFullscreen) document.webkitExitFulls
creen();"); | 61 sb.append(" if (document.webkitExitFullscreen) document.webkitExitFulls
creen();"); |
61 sb.append("})();"); | 62 sb.append("})();"); |
62 | 63 |
63 JavaScriptUtils.executeJavaScript(viewCore, sb.toString()); | 64 JavaScriptUtils.executeJavaScript(webContents, sb.toString()); |
64 } | 65 } |
65 | 66 |
66 /** | 67 /** |
67 * Returns the rect boundaries for a node by its id. | 68 * Returns the rect boundaries for a node by its id. |
68 */ | 69 */ |
69 public static Rect getNodeBounds(final ContentViewCore viewCore, String node
Id) | 70 public static Rect getNodeBounds(final WebContents webContents, String nodeI
d) |
70 throws InterruptedException, TimeoutException { | 71 throws InterruptedException, TimeoutException { |
71 StringBuilder sb = new StringBuilder(); | 72 StringBuilder sb = new StringBuilder(); |
72 sb.append("(function() {"); | 73 sb.append("(function() {"); |
73 sb.append(" var node = document.getElementById('" + nodeId + "');"); | 74 sb.append(" var node = document.getElementById('" + nodeId + "');"); |
74 sb.append(" if (!node) return null;"); | 75 sb.append(" if (!node) return null;"); |
75 sb.append(" var width = Math.round(node.offsetWidth);"); | 76 sb.append(" var width = Math.round(node.offsetWidth);"); |
76 sb.append(" var height = Math.round(node.offsetHeight);"); | 77 sb.append(" var height = Math.round(node.offsetHeight);"); |
77 sb.append(" var x = -window.scrollX;"); | 78 sb.append(" var x = -window.scrollX;"); |
78 sb.append(" var y = -window.scrollY;"); | 79 sb.append(" var y = -window.scrollY;"); |
79 sb.append(" do {"); | 80 sb.append(" do {"); |
80 sb.append(" x += node.offsetLeft;"); | 81 sb.append(" x += node.offsetLeft;"); |
81 sb.append(" y += node.offsetTop;"); | 82 sb.append(" y += node.offsetTop;"); |
82 sb.append(" } while (node = node.offsetParent);"); | 83 sb.append(" } while (node = node.offsetParent);"); |
83 sb.append(" return [ Math.round(x), Math.round(y), width, height ];"); | 84 sb.append(" return [ Math.round(x), Math.round(y), width, height ];"); |
84 sb.append("})();"); | 85 sb.append("})();"); |
85 | 86 |
86 String jsonText = JavaScriptUtils.executeJavaScriptAndWaitForResult( | 87 String jsonText = JavaScriptUtils.executeJavaScriptAndWaitForResult( |
87 viewCore, sb.toString()); | 88 webContents, sb.toString()); |
88 | 89 |
89 Assert.assertFalse("Failed to retrieve bounds for " + nodeId, | 90 Assert.assertFalse("Failed to retrieve bounds for " + nodeId, |
90 jsonText.trim().equalsIgnoreCase("null")); | 91 jsonText.trim().equalsIgnoreCase("null")); |
91 | 92 |
92 JsonReader jsonReader = new JsonReader(new StringReader(jsonText)); | 93 JsonReader jsonReader = new JsonReader(new StringReader(jsonText)); |
93 int[] bounds = new int[4]; | 94 int[] bounds = new int[4]; |
94 try { | 95 try { |
95 jsonReader.beginArray(); | 96 jsonReader.beginArray(); |
96 int i = 0; | 97 int i = 0; |
97 while (jsonReader.hasNext()) { | 98 while (jsonReader.hasNext()) { |
98 bounds[i++] = jsonReader.nextInt(); | 99 bounds[i++] = jsonReader.nextInt(); |
99 } | 100 } |
100 jsonReader.endArray(); | 101 jsonReader.endArray(); |
101 Assert.assertEquals("Invalid bounds returned.", 4, i); | 102 Assert.assertEquals("Invalid bounds returned.", 4, i); |
102 | 103 |
103 jsonReader.close(); | 104 jsonReader.close(); |
104 } catch (IOException exception) { | 105 } catch (IOException exception) { |
105 Assert.fail("Failed to evaluate JavaScript: " + jsonText + "\n" + ex
ception); | 106 Assert.fail("Failed to evaluate JavaScript: " + jsonText + "\n" + ex
ception); |
106 } | 107 } |
107 | 108 |
108 return new Rect(bounds[0], bounds[1], bounds[0] + bounds[2], bounds[1] +
bounds[3]); | 109 return new Rect(bounds[0], bounds[1], bounds[0] + bounds[2], bounds[1] +
bounds[3]); |
109 } | 110 } |
110 | 111 |
111 /** | 112 /** |
112 * Focus a DOM node by its id. | 113 * Focus a DOM node by its id. |
113 */ | 114 */ |
114 public static void focusNode(final ContentViewCore viewCore, String nodeId) | 115 public static void focusNode(final WebContents webContents, String nodeId) |
115 throws InterruptedException, TimeoutException { | 116 throws InterruptedException, TimeoutException { |
116 StringBuilder sb = new StringBuilder(); | 117 StringBuilder sb = new StringBuilder(); |
117 sb.append("(function() {"); | 118 sb.append("(function() {"); |
118 sb.append(" var node = document.getElementById('" + nodeId + "');"); | 119 sb.append(" var node = document.getElementById('" + nodeId + "');"); |
119 sb.append(" if (node) node.focus();"); | 120 sb.append(" if (node) node.focus();"); |
120 sb.append("})();"); | 121 sb.append("})();"); |
121 | 122 |
122 JavaScriptUtils.executeJavaScriptAndWaitForResult(viewCore, sb.toString(
)); | 123 JavaScriptUtils.executeJavaScriptAndWaitForResult(webContents, sb.toStri
ng()); |
123 } | 124 } |
124 | 125 |
125 /** | 126 /** |
126 * Click a DOM node by its id. | 127 * Click a DOM node by its id. |
127 */ | 128 */ |
128 public static void clickNode(ActivityInstrumentationTestCase2 activityTestCa
se, | 129 public static void clickNode(ActivityInstrumentationTestCase2 activityTestCa
se, |
129 final ContentViewCore viewCore, String nodeId) | 130 final ContentViewCore viewCore, String nodeId) |
130 throws InterruptedException, TimeoutException { | 131 throws InterruptedException, TimeoutException { |
131 int[] clickTarget = getClickTargetForNode(viewCore, nodeId); | 132 int[] clickTarget = getClickTargetForNode(viewCore, nodeId); |
132 TouchCommon touchCommon = new TouchCommon(activityTestCase); | 133 TouchCommon touchCommon = new TouchCommon(activityTestCase); |
133 touchCommon.singleClickView(viewCore.getContainerView(), clickTarget[0],
clickTarget[1]); | 134 touchCommon.singleClickView(viewCore.getContainerView(), clickTarget[0],
clickTarget[1]); |
134 } | 135 } |
135 | 136 |
136 /** | 137 /** |
137 * Long-press a DOM node by its id. | 138 * Long-press a DOM node by its id. |
138 */ | 139 */ |
139 public static void longPressNode(ActivityInstrumentationTestCase2 activityTe
stCase, | 140 public static void longPressNode(ActivityInstrumentationTestCase2 activityTe
stCase, |
140 final ContentViewCore viewCore, String nodeId) | 141 final ContentViewCore viewCore, String nodeId) |
141 throws InterruptedException, TimeoutException { | 142 throws InterruptedException, TimeoutException { |
142 int[] clickTarget = getClickTargetForNode(viewCore, nodeId); | 143 int[] clickTarget = getClickTargetForNode(viewCore, nodeId); |
143 TouchCommon touchCommon = new TouchCommon(activityTestCase); | 144 TouchCommon touchCommon = new TouchCommon(activityTestCase); |
144 touchCommon.longPressView(viewCore.getContainerView(), clickTarget[0], c
lickTarget[1]); | 145 touchCommon.longPressView(viewCore.getContainerView(), clickTarget[0], c
lickTarget[1]); |
145 } | 146 } |
146 | 147 |
147 /** | 148 /** |
148 * Scrolls the view to ensure that the required DOM node is visible. | 149 * Scrolls the view to ensure that the required DOM node is visible. |
149 */ | 150 */ |
150 public static void scrollNodeIntoView(ContentViewCore viewCore, String nodeI
d) | 151 public static void scrollNodeIntoView(WebContents webContents, String nodeId
) |
151 throws InterruptedException, TimeoutException { | 152 throws InterruptedException, TimeoutException { |
152 JavaScriptUtils.executeJavaScriptAndWaitForResult(viewCore, | 153 JavaScriptUtils.executeJavaScriptAndWaitForResult(webContents, |
153 "document.getElementById('" + nodeId + "').scrollIntoView()"); | 154 "document.getElementById('" + nodeId + "').scrollIntoView()"); |
154 } | 155 } |
155 | 156 |
156 /** | 157 /** |
157 * Returns the contents of the node by its id. | 158 * Returns the contents of the node by its id. |
158 */ | 159 */ |
159 public static String getNodeContents(ContentViewCore viewCore, String nodeId
) | 160 public static String getNodeContents(WebContents webContents, String nodeId) |
160 throws InterruptedException, TimeoutException { | 161 throws InterruptedException, TimeoutException { |
161 return getNodeField("textContent", viewCore, nodeId, String.class); | 162 return getNodeField("textContent", webContents, nodeId, String.class); |
162 } | 163 } |
163 | 164 |
164 /** | 165 /** |
165 * Returns the value of the node by its id. | 166 * Returns the value of the node by its id. |
166 */ | 167 */ |
167 public static String getNodeValue(final ContentViewCore viewCore, String nod
eId) | 168 public static String getNodeValue(final WebContents webContents, String node
Id) |
168 throws InterruptedException, TimeoutException { | 169 throws InterruptedException, TimeoutException { |
169 return getNodeField("value", viewCore, nodeId, String.class); | 170 return getNodeField("value", webContents, nodeId, String.class); |
170 } | 171 } |
171 | 172 |
172 /** | 173 /** |
173 * Returns the string value of a field of the node by its id. | 174 * Returns the string value of a field of the node by its id. |
174 */ | 175 */ |
175 public static String getNodeField(String fieldName, final ContentViewCore vi
ewCore, | 176 public static String getNodeField(String fieldName, final WebContents webCon
tents, |
176 String nodeId) | 177 String nodeId) |
177 throws InterruptedException, TimeoutException { | 178 throws InterruptedException, TimeoutException { |
178 return getNodeField(fieldName, viewCore, nodeId, String.class); | 179 return getNodeField(fieldName, webContents, nodeId, String.class); |
179 } | 180 } |
180 | 181 |
181 private static <T> T getNodeField(String fieldName, final ContentViewCore vi
ewCore, | 182 private static <T> T getNodeField(String fieldName, final WebContents webCon
tents, |
182 String nodeId, Class<T> valueType) | 183 String nodeId, Class<T> valueType) |
183 throws InterruptedException, TimeoutException { | 184 throws InterruptedException, TimeoutException { |
184 StringBuilder sb = new StringBuilder(); | 185 StringBuilder sb = new StringBuilder(); |
185 sb.append("(function() {"); | 186 sb.append("(function() {"); |
186 sb.append(" var node = document.getElementById('" + nodeId + "');"); | 187 sb.append(" var node = document.getElementById('" + nodeId + "');"); |
187 sb.append(" if (!node) return null;"); | 188 sb.append(" if (!node) return null;"); |
188 sb.append(" return [ node." + fieldName + " ];"); | 189 sb.append(" return [ node." + fieldName + " ];"); |
189 sb.append("})();"); | 190 sb.append("})();"); |
190 | 191 |
191 String jsonText = JavaScriptUtils.executeJavaScriptAndWaitForResult( | 192 String jsonText = JavaScriptUtils.executeJavaScriptAndWaitForResult( |
192 viewCore, sb.toString()); | 193 webContents, sb.toString()); |
193 Assert.assertFalse("Failed to retrieve contents for " + nodeId, | 194 Assert.assertFalse("Failed to retrieve contents for " + nodeId, |
194 jsonText.trim().equalsIgnoreCase("null")); | 195 jsonText.trim().equalsIgnoreCase("null")); |
195 | 196 |
196 JsonReader jsonReader = new JsonReader(new StringReader(jsonText)); | 197 JsonReader jsonReader = new JsonReader(new StringReader(jsonText)); |
197 T value = null; | 198 T value = null; |
198 try { | 199 try { |
199 jsonReader.beginArray(); | 200 jsonReader.beginArray(); |
200 if (jsonReader.hasNext()) value = readValue(jsonReader, valueType); | 201 if (jsonReader.hasNext()) value = readValue(jsonReader, valueType); |
201 jsonReader.endArray(); | 202 jsonReader.endArray(); |
202 Assert.assertNotNull("Invalid contents returned.", value); | 203 Assert.assertNotNull("Invalid contents returned.", value); |
(...skipping 14 matching lines...) Expand all Loading... |
217 if (valueType.equals(Long.class)) return ((T) ((Long) jsonReader.nextLon
g())); | 218 if (valueType.equals(Long.class)) return ((T) ((Long) jsonReader.nextLon
g())); |
218 if (valueType.equals(Double.class)) return ((T) ((Double) jsonReader.nex
tDouble())); | 219 if (valueType.equals(Double.class)) return ((T) ((Double) jsonReader.nex
tDouble())); |
219 | 220 |
220 throw new IllegalArgumentException("Cannot read values of type " + value
Type); | 221 throw new IllegalArgumentException("Cannot read values of type " + value
Type); |
221 } | 222 } |
222 | 223 |
223 /** | 224 /** |
224 * Wait until a given node has non-zero bounds. | 225 * Wait until a given node has non-zero bounds. |
225 * @return Whether the node started having non-zero bounds. | 226 * @return Whether the node started having non-zero bounds. |
226 */ | 227 */ |
227 public static boolean waitForNonZeroNodeBounds(final ContentViewCore viewCor
e, | 228 public static boolean waitForNonZeroNodeBounds(final WebContents webContents
, |
228 final String nodeName) | 229 final String nodeName) |
229 throws InterruptedException { | 230 throws InterruptedException { |
230 return CriteriaHelper.pollForCriteria(new Criteria() { | 231 return CriteriaHelper.pollForCriteria(new Criteria() { |
231 @Override | 232 @Override |
232 public boolean isSatisfied() { | 233 public boolean isSatisfied() { |
233 try { | 234 try { |
234 return !DOMUtils.getNodeBounds(viewCore, nodeName).isEmpty()
; | 235 return !DOMUtils.getNodeBounds(webContents, nodeName).isEmpt
y(); |
235 } catch (InterruptedException e) { | 236 } catch (InterruptedException e) { |
236 // Intentionally do nothing | 237 // Intentionally do nothing |
237 return false; | 238 return false; |
238 } catch (TimeoutException e) { | 239 } catch (TimeoutException e) { |
239 // Intentionally do nothing | 240 // Intentionally do nothing |
240 return false; | 241 return false; |
241 } | 242 } |
242 } | 243 } |
243 }); | 244 }); |
244 } | 245 } |
245 | 246 |
246 /** | 247 /** |
247 * Returns click targets for a given DOM node. | 248 * Returns click targets for a given DOM node. |
248 */ | 249 */ |
249 private static int[] getClickTargetForNode(ContentViewCore viewCore, String
nodeName) | 250 private static int[] getClickTargetForNode(ContentViewCore viewCore, String
nodeName) |
250 throws InterruptedException, TimeoutException { | 251 throws InterruptedException, TimeoutException { |
251 Rect bounds = getNodeBounds(viewCore, nodeName); | 252 Rect bounds = getNodeBounds(viewCore.getWebContents(), nodeName); |
252 Assert.assertNotNull("Failed to get DOM element bounds of '" + nodeName
+ "'.", bounds); | 253 Assert.assertNotNull("Failed to get DOM element bounds of '" + nodeName
+ "'.", bounds); |
253 | 254 |
254 int clickX = (int) viewCore.getRenderCoordinates().fromLocalCssToPix(bou
nds.exactCenterX()); | 255 int clickX = (int) viewCore.getRenderCoordinates().fromLocalCssToPix(bou
nds.exactCenterX()); |
255 int clickY = (int) viewCore.getRenderCoordinates().fromLocalCssToPix(bou
nds.exactCenterY()) | 256 int clickY = (int) viewCore.getRenderCoordinates().fromLocalCssToPix(bou
nds.exactCenterY()) |
256 + viewCore.getTopControlsLayoutHeightPix(); | 257 + viewCore.getTopControlsLayoutHeightPix(); |
257 return new int[] { clickX, clickY }; | 258 return new int[] { clickX, clickY }; |
258 } | 259 } |
259 } | 260 } |
OLD | NEW |