1d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block/* 2d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block * Copyright (C) 2011 The Android Open Source Project 3d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block * 4d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block * Licensed under the Apache License, Version 2.0 (the "License"); 5d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block * you may not use this file except in compliance with the License. 6d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block * You may obtain a copy of the License at 7d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block * 8d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block * http://www.apache.org/licenses/LICENSE-2.0 9d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block * 10d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block * Unless required by applicable law or agreed to in writing, software 11d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block * distributed under the License is distributed on an "AS IS" BASIS, 12d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block * See the License for the specific language governing permissions and 14d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block * limitations under the License. 15d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block */ 16d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block 17d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block/** 18d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block * Common functionality for testing the WebView's Java Bridge. 19d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block */ 20d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block 21d100cdbcc8033e59c405e0ce6855e81778f29132Steve Blockpackage com.android.webviewtests; 22d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block 23d100cdbcc8033e59c405e0ce6855e81778f29132Steve Blockimport android.test.ActivityInstrumentationTestCase2; 24d100cdbcc8033e59c405e0ce6855e81778f29132Steve Blockimport android.util.Log; 25d100cdbcc8033e59c405e0ce6855e81778f29132Steve Blockimport android.webkit.WebView; 26d100cdbcc8033e59c405e0ce6855e81778f29132Steve Blockimport android.webkit.WebViewClient; 27d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block 28d100cdbcc8033e59c405e0ce6855e81778f29132Steve Blockimport junit.framework.Assert; 29d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block 30d100cdbcc8033e59c405e0ce6855e81778f29132Steve Blockpublic class JavaBridgeTestBase extends ActivityInstrumentationTestCase2<WebViewStubActivity> { 31f7e26448c3591989840efa65f4f3f93a294b991eSteve Block protected class TestWebViewClient extends WebViewClient { 32d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block private boolean mIsPageFinished; 33d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block @Override 34d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block public synchronized void onPageFinished(WebView webView, String url) { 35d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block mIsPageFinished = true; 36d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block notify(); 37d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block } 38d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block public synchronized void waitForOnPageFinished() throws RuntimeException { 39d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block while (!mIsPageFinished) { 40d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block try { 41d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block wait(5000); 42d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block } catch (Exception e) { 43d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block continue; 44d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block } 45d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block if (!mIsPageFinished) { 46d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block throw new RuntimeException("Timed out waiting for onPageFinished()"); 47d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block } 48d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block } 49d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block mIsPageFinished = false; 50d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block } 51d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block } 52d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block 53d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block protected class Controller { 54d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block private boolean mIsResultReady; 55d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block 56d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block protected synchronized void notifyResultIsReady() { 57d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block mIsResultReady = true; 58d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block notify(); 59d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block } 60d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block protected synchronized void waitForResult() { 61d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block while (!mIsResultReady) { 62d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block try { 63d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block wait(5000); 64d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block } catch (Exception e) { 65d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block continue; 66d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block } 67d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block if (!mIsResultReady) { 68d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block Assert.fail("Wait timed out"); 69d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block } 70d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block } 71d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block mIsResultReady = false; 72d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block } 73d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block } 74d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block 75f7e26448c3591989840efa65f4f3f93a294b991eSteve Block protected TestWebViewClient mWebViewClient; 76d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block 77d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block public JavaBridgeTestBase() { 78d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block super(WebViewStubActivity.class); 79d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block } 80d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block 81d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block // Sets up the WebView and injects the supplied object. Intended to be called from setUp(). 82d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block protected void setUpWebView(final Object object, final String name) throws Exception { 83d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block mWebViewClient = new TestWebViewClient(); 84d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block // This starts the activity, so must be called on the test thread. 85d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block final WebViewStubActivity activity = getActivity(); 86d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block // On the UI thread, load an empty page and wait for it to finish 87d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block // loading so that the Java object is injected. 88d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block try { 89d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block runTestOnUiThread(new Runnable() { 90d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block @Override 91d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block public void run() { 92d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block WebView webView = activity.getWebView(); 93d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block webView.addJavascriptInterface(object, name); 94d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block webView.getSettings().setJavaScriptEnabled(true); 95d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block webView.setWebViewClient(mWebViewClient); 9647538c081d2900d6e6bbf58da69a3173287cc73fSteve Block webView.loadData("<!DOCTYPE html><title></title>", "text/html", null); 97d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block } 98d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block }); 99d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block mWebViewClient.waitForOnPageFinished(); 100d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block } catch (Throwable e) { 101d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block throw new RuntimeException("Failed to set up WebView: " + Log.getStackTraceString(e)); 102d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block } 103d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block } 104d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block 105d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block protected void executeJavaScript(final String script) throws Throwable { 106d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block runTestOnUiThread(new Runnable() { 107d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block @Override 108d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block public void run() { 109830698b1d94fc7215bd7a8ec50f884141a29212fSteve Block // When a JavaScript URL is executed, if the value of the last 110830698b1d94fc7215bd7a8ec50f884141a29212fSteve Block // expression evaluated is not 'undefined', this value is 111830698b1d94fc7215bd7a8ec50f884141a29212fSteve Block // converted to a string and used as the new document for the 112830698b1d94fc7215bd7a8ec50f884141a29212fSteve Block // frame. We don't want this behaviour, so wrap the script in 113830698b1d94fc7215bd7a8ec50f884141a29212fSteve Block // an anonymous function. 114830698b1d94fc7215bd7a8ec50f884141a29212fSteve Block getWebView().loadUrl("javascript:(function() { " + script + " })()"); 115d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block } 116d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block }); 117d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block } 118f7e26448c3591989840efa65f4f3f93a294b991eSteve Block 119f7e26448c3591989840efa65f4f3f93a294b991eSteve Block protected WebView getWebView() { 120f7e26448c3591989840efa65f4f3f93a294b991eSteve Block return getActivity().getWebView(); 121f7e26448c3591989840efa65f4f3f93a294b991eSteve Block } 122d100cdbcc8033e59c405e0ce6855e81778f29132Steve Block} 123