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
3 // found in the LICENSE file.
5 package org.chromium.content.browser;
7 import android.test.suitebuilder.annotation.SmallTest;
9 import org.chromium.base.test.util.Feature;
12 * Part of the test suite for the WebView's Java Bridge.
14 * Ensures that injected objects are exposed to child frames as well as the
17 public class JavaBridgeChildFrameTest extends JavaBridgeTestBase {
18 private class TestController extends Controller {
19 private String mStringValue;
21 @SuppressWarnings("unused") // Called via reflection
22 public synchronized void setStringValue(String x) {
24 notifyResultIsReady();
26 public synchronized String waitForStringValue() {
32 TestController mTestController;
35 protected void setUp() throws Exception {
37 mTestController = new TestController();
38 setUpContentView(mTestController, "testController");
42 @Feature({"AndroidWebView", "Android-JavaBridge"})
43 public void testInjectedObjectPresentInChildFrame() throws Throwable {
44 loadDataSync(getContentViewCore(),
45 "<html><body><iframe></iframe></body></html>", "text/html", false);
46 // We are not executing this code as a part of page loading routine to avoid races
47 // with internal Blink events that notify Java Bridge about window object updates.
48 assertEquals("\"object\"", executeJavaScriptAndGetResult(
49 getContentViewCore(), "typeof window.frames[0].testController"));
50 executeJavaScriptAndGetResult(
51 getContentViewCore(), "window.frames[0].testController.setStringValue('PASS')");
52 assertEquals("PASS", mTestController.waitForStringValue());
55 // Verify that loading an iframe doesn't ruin JS wrapper of the main page.
56 // This is a regression test for the problem described in b/15572824.
58 @Feature({"AndroidWebView", "Android-JavaBridge"})
59 public void testMainPageWrapperIsNotBrokenByChildFrame() throws Throwable {
60 loadDataSync(getContentViewCore(),
61 "<html><body><iframe></iframe></body></html>", "text/html", false);
62 // In case there is anything wrong with the JS wrapper, an attempt
63 // to look up its properties will result in an exception being thrown.
65 "(function(){ try {" +
66 " return typeof testController.setStringValue;" +
68 " return e.toString();" +
70 assertEquals("\"function\"",
71 executeJavaScriptAndGetResult(getContentViewCore(), script));
72 // Make sure calling a method also works.
73 executeJavaScriptAndGetResult(getContentViewCore(),
74 "testController.setStringValue('PASS');");
75 assertEquals("PASS", mTestController.waitForStringValue());
78 // Verify that parent page and child frame each has own JS wrapper object.
79 // Failing to do so exposes parent's context to the child.
81 @Feature({"AndroidWebView", "Android-JavaBridge"})
82 public void testWrapperIsNotSharedWithChildFrame() throws Throwable {
83 // Test by setting a custom property on the parent page's injected
84 // object and then checking that child frame doesn't see the property.
85 loadDataSync(getContentViewCore(),
88 " window.wProperty = 42;" +
89 " testController.tcProperty = 42;" +
90 " function queryProperties(w) {" +
91 " return w.wProperty + ' / ' + w.testController.tcProperty;" +
94 "</head><body><iframe></iframe></body></html>", "text/html", false);
95 assertEquals("\"42 / 42\"",
96 executeJavaScriptAndGetResult(getContentViewCore(), "queryProperties(window)"));
97 assertEquals("\"undefined / undefined\"",
98 executeJavaScriptAndGetResult(getContentViewCore(),
99 "queryProperties(window.frames[0])"));
102 private String executeJavaScriptAndGetResult(final ContentViewCore contentViewCore,
103 final String script) throws Throwable {
104 final String[] result = new String[1];
105 class ResultCallback extends JavaBridgeTestBase.Controller
106 implements ContentViewCore.JavaScriptCallback {
108 public void handleJavaScriptResult(String jsonResult) {
109 result[0] = jsonResult;
110 notifyResultIsReady();
113 final ResultCallback resultCallback = new ResultCallback();
114 runTestOnUiThread(new Runnable() {
117 contentViewCore.evaluateJavaScript(script, resultCallback);
120 resultCallback.waitForResult();