Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(50)

Side by Side Diff: content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeBasicsTest.java

Issue 2766393004: Convert most of the rest of instrumentation tests in content (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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; 5 package org.chromium.content.browser;
6 6
7 import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout; 7 import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
8 8
9 import android.support.test.InstrumentationRegistry;
9 import android.support.test.filters.SmallTest; 10 import android.support.test.filters.SmallTest;
10 11
11 import junit.framework.Assert; 12 import org.junit.Assert;
13 import org.junit.Rule;
14 import org.junit.Test;
15 import org.junit.runner.RunWith;
12 16
13 import org.chromium.base.annotations.SuppressFBWarnings; 17 import org.chromium.base.annotations.SuppressFBWarnings;
14 import org.chromium.base.test.util.CommandLineFlags; 18 import org.chromium.base.test.BaseJUnit4ClassRunner;
19 import org.chromium.base.test.util.CommandLineTestRule;
15 import org.chromium.base.test.util.Feature; 20 import org.chromium.base.test.util.Feature;
16 import org.chromium.content.browser.JavaBridgeTestCommon.Controller; 21 import org.chromium.content.browser.JavaBridgeTestCommon.Controller;
17 import org.chromium.content.browser.test.util.TestCallbackHelperContainer; 22 import org.chromium.content.browser.test.util.TestCallbackHelperContainer;
23 import org.chromium.content.common.ContentSwitches;
18 import org.chromium.content_public.browser.LoadUrlParams; 24 import org.chromium.content_public.browser.LoadUrlParams;
19 25
20 import java.lang.annotation.ElementType; 26 import java.lang.annotation.ElementType;
21 import java.lang.annotation.Retention; 27 import java.lang.annotation.Retention;
22 import java.lang.annotation.RetentionPolicy; 28 import java.lang.annotation.RetentionPolicy;
23 import java.lang.annotation.Target; 29 import java.lang.annotation.Target;
24 import java.lang.ref.WeakReference; 30 import java.lang.ref.WeakReference;
25 import java.util.concurrent.CountDownLatch; 31 import java.util.concurrent.CountDownLatch;
26 32
27 /** 33 /**
28 * Part of the test suite for the Java Bridge. Tests a number of features includ ing ... 34 * Part of the test suite for the Java Bridge. Tests a number of features includ ing ...
29 * - The type of injected objects 35 * - The type of injected objects
30 * - The type of their methods 36 * - The type of their methods
31 * - Replacing objects 37 * - Replacing objects
32 * - Removing objects 38 * - Removing objects
33 * - Access control 39 * - Access control
34 * - Calling methods on returned objects 40 * - Calling methods on returned objects
35 * - Multiply injected objects 41 * - Multiply injected objects
36 * - Threading 42 * - Threading
37 * - Inheritance 43 * - Inheritance
38 */ 44 */
45 @RunWith(BaseJUnit4ClassRunner.class)
39 @SuppressFBWarnings( 46 @SuppressFBWarnings(
40 {"UMAC_UNCALLABLE_METHOD_OF_ANONYMOUS_CLASS", "URF_UNREAD_PUBLIC_OR_PROT ECTED_FIELD"}) 47 {"UMAC_UNCALLABLE_METHOD_OF_ANONYMOUS_CLASS", "URF_UNREAD_PUBLIC_OR_PROT ECTED_FIELD"})
41 public class JavaBridgeBasicsTest extends JavaBridgeTestBase { 48 public class JavaBridgeBasicsTest {
49 @Rule
50 public JavaBridgeActivityTestRule mActivityTestRule = new JavaBridgeActivity TestRule(false);
51
52 @Rule
53 public CommandLineTestRule mCommandLineRule = new CommandLineTestRule(false) ;
54
42 @SuppressFBWarnings("CHROMIUM_SYNCHRONIZED_METHOD") 55 @SuppressFBWarnings("CHROMIUM_SYNCHRONIZED_METHOD")
43 private static class TestController extends Controller { 56 private static class TestController extends Controller {
44 private int mIntValue; 57 private int mIntValue;
45 private long mLongValue; 58 private long mLongValue;
46 private String mStringValue; 59 private String mStringValue;
47 private boolean mBooleanValue; 60 private boolean mBooleanValue;
48 61
49 public synchronized void setIntValue(int x) { 62 public synchronized void setIntValue(int x) {
50 mIntValue = x; 63 mIntValue = x;
51 notifyResultIsReady(); 64 notifyResultIsReady();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 } 99 }
87 100
88 private static class ObjectWithStaticMethod { 101 private static class ObjectWithStaticMethod {
89 public static String staticMethod() { 102 public static String staticMethod() {
90 return "foo"; 103 return "foo";
91 } 104 }
92 } 105 }
93 106
94 TestController mTestController; 107 TestController mTestController;
95 108
96 @Override 109 private void setUpHelper() throws Exception {
97 protected void setUp() throws Exception { 110 mActivityTestRule.setUpContentView();
98 super.setUp();
99 mTestController = new TestController(); 111 mTestController = new TestController();
100 injectObjectAndReload(mTestController, "testController"); 112 mActivityTestRule.injectObjectAndReload(mTestController, "testController ");
101 } 113 }
102 114
103 // Note that this requires that we can pass a JavaScript string to Java. 115 // Note that this requires that we can pass a JavaScript string to Java.
104 protected String executeJavaScriptAndGetStringResult(String script) throws T hrowable { 116 protected String executeJavaScriptAndGetStringResult(String script) throws T hrowable {
105 executeJavaScript("testController.setStringValue(" + script + ");"); 117 mActivityTestRule.executeJavaScript("testController.setStringValue(" + s cript + ");");
106 return mTestController.waitForStringValue(); 118 return mTestController.waitForStringValue();
107 } 119 }
108 120
109 // Note that this requires that we can pass a JavaScript boolean to Java. 121 // Note that this requires that we can pass a JavaScript boolean to Java.
110 private void executeAndSetIfException(String script) throws Throwable { 122 private void executeAndSetIfException(String script) throws Throwable {
111 executeJavaScript("try {" 123 mActivityTestRule.executeJavaScript("try {" + script + ";"
112 + script + ";"
113 + " testController.setBooleanValue(false);" 124 + " testController.setBooleanValue(false);"
114 + "} catch (exception) {" 125 + "} catch (exception) {"
115 + " testController.setBooleanValue(true);" 126 + " testController.setBooleanValue(true);"
116 + "}"); 127 + "}");
117 } 128 }
118 129
119 private void assertRaisesException(String script) throws Throwable { 130 private void assertRaisesException(String script) throws Throwable {
120 executeAndSetIfException(script); 131 executeAndSetIfException(script);
121 assertTrue(mTestController.waitForBooleanValue()); 132 Assert.assertTrue(mTestController.waitForBooleanValue());
122 } 133 }
123 134
124 private void assertNoRaisedException(String script) throws Throwable { 135 private void assertNoRaisedException(String script) throws Throwable {
125 executeAndSetIfException(script); 136 executeAndSetIfException(script);
126 assertFalse(mTestController.waitForBooleanValue()); 137 Assert.assertFalse(mTestController.waitForBooleanValue());
127 } 138 }
128 139
140 @Test
129 @SmallTest 141 @SmallTest
130 @Feature({"AndroidWebView", "Android-JavaBridge"}) 142 @Feature({"AndroidWebView", "Android-JavaBridge"})
131 public void testTypeOfInjectedObject() throws Throwable { 143 public void testTypeOfInjectedObject() throws Throwable {
132 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testC ontroller")); 144 setUpHelper();
145 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f testController"));
133 } 146 }
134 147
148 @Test
135 @SmallTest 149 @SmallTest
136 @Feature({"AndroidWebView", "Android-JavaBridge"}) 150 @Feature({"AndroidWebView", "Android-JavaBridge"})
137 public void testAdditionNotReflectedUntilReload() throws Throwable { 151 public void testAdditionNotReflectedUntilReload() throws Throwable {
138 assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof te stObject")); 152 setUpHelper();
139 runTestOnUiThread(new Runnable() { 153 Assert.assertEquals("undefined", executeJavaScriptAndGetStringResult("ty peof testObject"));
154 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable( ) {
140 @Override 155 @Override
141 public void run() { 156 public void run() {
142 getContentViewCore().addPossiblyUnsafeJavascriptInterface( 157 mActivityTestRule.getContentViewCore().addPossiblyUnsafeJavascri ptInterface(
143 new Object(), "testObject", null); 158 new Object(), "testObject", null);
144 } 159 }
145 }); 160 });
146 assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof te stObject")); 161 Assert.assertEquals("undefined", executeJavaScriptAndGetStringResult("ty peof testObject"));
147 synchronousPageReload(); 162 mActivityTestRule.synchronousPageReload();
148 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testO bject")); 163 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f testObject"));
149 } 164 }
150 165
166 @Test
151 @SmallTest 167 @SmallTest
152 @Feature({"AndroidWebView", "Android-JavaBridge"}) 168 @Feature({"AndroidWebView", "Android-JavaBridge"})
153 public void testRemovalNotReflectedUntilReload() throws Throwable { 169 public void testRemovalNotReflectedUntilReload() throws Throwable {
154 injectObjectAndReload(new Object() { 170 setUpHelper();
171 mActivityTestRule.injectObjectAndReload(new Object() {
155 public void method() { 172 public void method() {
156 mTestController.setStringValue("I'm here"); 173 mTestController.setStringValue("I'm here");
157 } 174 }
158 }, "testObject"); 175 }, "testObject");
159 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testO bject")); 176 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f testObject"));
160 executeJavaScript("testObject.method()"); 177 mActivityTestRule.executeJavaScript("testObject.method()");
161 assertEquals("I'm here", mTestController.waitForStringValue()); 178 Assert.assertEquals("I'm here", mTestController.waitForStringValue());
162 runTestOnUiThread(new Runnable() { 179 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable( ) {
163 @Override 180 @Override
164 public void run() { 181 public void run() {
165 getContentViewCore().removeJavascriptInterface("testObject"); 182 mActivityTestRule.getContentViewCore().removeJavascriptInterface ("testObject");
166 } 183 }
167 }); 184 });
168 // Check that the Java object is being held by the Java bridge, thus it' s not 185 // Check that the Java object is being held by the Java bridge, thus it' s not
169 // collected. Note that despite that what JavaDoc says about invoking "g c()", both Dalvik 186 // collected. Note that despite that what JavaDoc says about invoking "g c()", both Dalvik
170 // and ART actually run the collector if called via Runtime. 187 // and ART actually run the collector if called via Runtime.
171 Runtime.getRuntime().gc(); 188 Runtime.getRuntime().gc();
172 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testO bject")); 189 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f testObject"));
173 executeJavaScript("testObject.method()"); 190 mActivityTestRule.executeJavaScript("testObject.method()");
174 assertEquals("I'm here", mTestController.waitForStringValue()); 191 Assert.assertEquals("I'm here", mTestController.waitForStringValue());
175 synchronousPageReload(); 192 mActivityTestRule.synchronousPageReload();
176 assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof te stObject")); 193 Assert.assertEquals("undefined", executeJavaScriptAndGetStringResult("ty peof testObject"));
177 } 194 }
178 195
196 @Test
179 @SmallTest 197 @SmallTest
180 @Feature({"AndroidWebView", "Android-JavaBridge"}) 198 @Feature({"AndroidWebView", "Android-JavaBridge"})
181 public void testRemoveObjectNotAdded() throws Throwable { 199 public void testRemoveObjectNotAdded() throws Throwable {
200 setUpHelper();
182 TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper = 201 TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
183 getTestCallBackHelperContainer().getOnPageFinishedHelper(); 202 mActivityTestRule.getTestCallBackHelperContainer().getOnPageFini shedHelper();
184 int currentCallCount = onPageFinishedHelper.getCallCount(); 203 int currentCallCount = onPageFinishedHelper.getCallCount();
185 runTestOnUiThread(new Runnable() { 204 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable( ) {
186 @Override 205 @Override
187 public void run() { 206 public void run() {
188 getContentViewCore().removeJavascriptInterface("foo"); 207 mActivityTestRule.getContentViewCore().removeJavascriptInterface ("foo");
189 getContentViewCore().getWebContents().getNavigationController(). reload(true); 208 mActivityTestRule.getContentViewCore()
209 .getWebContents()
210 .getNavigationController()
211 .reload(true);
190 } 212 }
191 }); 213 });
192 onPageFinishedHelper.waitForCallback(currentCallCount); 214 onPageFinishedHelper.waitForCallback(currentCallCount);
193 assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof fo o")); 215 Assert.assertEquals("undefined", executeJavaScriptAndGetStringResult("ty peof foo"));
194 } 216 }
195 217
218 @Test
196 @SmallTest 219 @SmallTest
197 @Feature({"AndroidWebView", "Android-JavaBridge"}) 220 @Feature({"AndroidWebView", "Android-JavaBridge"})
198 public void testTypeOfMethod() throws Throwable { 221 public void testTypeOfMethod() throws Throwable {
199 assertEquals("function", 222 setUpHelper();
223 Assert.assertEquals("function",
200 executeJavaScriptAndGetStringResult("typeof testController.setSt ringValue")); 224 executeJavaScriptAndGetStringResult("typeof testController.setSt ringValue"));
201 } 225 }
202 226
227 @Test
203 @SmallTest 228 @SmallTest
204 @Feature({"AndroidWebView", "Android-JavaBridge"}) 229 @Feature({"AndroidWebView", "Android-JavaBridge"})
205 public void testTypeOfInvalidMethod() throws Throwable { 230 public void testTypeOfInvalidMethod() throws Throwable {
206 assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof te stController.foo")); 231 setUpHelper();
232 Assert.assertEquals(
233 "undefined", executeJavaScriptAndGetStringResult("typeof testCon troller.foo"));
207 } 234 }
208 235
236 @Test
209 @SmallTest 237 @SmallTest
210 @Feature({"AndroidWebView", "Android-JavaBridge"}) 238 @Feature({"AndroidWebView", "Android-JavaBridge"})
211 public void testCallingInvalidMethodRaisesException() throws Throwable { 239 public void testCallingInvalidMethodRaisesException() throws Throwable {
240 setUpHelper();
212 assertRaisesException("testController.foo()"); 241 assertRaisesException("testController.foo()");
213 } 242 }
214 243
244 @Test
215 @SmallTest 245 @SmallTest
216 @Feature({"AndroidWebView", "Android-JavaBridge"}) 246 @Feature({"AndroidWebView", "Android-JavaBridge"})
217 public void testUncaughtJavaExceptionRaisesJavaScriptException() throws Thro wable { 247 public void testUncaughtJavaExceptionRaisesJavaScriptException() throws Thro wable {
218 injectObjectAndReload(new Object() { 248 setUpHelper();
249 mActivityTestRule.injectObjectAndReload(new Object() {
219 public void method() { 250 public void method() {
220 throw new RuntimeException("foo"); 251 throw new RuntimeException("foo");
221 } 252 }
222 }, "testObject"); 253 }, "testObject");
223 assertRaisesException("testObject.method()"); 254 assertRaisesException("testObject.method()");
224 } 255 }
225 256
257 @Test
226 @SmallTest 258 @SmallTest
227 @Feature({"AndroidWebView", "Android-JavaBridge"}) 259 @Feature({"AndroidWebView", "Android-JavaBridge"})
228 public void testCallingAsConstructorRaisesException() throws Throwable { 260 public void testCallingAsConstructorRaisesException() throws Throwable {
261 setUpHelper();
229 assertRaisesException("new testController.setStringValue('foo')"); 262 assertRaisesException("new testController.setStringValue('foo')");
230 } 263 }
231 264
265 @Test
232 @SmallTest 266 @SmallTest
233 @Feature({"AndroidWebView", "Android-JavaBridge"}) 267 @Feature({"AndroidWebView", "Android-JavaBridge"})
234 public void testCallingOnNonInjectedObjectRaisesException() throws Throwable { 268 public void testCallingOnNonInjectedObjectRaisesException() throws Throwable {
269 setUpHelper();
235 assertRaisesException("testController.setStringValue.call({}, 'foo')"); 270 assertRaisesException("testController.setStringValue.call({}, 'foo')");
236 } 271 }
237 272
273 @Test
238 @SmallTest 274 @SmallTest
239 @Feature({"AndroidWebView", "Android-JavaBridge"}) 275 @Feature({"AndroidWebView", "Android-JavaBridge"})
240 public void testCallingOnInstanceOfOtherClassRaisesException() throws Throwa ble { 276 public void testCallingOnInstanceOfOtherClassRaisesException() throws Throwa ble {
241 injectObjectAndReload(new Object(), "testObject"); 277 setUpHelper();
242 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testO bject")); 278 mActivityTestRule.injectObjectAndReload(new Object(), "testObject");
243 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testC ontroller")); 279 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f testObject"));
244 assertEquals("function", 280 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f testController"));
281 Assert.assertEquals("function",
245 executeJavaScriptAndGetStringResult("typeof testController.setSt ringValue")); 282 executeJavaScriptAndGetStringResult("typeof testController.setSt ringValue"));
246 assertRaisesException("testController.setStringValue.call(testObject, 'f oo')"); 283 assertRaisesException("testController.setStringValue.call(testObject, 'f oo')");
247 } 284 }
248 285
249 // Note that this requires that we can pass a JavaScript string to Java. 286 // Note that this requires that we can pass a JavaScript string to Java.
287 @Test
250 @SmallTest 288 @SmallTest
251 @Feature({"AndroidWebView", "Android-JavaBridge"}) 289 @Feature({"AndroidWebView", "Android-JavaBridge"})
252 public void testTypeOfStaticMethod() throws Throwable { 290 public void testTypeOfStaticMethod() throws Throwable {
253 injectObjectAndReload(new ObjectWithStaticMethod(), "testObject"); 291 setUpHelper();
254 executeJavaScript("testController.setStringValue(typeof testObject.stati cMethod)"); 292 mActivityTestRule.injectObjectAndReload(new ObjectWithStaticMethod(), "t estObject");
255 assertEquals("function", mTestController.waitForStringValue()); 293 mActivityTestRule.executeJavaScript(
294 "testController.setStringValue(typeof testObject.staticMethod)") ;
295 Assert.assertEquals("function", mTestController.waitForStringValue());
256 } 296 }
257 297
258 // Note that this requires that we can pass a JavaScript string to Java. 298 // Note that this requires that we can pass a JavaScript string to Java.
299 @Test
259 @SmallTest 300 @SmallTest
260 @Feature({"AndroidWebView", "Android-JavaBridge"}) 301 @Feature({"AndroidWebView", "Android-JavaBridge"})
261 public void testCallStaticMethod() throws Throwable { 302 public void testCallStaticMethod() throws Throwable {
262 injectObjectAndReload(new ObjectWithStaticMethod(), "testObject"); 303 setUpHelper();
263 executeJavaScript("testController.setStringValue(testObject.staticMethod ())"); 304 mActivityTestRule.injectObjectAndReload(new ObjectWithStaticMethod(), "t estObject");
264 assertEquals("foo", mTestController.waitForStringValue()); 305 mActivityTestRule.executeJavaScript(
306 "testController.setStringValue(testObject.staticMethod())");
307 Assert.assertEquals("foo", mTestController.waitForStringValue());
265 } 308 }
266 309
310 @Test
267 @SmallTest 311 @SmallTest
268 @Feature({"AndroidWebView", "Android-JavaBridge"}) 312 @Feature({"AndroidWebView", "Android-JavaBridge"})
269 public void testPrivateMethodNotExposed() throws Throwable { 313 public void testPrivateMethodNotExposed() throws Throwable {
270 injectObjectAndReload(new Object() { 314 setUpHelper();
315 mActivityTestRule.injectObjectAndReload(new Object() {
271 private void method() {} 316 private void method() {}
272 protected void method2() {} 317 protected void method2() {}
273 }, "testObject"); 318 }, "testObject");
274 assertEquals("undefined", 319 Assert.assertEquals(
275 executeJavaScriptAndGetStringResult("typeof testObject.method")) ; 320 "undefined", executeJavaScriptAndGetStringResult("typeof testObj ect.method"));
276 assertEquals("undefined", 321 Assert.assertEquals(
277 executeJavaScriptAndGetStringResult("typeof testObject.method2") ); 322 "undefined", executeJavaScriptAndGetStringResult("typeof testObj ect.method2"));
278 } 323 }
279 324
325 @Test
280 @SmallTest 326 @SmallTest
281 @Feature({"AndroidWebView", "Android-JavaBridge"}) 327 @Feature({"AndroidWebView", "Android-JavaBridge"})
282 public void testReplaceInjectedObject() throws Throwable { 328 public void testReplaceInjectedObject() throws Throwable {
283 injectObjectAndReload(new Object() { 329 setUpHelper();
330 mActivityTestRule.injectObjectAndReload(new Object() {
284 public void method() { 331 public void method() {
285 mTestController.setStringValue("object 1"); 332 mTestController.setStringValue("object 1");
286 } 333 }
287 }, "testObject"); 334 }, "testObject");
288 executeJavaScript("testObject.method()"); 335 mActivityTestRule.executeJavaScript("testObject.method()");
289 assertEquals("object 1", mTestController.waitForStringValue()); 336 Assert.assertEquals("object 1", mTestController.waitForStringValue());
290 337
291 injectObjectAndReload(new Object() { 338 mActivityTestRule.injectObjectAndReload(new Object() {
292 public void method() { 339 public void method() {
293 mTestController.setStringValue("object 2"); 340 mTestController.setStringValue("object 2");
294 } 341 }
295 }, "testObject"); 342 }, "testObject");
296 executeJavaScript("testObject.method()"); 343 mActivityTestRule.executeJavaScript("testObject.method()");
297 assertEquals("object 2", mTestController.waitForStringValue()); 344 Assert.assertEquals("object 2", mTestController.waitForStringValue());
298 } 345 }
299 346
347 @Test
300 @SmallTest 348 @SmallTest
301 @Feature({"AndroidWebView", "Android-JavaBridge"}) 349 @Feature({"AndroidWebView", "Android-JavaBridge"})
302 public void testInjectNullObjectIsIgnored() throws Throwable { 350 public void testInjectNullObjectIsIgnored() throws Throwable {
303 injectObjectAndReload(null, "testObject"); 351 setUpHelper();
304 assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof te stObject")); 352 mActivityTestRule.injectObjectAndReload(null, "testObject");
353 Assert.assertEquals("undefined", executeJavaScriptAndGetStringResult("ty peof testObject"));
305 } 354 }
306 355
356 @Test
307 @SmallTest 357 @SmallTest
308 @Feature({"AndroidWebView", "Android-JavaBridge"}) 358 @Feature({"AndroidWebView", "Android-JavaBridge"})
309 public void testReplaceInjectedObjectWithNullObjectIsIgnored() throws Throwa ble { 359 public void testReplaceInjectedObjectWithNullObjectIsIgnored() throws Throwa ble {
310 injectObjectAndReload(new Object(), "testObject"); 360 setUpHelper();
311 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testO bject")); 361 mActivityTestRule.injectObjectAndReload(new Object(), "testObject");
312 injectObjectAndReload(null, "testObject"); 362 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f testObject"));
313 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testO bject")); 363 mActivityTestRule.injectObjectAndReload(null, "testObject");
364 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f testObject"));
314 } 365 }
315 366
367 @Test
316 @SmallTest 368 @SmallTest
317 @Feature({"AndroidWebView", "Android-JavaBridge"}) 369 @Feature({"AndroidWebView", "Android-JavaBridge"})
318 public void testCallOverloadedMethodWithDifferentNumberOfArguments() throws Throwable { 370 public void testCallOverloadedMethodWithDifferentNumberOfArguments() throws Throwable {
319 injectObjectAndReload(new Object() { 371 setUpHelper();
372 mActivityTestRule.injectObjectAndReload(new Object() {
320 public void method() { 373 public void method() {
321 mTestController.setStringValue("0 args"); 374 mTestController.setStringValue("0 args");
322 } 375 }
323 376
324 public void method(int x) { 377 public void method(int x) {
325 mTestController.setStringValue("1 arg"); 378 mTestController.setStringValue("1 arg");
326 } 379 }
327 380
328 public void method(int x, int y) { 381 public void method(int x, int y) {
329 mTestController.setStringValue("2 args"); 382 mTestController.setStringValue("2 args");
330 } 383 }
331 }, "testObject"); 384 }, "testObject");
332 executeJavaScript("testObject.method()"); 385 mActivityTestRule.executeJavaScript("testObject.method()");
333 assertEquals("0 args", mTestController.waitForStringValue()); 386 Assert.assertEquals("0 args", mTestController.waitForStringValue());
334 executeJavaScript("testObject.method(42)"); 387 mActivityTestRule.executeJavaScript("testObject.method(42)");
335 assertEquals("1 arg", mTestController.waitForStringValue()); 388 Assert.assertEquals("1 arg", mTestController.waitForStringValue());
336 executeJavaScript("testObject.method(null)"); 389 mActivityTestRule.executeJavaScript("testObject.method(null)");
337 assertEquals("1 arg", mTestController.waitForStringValue()); 390 Assert.assertEquals("1 arg", mTestController.waitForStringValue());
338 executeJavaScript("testObject.method(undefined)"); 391 mActivityTestRule.executeJavaScript("testObject.method(undefined)");
339 assertEquals("1 arg", mTestController.waitForStringValue()); 392 Assert.assertEquals("1 arg", mTestController.waitForStringValue());
340 executeJavaScript("testObject.method(42, 42)"); 393 mActivityTestRule.executeJavaScript("testObject.method(42, 42)");
341 assertEquals("2 args", mTestController.waitForStringValue()); 394 Assert.assertEquals("2 args", mTestController.waitForStringValue());
342 } 395 }
343 396
397 @Test
344 @SmallTest 398 @SmallTest
345 @Feature({"AndroidWebView", "Android-JavaBridge"}) 399 @Feature({"AndroidWebView", "Android-JavaBridge"})
346 public void testCallMethodWithWrongNumberOfArgumentsRaisesException() throws Throwable { 400 public void testCallMethodWithWrongNumberOfArgumentsRaisesException() throws Throwable {
401 setUpHelper();
347 assertRaisesException("testController.setIntValue()"); 402 assertRaisesException("testController.setIntValue()");
348 assertRaisesException("testController.setIntValue(42, 42)"); 403 assertRaisesException("testController.setIntValue(42, 42)");
349 } 404 }
350 405
406 @Test
351 @SmallTest 407 @SmallTest
352 @Feature({"AndroidWebView", "Android-JavaBridge"}) 408 @Feature({"AndroidWebView", "Android-JavaBridge"})
353 public void testObjectPersistsAcrossPageLoads() throws Throwable { 409 public void testObjectPersistsAcrossPageLoads() throws Throwable {
354 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testC ontroller")); 410 setUpHelper();
355 synchronousPageReload(); 411 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f testController"));
356 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testC ontroller")); 412 mActivityTestRule.synchronousPageReload();
413 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f testController"));
357 } 414 }
358 415
416 @Test
359 @SmallTest 417 @SmallTest
360 @Feature({"AndroidWebView", "Android-JavaBridge"}) 418 @Feature({"AndroidWebView", "Android-JavaBridge"})
361 public void testCustomPropertiesCleanedUpOnPageReloads() throws Throwable { 419 public void testCustomPropertiesCleanedUpOnPageReloads() throws Throwable {
362 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testC ontroller")); 420 setUpHelper();
363 executeJavaScript("testController.myProperty = 42;"); 421 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f testController"));
364 assertEquals("42", executeJavaScriptAndGetStringResult("testController.m yProperty")); 422 mActivityTestRule.executeJavaScript("testController.myProperty = 42;");
365 synchronousPageReload(); 423 Assert.assertEquals("42", executeJavaScriptAndGetStringResult("testContr oller.myProperty"));
366 assertEquals("object", executeJavaScriptAndGetStringResult("typeof testC ontroller")); 424 mActivityTestRule.synchronousPageReload();
367 assertEquals("undefined", executeJavaScriptAndGetStringResult("testContr oller.myProperty")); 425 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f testController"));
426 Assert.assertEquals(
427 "undefined", executeJavaScriptAndGetStringResult("testController .myProperty"));
368 } 428 }
369 429
430 @Test
370 @SmallTest 431 @SmallTest
371 @Feature({"AndroidWebView", "Android-JavaBridge"}) 432 @Feature({"AndroidWebView", "Android-JavaBridge"})
372 public void testSameObjectInjectedMultipleTimes() throws Throwable { 433 public void testSameObjectInjectedMultipleTimes() throws Throwable {
434 setUpHelper();
373 class TestObject { 435 class TestObject {
374 private int mNumMethodInvocations; 436 private int mNumMethodInvocations;
375 437
376 public void method() { 438 public void method() {
377 mTestController.setIntValue(++mNumMethodInvocations); 439 mTestController.setIntValue(++mNumMethodInvocations);
378 } 440 }
379 } 441 }
380 final TestObject testObject = new TestObject(); 442 final TestObject testObject = new TestObject();
381 injectObjectsAndReload(testObject, "testObject1", testObject, "testObjec t2", null); 443 mActivityTestRule.injectObjectsAndReload(
382 executeJavaScript("testObject1.method()"); 444 testObject, "testObject1", testObject, "testObject2", null);
383 assertEquals(1, mTestController.waitForIntValue()); 445 mActivityTestRule.executeJavaScript("testObject1.method()");
384 executeJavaScript("testObject2.method()"); 446 Assert.assertEquals(1, mTestController.waitForIntValue());
385 assertEquals(2, mTestController.waitForIntValue()); 447 mActivityTestRule.executeJavaScript("testObject2.method()");
448 Assert.assertEquals(2, mTestController.waitForIntValue());
386 } 449 }
387 450
451 @Test
388 @SmallTest 452 @SmallTest
389 @Feature({"AndroidWebView", "Android-JavaBridge"}) 453 @Feature({"AndroidWebView", "Android-JavaBridge"})
390 public void testCallMethodOnReturnedObject() throws Throwable { 454 public void testCallMethodOnReturnedObject() throws Throwable {
391 injectObjectAndReload(new Object() { 455 setUpHelper();
456 mActivityTestRule.injectObjectAndReload(new Object() {
392 public Object getInnerObject() { 457 public Object getInnerObject() {
393 return new Object() { 458 return new Object() {
394 public void method(int x) { 459 public void method(int x) {
395 mTestController.setIntValue(x); 460 mTestController.setIntValue(x);
396 } 461 }
397 }; 462 };
398 } 463 }
399 }, "testObject"); 464 }, "testObject");
400 executeJavaScript("testObject.getInnerObject().method(42)"); 465 mActivityTestRule.executeJavaScript("testObject.getInnerObject().method( 42)");
401 assertEquals(42, mTestController.waitForIntValue()); 466 Assert.assertEquals(42, mTestController.waitForIntValue());
402 } 467 }
403 468
469 @Test
404 @SmallTest 470 @SmallTest
405 @Feature({"AndroidWebView", "Android-JavaBridge"}) 471 @Feature({"AndroidWebView", "Android-JavaBridge"})
406 public void testReturnedObjectInjectedElsewhere() throws Throwable { 472 public void testReturnedObjectInjectedElsewhere() throws Throwable {
473 setUpHelper();
407 class InnerObject { 474 class InnerObject {
408 private int mNumMethodInvocations; 475 private int mNumMethodInvocations;
409 476
410 public void method() { 477 public void method() {
411 mTestController.setIntValue(++mNumMethodInvocations); 478 mTestController.setIntValue(++mNumMethodInvocations);
412 } 479 }
413 } 480 }
414 final InnerObject innerObject = new InnerObject(); 481 final InnerObject innerObject = new InnerObject();
415 final Object object = new Object() { 482 final Object object = new Object() {
416 public InnerObject getInnerObject() { 483 public InnerObject getInnerObject() {
417 return innerObject; 484 return innerObject;
418 } 485 }
419 }; 486 };
420 injectObjectsAndReload(object, "testObject", innerObject, "innerObject", null); 487 mActivityTestRule.injectObjectsAndReload(
421 executeJavaScript("testObject.getInnerObject().method()"); 488 object, "testObject", innerObject, "innerObject", null);
422 assertEquals(1, mTestController.waitForIntValue()); 489 mActivityTestRule.executeJavaScript("testObject.getInnerObject().method( )");
423 executeJavaScript("innerObject.method()"); 490 Assert.assertEquals(1, mTestController.waitForIntValue());
424 assertEquals(2, mTestController.waitForIntValue()); 491 mActivityTestRule.executeJavaScript("innerObject.method()");
492 Assert.assertEquals(2, mTestController.waitForIntValue());
425 } 493 }
426 494
427 // Verify that Java objects returned from bridge object methods are derefere nced 495 // Verify that Java objects returned from bridge object methods are derefere nced
428 // on the Java side once they have been fully dereferenced on the JS side. 496 // on the Java side once they have been fully dereferenced on the JS side.
429 // Failing this test would mean that methods returning objects effectively c reate a memory 497 // Failing this test would mean that methods returning objects effectively c reate a memory
430 // leak. 498 // leak.
499 @Test
431 @SmallTest 500 @SmallTest
432 @Feature({"AndroidWebView", "Android-JavaBridge"}) 501 @Feature({"AndroidWebView", "Android-JavaBridge"})
433 @CommandLineFlags.Add("js-flags=--expose-gc")
434 public void testReturnedObjectIsGarbageCollected() throws Throwable { 502 public void testReturnedObjectIsGarbageCollected() throws Throwable {
435 // Make sure V8 exposes "gc" property on the global object (enabled with --expose-gc flag) 503 mCommandLineRule.setFlags(ContentSwitches.ENABLE_TEST_INTENTS, "js-flags =--expose-gc");
436 assertEquals("function", executeJavaScriptAndGetStringResult("typeof gc" )); 504 mCommandLineRule.setUp();
505 setUpHelper();
506 Assert.assertEquals("function", executeJavaScriptAndGetStringResult("typ eof gc"));
437 class InnerObject { 507 class InnerObject {
438 } 508 }
439 class TestObject { 509 class TestObject {
440 public InnerObject getInnerObject() { 510 public InnerObject getInnerObject() {
441 InnerObject inner = new InnerObject(); 511 InnerObject inner = new InnerObject();
442 mWeakRefForInner = new WeakReference<InnerObject>(inner); 512 mWeakRefForInner = new WeakReference<InnerObject>(inner);
443 return inner; 513 return inner;
444 } 514 }
445 // A weak reference is used to check InnerObject instance reachabili ty. 515 // A weak reference is used to check InnerObject instance reachabili ty.
446 WeakReference<InnerObject> mWeakRefForInner; 516 WeakReference<InnerObject> mWeakRefForInner;
447 } 517 }
448 TestObject object = new TestObject(); 518 TestObject object = new TestObject();
449 injectObjectAndReload(object, "testObject"); 519 mActivityTestRule.injectObjectAndReload(object, "testObject");
450 // Initially, store a reference to the inner object in JS to make sure i t's not 520 // Initially, store a reference to the inner object in JS to make sure i t's not
451 // garbage-collected prematurely. 521 // garbage-collected prematurely.
452 assertEquals("object", executeJavaScriptAndGetStringResult( 522 Assert.assertEquals("object",
453 "(function() { " 523 executeJavaScriptAndGetStringResult("(function() { "
454 + "globalInner = testObject.getInnerObject(); return typ eof globalInner; " 524 + "globalInner = testObject.getInnerObject(); return typ eof globalInner; "
455 + "})()")); 525 + "})()"));
456 assertTrue(object.mWeakRefForInner.get() != null); 526 Assert.assertTrue(object.mWeakRefForInner.get() != null);
457 // Check that returned Java object is being held by the Java bridge, thu s it's not 527 // Check that returned Java object is being held by the Java bridge, thu s it's not
458 // collected. Note that despite that what JavaDoc says about invoking " gc()", both Dalvik 528 // collected. Note that despite that what JavaDoc says about invoking " gc()", both Dalvik
459 // and ART actually run the collector. 529 // and ART actually run the collector.
460 Runtime.getRuntime().gc(); 530 Runtime.getRuntime().gc();
461 assertTrue(object.mWeakRefForInner.get() != null); 531 Assert.assertTrue(object.mWeakRefForInner.get() != null);
462 // Now dereference the inner object in JS and run GC to collect the inte rface object. 532 // Now dereference the inner object in JS and run GC to collect the inte rface object.
463 assertEquals("true", executeJavaScriptAndGetStringResult( 533 Assert.assertEquals("true",
464 "(function() { " 534 executeJavaScriptAndGetStringResult("(function() { "
465 + "delete globalInner; gc(); return (typeof globalInner == 'undefined'); " 535 + "delete globalInner; gc(); return (typeof globalInner == 'undefined'); "
466 + "})()")); 536 + "})()"));
467 // Force GC on the Java side again. The bridge had to release the inner object, so it must 537 // Force GC on the Java side again. The bridge had to release the inner object, so it must
468 // be collected this time. 538 // be collected this time.
469 Runtime.getRuntime().gc(); 539 Runtime.getRuntime().gc();
470 assertEquals(null, object.mWeakRefForInner.get()); 540 Assert.assertEquals(null, object.mWeakRefForInner.get());
471 } 541 }
472 542
543 @Test
473 @SmallTest 544 @SmallTest
474 @Feature({"AndroidWebView", "Android-JavaBridge"}) 545 @Feature({"AndroidWebView", "Android-JavaBridge"})
475 public void testSameReturnedObjectUsesSameWrapper() throws Throwable { 546 public void testSameReturnedObjectUsesSameWrapper() throws Throwable {
547 setUpHelper();
476 class InnerObject { 548 class InnerObject {
477 } 549 }
478 final InnerObject innerObject = new InnerObject(); 550 final InnerObject innerObject = new InnerObject();
479 final Object injectedTestObject = new Object() { 551 final Object injectedTestObject = new Object() {
480 public InnerObject getInnerObject() { 552 public InnerObject getInnerObject() {
481 return innerObject; 553 return innerObject;
482 } 554 }
483 }; 555 };
484 injectObjectAndReload(injectedTestObject, "injectedTestObject"); 556 mActivityTestRule.injectObjectAndReload(injectedTestObject, "injectedTes tObject");
485 executeJavaScript("inner1 = injectedTestObject.getInnerObject()"); 557 mActivityTestRule.executeJavaScript("inner1 = injectedTestObject.getInne rObject()");
486 executeJavaScript("inner2 = injectedTestObject.getInnerObject()"); 558 mActivityTestRule.executeJavaScript("inner2 = injectedTestObject.getInne rObject()");
487 assertEquals("object", executeJavaScriptAndGetStringResult("typeof inner 1")); 559 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f inner1"));
488 assertEquals("object", executeJavaScriptAndGetStringResult("typeof inner 2")); 560 Assert.assertEquals("object", executeJavaScriptAndGetStringResult("typeo f inner2"));
489 assertEquals("true", executeJavaScriptAndGetStringResult("inner1 === inn er2")); 561 Assert.assertEquals("true", executeJavaScriptAndGetStringResult("inner1 === inner2"));
490 } 562 }
491 563
564 @Test
492 @SmallTest 565 @SmallTest
493 @Feature({"AndroidWebView", "Android-JavaBridge"}) 566 @Feature({"AndroidWebView", "Android-JavaBridge"})
494 public void testMethodInvokedOnBackgroundThread() throws Throwable { 567 public void testMethodInvokedOnBackgroundThread() throws Throwable {
495 injectObjectAndReload(new Object() { 568 setUpHelper();
569 mActivityTestRule.injectObjectAndReload(new Object() {
496 public void captureThreadId() { 570 public void captureThreadId() {
497 mTestController.setLongValue(Thread.currentThread().getId()); 571 mTestController.setLongValue(Thread.currentThread().getId());
498 } 572 }
499 }, "testObject"); 573 }, "testObject");
500 executeJavaScript("testObject.captureThreadId()"); 574 mActivityTestRule.executeJavaScript("testObject.captureThreadId()");
501 final long threadId = mTestController.waitForLongValue(); 575 final long threadId = mTestController.waitForLongValue();
502 assertFalse(threadId == Thread.currentThread().getId()); 576 Assert.assertFalse(threadId == Thread.currentThread().getId());
503 runTestOnUiThread(new Runnable() { 577 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable( ) {
504 @Override 578 @Override
505 public void run() { 579 public void run() {
506 assertFalse(threadId == Thread.currentThread().getId()); 580 Assert.assertFalse(threadId == Thread.currentThread().getId());
507 } 581 }
508 }); 582 });
509 } 583 }
510 584
585 @Test
511 @SmallTest 586 @SmallTest
512 @Feature({"AndroidWebView", "Android-JavaBridge"}) 587 @Feature({"AndroidWebView", "Android-JavaBridge"})
513 public void testBlockingUiThreadDoesNotBlockCallsFromJs() throws Throwable { 588 public void testBlockingUiThreadDoesNotBlockCallsFromJs() throws Throwable {
589 setUpHelper();
514 class TestObject { 590 class TestObject {
515 private CountDownLatch mLatch; 591 private CountDownLatch mLatch;
516 public TestObject() { 592 public TestObject() {
517 mLatch = new CountDownLatch(1); 593 mLatch = new CountDownLatch(1);
518 } 594 }
519 public boolean waitOnTheLatch() throws Exception { 595 public boolean waitOnTheLatch() throws Exception {
520 return mLatch.await(scaleTimeout(10000), 596 return mLatch.await(scaleTimeout(10000),
521 java.util.concurrent.TimeUnit.MILLISECONDS); 597 java.util.concurrent.TimeUnit.MILLISECONDS);
522 } 598 }
523 public void unlockTheLatch() throws Exception { 599 public void unlockTheLatch() throws Exception {
524 mTestController.setStringValue("unlocked"); 600 mTestController.setStringValue("unlocked");
525 mLatch.countDown(); 601 mLatch.countDown();
526 } 602 }
527 } 603 }
528 final TestObject testObject = new TestObject(); 604 final TestObject testObject = new TestObject();
529 injectObjectAndReload(testObject, "testObject"); 605 mActivityTestRule.injectObjectAndReload(testObject, "testObject");
530 runTestOnUiThread(new Runnable() { 606 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable( ) {
531 @Override 607 @Override
532 public void run() { 608 public void run() {
533 // loadUrl is asynchronous, the JS code will start running on th e renderer 609 // loadUrl is asynchronous, the JS code will start running on th e renderer
534 // thread. As soon as we exit loadUrl, the browser UI thread wil l be stuck waiting 610 // thread. As soon as we exit loadUrl, the browser UI thread wil l be stuck waiting
535 // on the latch. If blocking the browser thread blocks Java Brid ge, then the call 611 // on the latch. If blocking the browser thread blocks Java Brid ge, then the call
536 // to "unlockTheLatch()" will be executed after the waiting time out, thus the 612 // to "unlockTheLatch()" will be executed after the waiting time out, thus the
537 // string value will not yet be updated by the injected object. 613 // string value will not yet be updated by the injected object.
538 mTestController.setStringValue("locked"); 614 mTestController.setStringValue("locked");
539 getWebContents().getNavigationController().loadUrl(new LoadUrlPa rams( 615 mActivityTestRule.getWebContents().getNavigationController().loa dUrl(
540 "javascript:(function() { testObject.unlockTheLatch() }) ()")); 616 new LoadUrlParams(
617 "javascript:(function() { testObject.unlockTheLa tch() })()"));
541 try { 618 try {
542 assertTrue(testObject.waitOnTheLatch()); 619 Assert.assertTrue(testObject.waitOnTheLatch());
543 } catch (Exception e) { 620 } catch (Exception e) {
544 android.util.Log.e("JavaBridgeBasicsTest", "Wait exception", e); 621 android.util.Log.e("JavaBridgeBasicsTest", "Wait exception", e);
545 Assert.fail("Wait exception"); 622 Assert.fail("Wait exception");
546 } 623 }
547 assertEquals("unlocked", mTestController.getStringValue()); 624 Assert.assertEquals("unlocked", mTestController.getStringValue() );
548 } 625 }
549 }); 626 });
550 } 627 }
551 628
629 @Test
552 @SmallTest 630 @SmallTest
553 @Feature({"AndroidWebView", "Android-JavaBridge"}) 631 @Feature({"AndroidWebView", "Android-JavaBridge"})
554 public void testPublicInheritedMethod() throws Throwable { 632 public void testPublicInheritedMethod() throws Throwable {
633 setUpHelper();
555 class Base { 634 class Base {
556 public void method(int x) { 635 public void method(int x) {
557 mTestController.setIntValue(x); 636 mTestController.setIntValue(x);
558 } 637 }
559 } 638 }
560 class Derived extends Base { 639 class Derived extends Base {
561 } 640 }
562 injectObjectAndReload(new Derived(), "testObject"); 641 mActivityTestRule.injectObjectAndReload(new Derived(), "testObject");
563 assertEquals("function", executeJavaScriptAndGetStringResult("typeof tes tObject.method")); 642 Assert.assertEquals(
564 executeJavaScript("testObject.method(42)"); 643 "function", executeJavaScriptAndGetStringResult("typeof testObje ct.method"));
565 assertEquals(42, mTestController.waitForIntValue()); 644 mActivityTestRule.executeJavaScript("testObject.method(42)");
645 Assert.assertEquals(42, mTestController.waitForIntValue());
566 } 646 }
567 647
648 @Test
568 @SmallTest 649 @SmallTest
569 @Feature({"AndroidWebView", "Android-JavaBridge"}) 650 @Feature({"AndroidWebView", "Android-JavaBridge"})
570 public void testPrivateInheritedMethod() throws Throwable { 651 public void testPrivateInheritedMethod() throws Throwable {
652 setUpHelper();
571 class Base { 653 class Base {
572 private void method() {} 654 private void method() {}
573 } 655 }
574 class Derived extends Base { 656 class Derived extends Base {
575 } 657 }
576 injectObjectAndReload(new Derived(), "testObject"); 658 mActivityTestRule.injectObjectAndReload(new Derived(), "testObject");
577 assertEquals("undefined", executeJavaScriptAndGetStringResult("typeof te stObject.method")); 659 Assert.assertEquals(
660 "undefined", executeJavaScriptAndGetStringResult("typeof testObj ect.method"));
578 } 661 }
579 662
663 @Test
580 @SmallTest 664 @SmallTest
581 @Feature({"AndroidWebView", "Android-JavaBridge"}) 665 @Feature({"AndroidWebView", "Android-JavaBridge"})
582 public void testOverriddenMethod() throws Throwable { 666 public void testOverriddenMethod() throws Throwable {
667 setUpHelper();
583 class Base { 668 class Base {
584 public void method() { 669 public void method() {
585 mTestController.setStringValue("base"); 670 mTestController.setStringValue("base");
586 } 671 }
587 } 672 }
588 class Derived extends Base { 673 class Derived extends Base {
589 @Override 674 @Override
590 public void method() { 675 public void method() {
591 mTestController.setStringValue("derived"); 676 mTestController.setStringValue("derived");
592 } 677 }
593 } 678 }
594 injectObjectAndReload(new Derived(), "testObject"); 679 mActivityTestRule.injectObjectAndReload(new Derived(), "testObject");
595 executeJavaScript("testObject.method()"); 680 mActivityTestRule.executeJavaScript("testObject.method()");
596 assertEquals("derived", mTestController.waitForStringValue()); 681 Assert.assertEquals("derived", mTestController.waitForStringValue());
597 } 682 }
598 683
684 @Test
599 @SmallTest 685 @SmallTest
600 @Feature({"AndroidWebView", "Android-JavaBridge"}) 686 @Feature({"AndroidWebView", "Android-JavaBridge"})
601 public void testEnumerateMembers() throws Throwable { 687 public void testEnumerateMembers() throws Throwable {
602 injectObjectAndReload(new Object() { 688 setUpHelper();
689 mActivityTestRule.injectObjectAndReload(new Object() {
603 public void method() {} 690 public void method() {}
604 private void privateMethod() {} 691 private void privateMethod() {}
605 @SuppressFBWarnings("UUF_UNUSED") 692 @SuppressFBWarnings("UUF_UNUSED")
606 public int field; 693 public int field;
607 @SuppressFBWarnings("UUF_UNUSED") 694 @SuppressFBWarnings("UUF_UNUSED")
608 private int mPrivateField; 695 private int mPrivateField;
609 }, "testObject"); 696 }, "testObject");
610 executeJavaScript( 697 mActivityTestRule.executeJavaScript("var result = \"\"; "
611 "var result = \"\"; "
612 + "for (x in testObject) { result += \" \" + x } " 698 + "for (x in testObject) { result += \" \" + x } "
613 + "testController.setStringValue(result);"); 699 + "testController.setStringValue(result);");
614 assertEquals(" equals getClass hashCode method notify notifyAll toString wait", 700 Assert.assertEquals(" equals getClass hashCode method notify notifyAll t oString wait",
615 mTestController.waitForStringValue()); 701 mTestController.waitForStringValue());
616 } 702 }
617 703
704 @Test
618 @SmallTest 705 @SmallTest
619 @Feature({"AndroidWebView", "Android-JavaBridge"}) 706 @Feature({"AndroidWebView", "Android-JavaBridge"})
620 public void testReflectPublicMethod() throws Throwable { 707 public void testReflectPublicMethod() throws Throwable {
621 injectObjectAndReload(new Object() { 708 setUpHelper();
709 mActivityTestRule.injectObjectAndReload(new Object() {
622 public Class<?> myGetClass() { 710 public Class<?> myGetClass() {
623 return getClass(); 711 return getClass();
624 } 712 }
625 713
626 public String method() { 714 public String method() {
627 return "foo"; 715 return "foo";
628 } 716 }
629 }, "testObject"); 717 }, "testObject");
630 assertEquals("foo", executeJavaScriptAndGetStringResult( 718 Assert.assertEquals("foo",
631 "testObject.myGetClass().getMethod('method', null).invoke(testOb ject, null)" 719 executeJavaScriptAndGetStringResult(
632 + ".toString()")); 720 "testObject.myGetClass().getMethod('method', null).invok e(testObject, null)"
721 + ".toString()"));
633 } 722 }
634 723
724 @Test
635 @SmallTest 725 @SmallTest
636 @Feature({"AndroidWebView", "Android-JavaBridge"}) 726 @Feature({"AndroidWebView", "Android-JavaBridge"})
637 public void testReflectPublicField() throws Throwable { 727 public void testReflectPublicField() throws Throwable {
638 injectObjectAndReload(new Object() { 728 setUpHelper();
729 mActivityTestRule.injectObjectAndReload(new Object() {
639 public Class<?> myGetClass() { 730 public Class<?> myGetClass() {
640 return getClass(); 731 return getClass();
641 } 732 }
642 733
643 public String field = "foo"; 734 public String field = "foo";
644 }, "testObject"); 735 }, "testObject");
645 assertEquals("foo", executeJavaScriptAndGetStringResult( 736 Assert.assertEquals("foo",
646 "testObject.myGetClass().getField('field').get(testObject).toStr ing()")); 737 executeJavaScriptAndGetStringResult(
738 "testObject.myGetClass().getField('field').get(testObjec t).toString()"));
647 } 739 }
648 740
741 @Test
649 @SmallTest 742 @SmallTest
650 @Feature({"AndroidWebView", "Android-JavaBridge"}) 743 @Feature({"AndroidWebView", "Android-JavaBridge"})
651 public void testReflectPrivateMethodRaisesException() throws Throwable { 744 public void testReflectPrivateMethodRaisesException() throws Throwable {
652 injectObjectAndReload(new Object() { 745 setUpHelper();
746 mActivityTestRule.injectObjectAndReload(new Object() {
653 public Class<?> myGetClass() { 747 public Class<?> myGetClass() {
654 return getClass(); 748 return getClass();
655 } 749 }
656 750
657 private void method() {}; 751 private void method() {};
658 }, "testObject"); 752 }, "testObject");
659 assertRaisesException("testObject.myGetClass().getMethod('method', null) "); 753 assertRaisesException("testObject.myGetClass().getMethod('method', null) ");
660 // getDeclaredMethod() is able to access a private method, but invoke() 754 // getDeclaredMethod() is able to access a private method, but invoke()
661 // throws a Java exception. 755 // throws a Java exception.
662 assertRaisesException( 756 assertRaisesException(
663 "testObject.myGetClass().getDeclaredMethod('method', null)." 757 "testObject.myGetClass().getDeclaredMethod('method', null)."
664 + "invoke(testObject, null)"); 758 + "invoke(testObject, null)");
665 } 759 }
666 760
761 @Test
667 @SmallTest 762 @SmallTest
668 @Feature({"AndroidWebView", "Android-JavaBridge"}) 763 @Feature({"AndroidWebView", "Android-JavaBridge"})
669 public void testReflectPrivateFieldRaisesException() throws Throwable { 764 public void testReflectPrivateFieldRaisesException() throws Throwable {
670 injectObjectAndReload(new Object() { 765 setUpHelper();
766 mActivityTestRule.injectObjectAndReload(new Object() {
671 public Class<?> myGetClass() { 767 public Class<?> myGetClass() {
672 return getClass(); 768 return getClass();
673 } 769 }
674 770
675 @SuppressFBWarnings("UUF_UNUSED") 771 @SuppressFBWarnings("UUF_UNUSED")
676 private int mField; 772 private int mField;
677 }, "testObject"); 773 }, "testObject");
678 String fieldName = "mField"; 774 String fieldName = "mField";
679 assertRaisesException("testObject.myGetClass().getField('" + fieldName + "')"); 775 assertRaisesException("testObject.myGetClass().getField('" + fieldName + "')");
680 // getDeclaredField() is able to access a private field, but getInt() 776 // getDeclaredField() is able to access a private field, but getInt()
681 // throws a Java exception. 777 // throws a Java exception.
682 assertNoRaisedException("testObject.myGetClass().getDeclaredField('" + f ieldName + "')"); 778 assertNoRaisedException("testObject.myGetClass().getDeclaredField('" + f ieldName + "')");
683 assertRaisesException( 779 assertRaisesException(
684 "testObject.myGetClass().getDeclaredField('" + fieldName + "').g etInt(testObject)"); 780 "testObject.myGetClass().getDeclaredField('" + fieldName + "').g etInt(testObject)");
685 } 781 }
686 782
783 @Test
687 @SmallTest 784 @SmallTest
688 @Feature({"AndroidWebView", "Android-JavaBridge"}) 785 @Feature({"AndroidWebView", "Android-JavaBridge"})
689 public void testAllowNonAnnotatedMethods() throws Throwable { 786 public void testAllowNonAnnotatedMethods() throws Throwable {
690 injectObjectAndReload(new Object() { 787 setUpHelper();
788 mActivityTestRule.injectObjectAndReload(new Object() {
691 public String allowed() { 789 public String allowed() {
692 return "foo"; 790 return "foo";
693 } 791 }
694 }, "testObject", null); 792 }, "testObject", null);
695 793
696 // Test calling a method of an explicitly inherited class (Base#allowed( )). 794 // Test calling a method of an explicitly inherited class (Base#allowed( )).
697 assertEquals("foo", executeJavaScriptAndGetStringResult("testObject.allo wed()")); 795 Assert.assertEquals("foo", executeJavaScriptAndGetStringResult("testObje ct.allowed()"));
698 796
699 // Test calling a method of an implicitly inherited class (Object#toStri ng()). 797 // Test calling a method of an implicitly inherited class (Object#toStri ng()).
700 assertEquals("string", executeJavaScriptAndGetStringResult("typeof testO bject.toString()")); 798 Assert.assertEquals(
799 "string", executeJavaScriptAndGetStringResult("typeof testObject .toString()"));
701 } 800 }
702 801
802 @Test
703 @SmallTest 803 @SmallTest
704 @Feature({"AndroidWebView", "Android-JavaBridge"}) 804 @Feature({"AndroidWebView", "Android-JavaBridge"})
705 public void testAllowOnlyAnnotatedMethods() throws Throwable { 805 public void testAllowOnlyAnnotatedMethods() throws Throwable {
706 injectObjectAndReload(new Object() { 806 setUpHelper();
807 mActivityTestRule.injectObjectAndReload(new Object() {
707 @JavascriptInterface 808 @JavascriptInterface
708 public String allowed() { 809 public String allowed() {
709 return "foo"; 810 return "foo";
710 } 811 }
711 812
712 public String disallowed() { 813 public String disallowed() {
713 return "bar"; 814 return "bar";
714 } 815 }
715 }, "testObject", JavascriptInterface.class); 816 }, "testObject", JavascriptInterface.class);
716 817
717 // getClass() is an Object method and does not have the @JavascriptInter face annotation and 818 // getClass() is an Object method and does not have the @JavascriptInter face annotation and
718 // should not be able to be called. 819 // should not be able to be called.
719 assertRaisesException("testObject.getClass()"); 820 assertRaisesException("testObject.getClass()");
720 assertEquals("undefined", executeJavaScriptAndGetStringResult( 821 Assert.assertEquals(
721 "typeof testObject.getClass")); 822 "undefined", executeJavaScriptAndGetStringResult("typeof testObj ect.getClass"));
722 823
723 // allowed() is marked with the @JavascriptInterface annotation and shou ld be allowed to be 824 // allowed() is marked with the @JavascriptInterface annotation and shou ld be allowed to be
724 // called. 825 // called.
725 assertEquals("foo", executeJavaScriptAndGetStringResult("testObject.allo wed()")); 826 Assert.assertEquals("foo", executeJavaScriptAndGetStringResult("testObje ct.allowed()"));
726 827
727 // disallowed() is not marked with the @JavascriptInterface annotation a nd should not be 828 // disallowed() is not marked with the @JavascriptInterface annotation a nd should not be
728 // able to be called. 829 // able to be called.
729 assertRaisesException("testObject.disallowed()"); 830 assertRaisesException("testObject.disallowed()");
730 assertEquals("undefined", executeJavaScriptAndGetStringResult( 831 Assert.assertEquals(
731 "typeof testObject.disallowed")); 832 "undefined", executeJavaScriptAndGetStringResult("typeof testObj ect.disallowed"));
732 } 833 }
733 834
835 @Test
734 @SmallTest 836 @SmallTest
735 @Feature({"AndroidWebView", "Android-JavaBridge"}) 837 @Feature({"AndroidWebView", "Android-JavaBridge"})
736 public void testAnnotationRequirementRetainsPropertyAcrossObjects() throws T hrowable { 838 public void testAnnotationRequirementRetainsPropertyAcrossObjects() throws T hrowable {
839 setUpHelper();
737 class Test { 840 class Test {
738 @JavascriptInterface 841 @JavascriptInterface
739 public String safe() { 842 public String safe() {
740 return "foo"; 843 return "foo";
741 } 844 }
742 845
743 public String unsafe() { 846 public String unsafe() {
744 return "bar"; 847 return "bar";
745 } 848 }
746 } 849 }
747 850
748 class TestReturner { 851 class TestReturner {
749 @JavascriptInterface 852 @JavascriptInterface
750 public Test getTest() { 853 public Test getTest() {
751 return new Test(); 854 return new Test();
752 } 855 }
753 } 856 }
754 857
755 // First test with safe mode off. 858 // First test with safe mode off.
756 injectObjectAndReload(new TestReturner(), "unsafeTestObject", null); 859 mActivityTestRule.injectObjectAndReload(new TestReturner(), "unsafeTestO bject", null);
757 860
758 // safe() should be able to be called regardless of whether or not we ar e in safe mode. 861 // safe() should be able to be called regardless of whether or not we ar e in safe mode.
759 assertEquals("foo", executeJavaScriptAndGetStringResult( 862 Assert.assertEquals(
760 "unsafeTestObject.getTest().safe()")); 863 "foo", executeJavaScriptAndGetStringResult("unsafeTestObject.get Test().safe()"));
761 // unsafe() should be able to be called because we are not in safe mode. 864 // unsafe() should be able to be called because we are not in safe mode.
762 assertEquals("bar", executeJavaScriptAndGetStringResult( 865 Assert.assertEquals(
763 "unsafeTestObject.getTest().unsafe()")); 866 "bar", executeJavaScriptAndGetStringResult("unsafeTestObject.get Test().unsafe()"));
764 867
765 // Now test with safe mode on. 868 // Now test with safe mode on.
766 injectObjectAndReload(new TestReturner(), "safeTestObject", JavascriptIn terface.class); 869 mActivityTestRule.injectObjectAndReload(
870 new TestReturner(), "safeTestObject", JavascriptInterface.class) ;
767 871
768 // safe() should be able to be called regardless of whether or not we ar e in safe mode. 872 // safe() should be able to be called regardless of whether or not we ar e in safe mode.
769 assertEquals("foo", executeJavaScriptAndGetStringResult( 873 Assert.assertEquals(
770 "safeTestObject.getTest().safe()")); 874 "foo", executeJavaScriptAndGetStringResult("safeTestObject.getTe st().safe()"));
771 // unsafe() should not be able to be called because we are in safe mode. 875 // unsafe() should not be able to be called because we are in safe mode.
772 assertRaisesException("safeTestObject.getTest().unsafe()"); 876 assertRaisesException("safeTestObject.getTest().unsafe()");
773 assertEquals("undefined", executeJavaScriptAndGetStringResult( 877 Assert.assertEquals("undefined",
774 "typeof safeTestObject.getTest().unsafe")); 878 executeJavaScriptAndGetStringResult("typeof safeTestObject.getTe st().unsafe"));
775 // getClass() is an Object method and does not have the @JavascriptInter face annotation and 879 // getClass() is an Object method and does not have the @JavascriptInter face annotation and
776 // should not be able to be called. 880 // should not be able to be called.
777 assertRaisesException("safeTestObject.getTest().getClass()"); 881 assertRaisesException("safeTestObject.getTest().getClass()");
778 assertEquals("undefined", executeJavaScriptAndGetStringResult( 882 Assert.assertEquals("undefined",
779 "typeof safeTestObject.getTest().getClass")); 883 executeJavaScriptAndGetStringResult("typeof safeTestObject.getTe st().getClass"));
780 } 884 }
781 885
886 @Test
782 @SmallTest 887 @SmallTest
783 @Feature({"AndroidWebView", "Android-JavaBridge"}) 888 @Feature({"AndroidWebView", "Android-JavaBridge"})
784 public void testAnnotationDoesNotGetInherited() throws Throwable { 889 public void testAnnotationDoesNotGetInherited() throws Throwable {
890 setUpHelper();
785 class Base { 891 class Base {
786 @JavascriptInterface 892 @JavascriptInterface
787 public void base() { } 893 public void base() { }
788 } 894 }
789 895
790 class Child extends Base { 896 class Child extends Base {
791 @Override 897 @Override
792 public void base() { } 898 public void base() { }
793 } 899 }
794 900
795 injectObjectAndReload(new Child(), "testObject", JavascriptInterface.cla ss); 901 mActivityTestRule.injectObjectAndReload(
902 new Child(), "testObject", JavascriptInterface.class);
796 903
797 // base() is inherited. The inherited method does not have the @Javascr iptInterface 904 // base() is inherited. The inherited method does not have the @Javascr iptInterface
798 // annotation and should not be able to be called. 905 // annotation and should not be able to be called.
799 assertRaisesException("testObject.base()"); 906 assertRaisesException("testObject.base()");
800 assertEquals("undefined", executeJavaScriptAndGetStringResult( 907 Assert.assertEquals(
801 "typeof testObject.base")); 908 "undefined", executeJavaScriptAndGetStringResult("typeof testObj ect.base"));
802 } 909 }
803 910
804 @SuppressWarnings("javadoc") 911 @SuppressWarnings("javadoc")
805 @Retention(RetentionPolicy.RUNTIME) 912 @Retention(RetentionPolicy.RUNTIME)
806 @Target({ElementType.METHOD}) 913 @Target({ElementType.METHOD})
807 @interface TestAnnotation { 914 @interface TestAnnotation {
808 } 915 }
809 916
917 @Test
810 @SmallTest 918 @SmallTest
811 @Feature({"AndroidWebView", "Android-JavaBridge"}) 919 @Feature({"AndroidWebView", "Android-JavaBridge"})
812 public void testCustomAnnotationRestriction() throws Throwable { 920 public void testCustomAnnotationRestriction() throws Throwable {
921 setUpHelper();
813 class Test { 922 class Test {
814 @TestAnnotation 923 @TestAnnotation
815 public String checkTestAnnotationFoo() { 924 public String checkTestAnnotationFoo() {
816 return "bar"; 925 return "bar";
817 } 926 }
818 927
819 @JavascriptInterface 928 @JavascriptInterface
820 public String checkJavascriptInterfaceFoo() { 929 public String checkJavascriptInterfaceFoo() {
821 return "bar"; 930 return "bar";
822 } 931 }
823 } 932 }
824 933
825 // Inject javascriptInterfaceObj and require the JavascriptInterface ann otation. 934 // Inject javascriptInterfaceObj and require the JavascriptInterface ann otation.
826 injectObjectAndReload(new Test(), "javascriptInterfaceObj", JavascriptIn terface.class); 935 mActivityTestRule.injectObjectAndReload(
936 new Test(), "javascriptInterfaceObj", JavascriptInterface.class) ;
827 937
828 // Test#testAnnotationFoo() should fail, as it isn't annotated with Java scriptInterface. 938 // Test#testAnnotationFoo() should fail, as it isn't annotated with Java scriptInterface.
829 assertRaisesException("javascriptInterfaceObj.checkTestAnnotationFoo()") ; 939 assertRaisesException("javascriptInterfaceObj.checkTestAnnotationFoo()") ;
830 assertEquals("undefined", executeJavaScriptAndGetStringResult( 940 Assert.assertEquals("undefined",
831 "typeof javascriptInterfaceObj.checkTestAnnotationFoo")); 941 executeJavaScriptAndGetStringResult(
942 "typeof javascriptInterfaceObj.checkTestAnnotationFoo")) ;
832 943
833 // Test#javascriptInterfaceFoo() should pass, as it is annotated with Ja vascriptInterface. 944 // Test#javascriptInterfaceFoo() should pass, as it is annotated with Ja vascriptInterface.
834 assertEquals("bar", executeJavaScriptAndGetStringResult( 945 Assert.assertEquals("bar",
835 "javascriptInterfaceObj.checkJavascriptInterfaceFoo()")); 946 executeJavaScriptAndGetStringResult(
947 "javascriptInterfaceObj.checkJavascriptInterfaceFoo()")) ;
836 948
837 // Inject testAnnotationObj and require the TestAnnotation annotation. 949 // Inject testAnnotationObj and require the TestAnnotation annotation.
838 injectObjectAndReload(new Test(), "testAnnotationObj", TestAnnotation.cl ass); 950 mActivityTestRule.injectObjectAndReload(
951 new Test(), "testAnnotationObj", TestAnnotation.class);
839 952
840 // Test#testAnnotationFoo() should pass, as it is annotated with TestAnn otation. 953 // Test#testAnnotationFoo() should pass, as it is annotated with TestAnn otation.
841 assertEquals("bar", executeJavaScriptAndGetStringResult( 954 Assert.assertEquals("bar",
842 "testAnnotationObj.checkTestAnnotationFoo()")); 955 executeJavaScriptAndGetStringResult("testAnnotationObj.checkTest AnnotationFoo()"));
843 956
844 // Test#javascriptInterfaceFoo() should fail, as it isn't annotated with TestAnnotation. 957 // Test#javascriptInterfaceFoo() should fail, as it isn't annotated with TestAnnotation.
845 assertRaisesException("testAnnotationObj.checkJavascriptInterfaceFoo()") ; 958 assertRaisesException("testAnnotationObj.checkJavascriptInterfaceFoo()") ;
846 assertEquals("undefined", executeJavaScriptAndGetStringResult( 959 Assert.assertEquals("undefined",
847 "typeof testAnnotationObj.checkJavascriptInterfaceFoo")); 960 executeJavaScriptAndGetStringResult(
961 "typeof testAnnotationObj.checkJavascriptInterfaceFoo")) ;
848 } 962 }
849 963
964 @Test
850 @SmallTest 965 @SmallTest
851 @Feature({"AndroidWebView", "Android-JavaBridge"}) 966 @Feature({"AndroidWebView", "Android-JavaBridge"})
852 public void testAddJavascriptInterfaceIsSafeByDefault() throws Throwable { 967 public void testAddJavascriptInterfaceIsSafeByDefault() throws Throwable {
968 setUpHelper();
853 class Test { 969 class Test {
854 public String blocked() { 970 public String blocked() {
855 return "bar"; 971 return "bar";
856 } 972 }
857 973
858 @JavascriptInterface 974 @JavascriptInterface
859 public String allowed() { 975 public String allowed() {
860 return "bar"; 976 return "bar";
861 } 977 }
862 } 978 }
863 979
864 // Manually inject the Test object, making sure to use the 980 // Manually inject the Test object, making sure to use the
865 // ContentViewCore#addJavascriptInterface, not the possibly unsafe versi on. 981 // ContentViewCore#addJavascriptInterface, not the possibly unsafe versi on.
866 TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper = 982 TestCallbackHelperContainer.OnPageFinishedHelper onPageFinishedHelper =
867 getTestCallBackHelperContainer().getOnPageFinishedHelper(); 983 mActivityTestRule.getTestCallBackHelperContainer().getOnPageFini shedHelper();
868 int currentCallCount = onPageFinishedHelper.getCallCount(); 984 int currentCallCount = onPageFinishedHelper.getCallCount();
869 runTestOnUiThread(new Runnable() { 985 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable( ) {
870 @Override 986 @Override
871 public void run() { 987 public void run() {
872 getContentViewCore().addJavascriptInterface(new Test(), 988 mActivityTestRule.getContentViewCore().addJavascriptInterface(
873 "testObject"); 989 new Test(), "testObject");
874 getContentViewCore().getWebContents().getNavigationController(). reload(true); 990 mActivityTestRule.getContentViewCore()
991 .getWebContents()
992 .getNavigationController()
993 .reload(true);
875 } 994 }
876 }); 995 });
877 onPageFinishedHelper.waitForCallback(currentCallCount); 996 onPageFinishedHelper.waitForCallback(currentCallCount);
878 997
879 // Test#allowed() should pass, as it is annotated with JavascriptInterfa ce. 998 // Test#allowed() should pass, as it is annotated with JavascriptInterfa ce.
880 assertEquals("bar", executeJavaScriptAndGetStringResult( 999 Assert.assertEquals("bar", executeJavaScriptAndGetStringResult("testObje ct.allowed()"));
881 "testObject.allowed()"));
882 1000
883 // Test#blocked() should fail, as it isn't annotated with JavascriptInte rface. 1001 // Test#blocked() should fail, as it isn't annotated with JavascriptInte rface.
884 assertRaisesException("testObject.blocked()"); 1002 assertRaisesException("testObject.blocked()");
885 assertEquals("undefined", executeJavaScriptAndGetStringResult( 1003 Assert.assertEquals(
886 "typeof testObject.blocked")); 1004 "undefined", executeJavaScriptAndGetStringResult("typeof testObj ect.blocked"));
887 } 1005 }
888 1006
1007 @Test
889 @SmallTest 1008 @SmallTest
890 @Feature({"AndroidWebView", "Android-JavaBridge"}) 1009 @Feature({"AndroidWebView", "Android-JavaBridge"})
891 public void testObjectsInspection() throws Throwable { 1010 public void testObjectsInspection() throws Throwable {
1011 setUpHelper();
892 class Test { 1012 class Test {
893 @JavascriptInterface 1013 @JavascriptInterface
894 public String m1() { 1014 public String m1() {
895 return "foo"; 1015 return "foo";
896 } 1016 }
897 1017
898 @JavascriptInterface 1018 @JavascriptInterface
899 public String m2() { 1019 public String m2() {
900 return "bar"; 1020 return "bar";
901 } 1021 }
902 1022
903 @JavascriptInterface 1023 @JavascriptInterface
904 public String m2(int x) { 1024 public String m2(int x) {
905 return "bar " + x; 1025 return "bar " + x;
906 } 1026 }
907 } 1027 }
908 1028
909 final String jsObjectKeysTestTemplate = "Object.keys(%s).toString()"; 1029 final String jsObjectKeysTestTemplate = "Object.keys(%s).toString()";
910 final String jsForInTestTemplate = 1030 final String jsForInTestTemplate =
911 "(function(){" 1031 "(function(){"
912 + " var s=[]; for(var m in %s) s.push(m); return s.join(\",\")" 1032 + " var s=[]; for(var m in %s) s.push(m); return s.join(\",\")"
913 + "})()"; 1033 + "})()";
914 final String inspectableObjectName = "testObj1"; 1034 final String inspectableObjectName = "testObj1";
915 final String nonInspectableObjectName = "testObj2"; 1035 final String nonInspectableObjectName = "testObj2";
916 1036
917 // Inspection is enabled by default. 1037 // Inspection is enabled by default.
918 injectObjectAndReload(new Test(), inspectableObjectName, JavascriptInter face.class); 1038 mActivityTestRule.injectObjectAndReload(
1039 new Test(), inspectableObjectName, JavascriptInterface.class);
919 1040
920 assertEquals("m1,m2", executeJavaScriptAndGetStringResult( 1041 Assert.assertEquals("m1,m2",
1042 executeJavaScriptAndGetStringResult(
921 String.format(jsObjectKeysTestTemplate, inspectableObjec tName))); 1043 String.format(jsObjectKeysTestTemplate, inspectableObjec tName)));
922 assertEquals("m1,m2", executeJavaScriptAndGetStringResult( 1044 Assert.assertEquals("m1,m2",
1045 executeJavaScriptAndGetStringResult(
923 String.format(jsForInTestTemplate, inspectableObjectName ))); 1046 String.format(jsForInTestTemplate, inspectableObjectName )));
924 1047
925 runTestOnUiThread(new Runnable() { 1048 InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable( ) {
926 @Override 1049 @Override
927 public void run() { 1050 public void run() {
928 getContentViewCore().setAllowJavascriptInterfacesInspection(fals e); 1051 mActivityTestRule.getContentViewCore().setAllowJavascriptInterfa cesInspection(
1052 false);
929 } 1053 }
930 }); 1054 });
931 1055
932 injectObjectAndReload(new Test(), nonInspectableObjectName, JavascriptIn terface.class); 1056 mActivityTestRule.injectObjectAndReload(
1057 new Test(), nonInspectableObjectName, JavascriptInterface.class) ;
933 1058
934 assertEquals("", executeJavaScriptAndGetStringResult( 1059 Assert.assertEquals("",
1060 executeJavaScriptAndGetStringResult(
935 String.format(jsObjectKeysTestTemplate, nonInspectableOb jectName))); 1061 String.format(jsObjectKeysTestTemplate, nonInspectableOb jectName)));
936 assertEquals("", executeJavaScriptAndGetStringResult( 1062 Assert.assertEquals("",
1063 executeJavaScriptAndGetStringResult(
937 String.format(jsForInTestTemplate, nonInspectableObjectN ame))); 1064 String.format(jsForInTestTemplate, nonInspectableObjectN ame)));
938 } 1065 }
939 1066
1067 @Test
940 @SmallTest 1068 @SmallTest
941 @Feature({"AndroidWebView", "Android-JavaBridge"}) 1069 @Feature({"AndroidWebView", "Android-JavaBridge"})
942 public void testAccessToObjectGetClassIsBlocked() throws Throwable { 1070 public void testAccessToObjectGetClassIsBlocked() throws Throwable {
943 injectObjectAndReload(new Object(), "testObject"); 1071 setUpHelper();
944 assertEquals("function", executeJavaScriptAndGetStringResult("typeof tes tObject.getClass")); 1072 mActivityTestRule.injectObjectAndReload(new Object(), "testObject");
1073 Assert.assertEquals(
1074 "function", executeJavaScriptAndGetStringResult("typeof testObje ct.getClass"));
945 assertRaisesException("testObject.getClass()"); 1075 assertRaisesException("testObject.getClass()");
946 } 1076 }
947 1077
1078 @Test
948 @SmallTest 1079 @SmallTest
949 @Feature({"AndroidWebView", "Android-JavaBridge"}) 1080 @Feature({"AndroidWebView", "Android-JavaBridge"})
950 public void testReplaceJavascriptInterface() throws Throwable { 1081 public void testReplaceJavascriptInterface() throws Throwable {
1082 setUpHelper();
951 class Test { 1083 class Test {
952 public Test(int value) { 1084 public Test(int value) {
953 mValue = value; 1085 mValue = value;
954 } 1086 }
955 @JavascriptInterface 1087 @JavascriptInterface
956 public int getValue() { 1088 public int getValue() {
957 return mValue; 1089 return mValue;
958 } 1090 }
959 private int mValue; 1091 private int mValue;
960 } 1092 }
961 injectObjectAndReload(new Test(13), "testObject"); 1093 mActivityTestRule.injectObjectAndReload(new Test(13), "testObject");
962 assertEquals("13", executeJavaScriptAndGetStringResult("testObject.getVa lue()")); 1094 Assert.assertEquals("13", executeJavaScriptAndGetStringResult("testObjec t.getValue()"));
963 // The documentation doesn't specify, what happens if the embedder is tr ying 1095 // The documentation doesn't specify, what happens if the embedder is tr ying
964 // to inject a different object under the same name. The current impleme ntation 1096 // to inject a different object under the same name. The current impleme ntation
965 // simply replaces the old object with the new one. 1097 // simply replaces the old object with the new one.
966 injectObjectAndReload(new Test(42), "testObject"); 1098 mActivityTestRule.injectObjectAndReload(new Test(42), "testObject");
967 assertEquals("42", executeJavaScriptAndGetStringResult("testObject.getVa lue()")); 1099 Assert.assertEquals("42", executeJavaScriptAndGetStringResult("testObjec t.getValue()"));
968 } 1100 }
969 1101
1102 @Test
970 @SmallTest 1103 @SmallTest
971 @Feature({"AndroidWebView", "Android-JavaBridge"}) 1104 @Feature({"AndroidWebView", "Android-JavaBridge"})
972 public void testMethodCalledOnAnotherInstance() throws Throwable { 1105 public void testMethodCalledOnAnotherInstance() throws Throwable {
1106 setUpHelper();
973 class TestObject { 1107 class TestObject {
974 private int mIndex; 1108 private int mIndex;
975 TestObject(int index) { 1109 TestObject(int index) {
976 mIndex = index; 1110 mIndex = index;
977 } 1111 }
978 public void method() { 1112 public void method() {
979 mTestController.setIntValue(mIndex); 1113 mTestController.setIntValue(mIndex);
980 } 1114 }
981 } 1115 }
982 final TestObject testObject1 = new TestObject(1); 1116 final TestObject testObject1 = new TestObject(1);
983 final TestObject testObject2 = new TestObject(2); 1117 final TestObject testObject2 = new TestObject(2);
984 injectObjectsAndReload(testObject1, "testObject1", testObject2, "testObj ect2", null); 1118 mActivityTestRule.injectObjectsAndReload(
985 executeJavaScript("testObject1.method()"); 1119 testObject1, "testObject1", testObject2, "testObject2", null);
986 assertEquals(1, mTestController.waitForIntValue()); 1120 mActivityTestRule.executeJavaScript("testObject1.method()");
987 executeJavaScript("testObject2.method()"); 1121 Assert.assertEquals(1, mTestController.waitForIntValue());
988 assertEquals(2, mTestController.waitForIntValue()); 1122 mActivityTestRule.executeJavaScript("testObject2.method()");
989 executeJavaScript("testObject1.method.call(testObject2)"); 1123 Assert.assertEquals(2, mTestController.waitForIntValue());
990 assertEquals(2, mTestController.waitForIntValue()); 1124 mActivityTestRule.executeJavaScript("testObject1.method.call(testObject2 )");
991 executeJavaScript("testObject2.method.call(testObject1)"); 1125 Assert.assertEquals(2, mTestController.waitForIntValue());
992 assertEquals(1, mTestController.waitForIntValue()); 1126 mActivityTestRule.executeJavaScript("testObject2.method.call(testObject1 )");
1127 Assert.assertEquals(1, mTestController.waitForIntValue());
993 } 1128 }
994 } 1129 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698