Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.webkit.cts;
     18 
     19 import android.cts.util.PollingCheck;
     20 import android.graphics.Bitmap;
     21 import android.os.Message;
     22 import android.test.ActivityInstrumentationTestCase2;
     23 import android.view.ViewGroup;
     24 import android.webkit.JsPromptResult;
     25 import android.webkit.JsResult;
     26 import android.webkit.WebIconDatabase;
     27 import android.webkit.WebSettings;
     28 import android.webkit.WebView;
     29 import android.webkit.cts.WebViewOnUiThread.WaitForProgressClient;
     30 
     31 public class WebChromeClientTest extends ActivityInstrumentationTestCase2<WebViewStubActivity> {
     32     private static final long TEST_TIMEOUT = 5000L;
     33 
     34     private CtsTestServer mWebServer;
     35     private WebIconDatabase mIconDb;
     36     private WebViewOnUiThread mOnUiThread;
     37     private boolean mBlockWindowCreationSync;
     38     private boolean mBlockWindowCreationAsync;
     39 
     40     public WebChromeClientTest() {
     41         super(WebViewStubActivity.class);
     42     }
     43 
     44     @Override
     45     protected void setUp() throws Exception {
     46         super.setUp();
     47         mOnUiThread = new WebViewOnUiThread(this, getActivity().getWebView());
     48         mWebServer = new CtsTestServer(getActivity());
     49     }
     50 
     51     @Override
     52     protected void tearDown() throws Exception {
     53         mOnUiThread.cleanUp();
     54         if (mWebServer != null) {
     55             mWebServer.shutdown();
     56         }
     57         if (mIconDb != null) {
     58             mIconDb.removeAllIcons();
     59             mIconDb.close();
     60         }
     61         super.tearDown();
     62     }
     63 
     64     public void testOnProgressChanged() {
     65         final MockWebChromeClient webChromeClient = new MockWebChromeClient();
     66         mOnUiThread.setWebChromeClient(webChromeClient);
     67 
     68         assertFalse(webChromeClient.hadOnProgressChanged());
     69         String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
     70         mOnUiThread.loadUrlAndWaitForCompletion(url);
     71 
     72         new PollingCheck(TEST_TIMEOUT) {
     73             @Override
     74             protected boolean check() {
     75                 return webChromeClient.hadOnProgressChanged();
     76             }
     77         }.run();
     78     }
     79 
     80     public void testOnReceivedTitle() throws Exception {
     81         final MockWebChromeClient webChromeClient = new MockWebChromeClient();
     82         mOnUiThread.setWebChromeClient(webChromeClient);
     83 
     84         assertFalse(webChromeClient.hadOnReceivedTitle());
     85         String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
     86         mOnUiThread.loadUrlAndWaitForCompletion(url);
     87 
     88         new PollingCheck(TEST_TIMEOUT) {
     89             @Override
     90             protected boolean check() {
     91                 return webChromeClient.hadOnReceivedTitle();
     92             }
     93         }.run();
     94         assertTrue(webChromeClient.hadOnReceivedTitle());
     95         assertEquals(TestHtmlConstants.HELLO_WORLD_TITLE, webChromeClient.getPageTitle());
     96     }
     97 
     98     public void testOnReceivedIcon() throws Throwable {
     99         final MockWebChromeClient webChromeClient = new MockWebChromeClient();
    100         mOnUiThread.setWebChromeClient(webChromeClient);
    101 
    102         runTestOnUiThread(new Runnable() {
    103             @Override
    104             public void run() {
    105                 // getInstance must run on the UI thread
    106                 mIconDb = WebIconDatabase.getInstance();
    107                 String dbPath = getActivity().getFilesDir().toString() + "/icons";
    108                 mIconDb.open(dbPath);
    109             }
    110         });
    111         getInstrumentation().waitForIdleSync();
    112         Thread.sleep(100); // Wait for open to be received on the icon db thread.
    113 
    114         assertFalse(webChromeClient.hadOnReceivedIcon());
    115 
    116         String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
    117         mOnUiThread.loadUrlAndWaitForCompletion(url);
    118 
    119         new PollingCheck(TEST_TIMEOUT) {
    120             @Override
    121             protected boolean check() {
    122                 return webChromeClient.hadOnReceivedIcon();
    123             }
    124         }.run();
    125     }
    126 
    127     public void runWindowTest(boolean expectWindowClose) throws Exception {
    128         final MockWebChromeClient webChromeClient = new MockWebChromeClient();
    129         mOnUiThread.setWebChromeClient(webChromeClient);
    130 
    131         final WebSettings settings = mOnUiThread.getSettings();
    132         settings.setJavaScriptEnabled(true);
    133         settings.setJavaScriptCanOpenWindowsAutomatically(true);
    134         settings.setSupportMultipleWindows(true);
    135 
    136         assertFalse(webChromeClient.hadOnCreateWindow());
    137 
    138         // Load a page that opens a child window and sets a timeout after which the child
    139         // will be closed.
    140         mOnUiThread.loadUrlAndWaitForCompletion(mWebServer.
    141                 getAssetUrl(TestHtmlConstants.JS_WINDOW_URL));
    142 
    143         new PollingCheck(TEST_TIMEOUT) {
    144             @Override
    145             protected boolean check() {
    146                 return webChromeClient.hadOnCreateWindow();
    147             }
    148         }.run();
    149 
    150         if (expectWindowClose) {
    151             new PollingCheck(TEST_TIMEOUT) {
    152                 @Override
    153                 protected boolean check() {
    154                     return webChromeClient.hadOnCloseWindow();
    155                 }
    156             }.run();
    157         } else {
    158             assertFalse(webChromeClient.hadOnCloseWindow());
    159         }
    160     }
    161     public void testWindows() throws Exception {
    162         runWindowTest(true);
    163     }
    164 
    165     public void testBlockWindowsSync() throws Exception {
    166         mBlockWindowCreationSync = true;
    167         runWindowTest(false);
    168     }
    169 
    170     public void testBlockWindowsAsync() throws Exception {
    171         mBlockWindowCreationAsync = true;
    172         runWindowTest(false);
    173     }
    174 
    175     public void testOnJsBeforeUnload() throws Exception {
    176         final MockWebChromeClient webChromeClient = new MockWebChromeClient();
    177         mOnUiThread.setWebChromeClient(webChromeClient);
    178 
    179         final WebSettings settings = mOnUiThread.getSettings();
    180         settings.setJavaScriptEnabled(true);
    181         settings.setJavaScriptCanOpenWindowsAutomatically(true);
    182 
    183         assertFalse(webChromeClient.hadOnJsBeforeUnload());
    184 
    185         mOnUiThread.loadUrlAndWaitForCompletion(mWebServer.getAssetUrl(TestHtmlConstants.JS_UNLOAD_URL));
    186         // unload should trigger when we try to navigate away
    187         mOnUiThread.loadUrlAndWaitForCompletion(mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL));
    188 
    189         new PollingCheck(TEST_TIMEOUT) {
    190             @Override
    191             protected boolean check() {
    192                 return webChromeClient.hadOnJsBeforeUnload();
    193             }
    194         }.run();
    195         assertEquals(webChromeClient.getMessage(), "testOnJsBeforeUnload");
    196     }
    197 
    198     public void testOnJsAlert() throws Exception {
    199         final MockWebChromeClient webChromeClient = new MockWebChromeClient();
    200         mOnUiThread.setWebChromeClient(webChromeClient);
    201 
    202         final WebSettings settings = mOnUiThread.getSettings();
    203         settings.setJavaScriptEnabled(true);
    204         settings.setJavaScriptCanOpenWindowsAutomatically(true);
    205 
    206         assertFalse(webChromeClient.hadOnJsAlert());
    207 
    208         String url = mWebServer.getAssetUrl(TestHtmlConstants.JS_ALERT_URL);
    209         mOnUiThread.loadUrlAndWaitForCompletion(url);
    210 
    211         new PollingCheck(TEST_TIMEOUT) {
    212             @Override
    213             protected boolean check() {
    214                 return webChromeClient.hadOnJsAlert();
    215             }
    216         }.run();
    217         assertEquals(webChromeClient.getMessage(), "testOnJsAlert");
    218     }
    219 
    220     public void testOnJsConfirm() throws Exception {
    221         final MockWebChromeClient webChromeClient = new MockWebChromeClient();
    222         mOnUiThread.setWebChromeClient(webChromeClient);
    223 
    224         final WebSettings settings = mOnUiThread.getSettings();
    225         settings.setJavaScriptEnabled(true);
    226         settings.setJavaScriptCanOpenWindowsAutomatically(true);
    227 
    228         assertFalse(webChromeClient.hadOnJsConfirm());
    229 
    230         String url = mWebServer.getAssetUrl(TestHtmlConstants.JS_CONFIRM_URL);
    231         mOnUiThread.loadUrlAndWaitForCompletion(url);
    232 
    233         new PollingCheck(TEST_TIMEOUT) {
    234             @Override
    235             protected boolean check() {
    236                 return webChromeClient.hadOnJsConfirm();
    237             }
    238         }.run();
    239         assertEquals(webChromeClient.getMessage(), "testOnJsConfirm");
    240     }
    241 
    242     public void testOnJsPrompt() throws Exception {
    243         final MockWebChromeClient webChromeClient = new MockWebChromeClient();
    244         mOnUiThread.setWebChromeClient(webChromeClient);
    245 
    246         final WebSettings settings = mOnUiThread.getSettings();
    247         settings.setJavaScriptEnabled(true);
    248         settings.setJavaScriptCanOpenWindowsAutomatically(true);
    249 
    250         assertFalse(webChromeClient.hadOnJsPrompt());
    251 
    252         final String promptResult = "CTS";
    253         webChromeClient.setPromptResult(promptResult);
    254         String url = mWebServer.getAssetUrl(TestHtmlConstants.JS_PROMPT_URL);
    255         mOnUiThread.loadUrlAndWaitForCompletion(url);
    256 
    257         new PollingCheck(TEST_TIMEOUT) {
    258             @Override
    259             protected boolean check() {
    260                 return webChromeClient.hadOnJsPrompt();
    261             }
    262         }.run();
    263         // the result returned by the client gets set as the page title
    264         new PollingCheck(TEST_TIMEOUT) {
    265             @Override
    266             protected boolean check() {
    267                 return mOnUiThread.getTitle().equals(promptResult);
    268             }
    269         }.run();
    270         assertEquals(webChromeClient.getMessage(), "testOnJsPrompt");
    271     }
    272 
    273     private class MockWebChromeClient extends WaitForProgressClient {
    274         private boolean mHadOnProgressChanged;
    275         private boolean mHadOnReceivedTitle;
    276         private String mPageTitle;
    277         private boolean mHadOnJsAlert;
    278         private boolean mHadOnJsConfirm;
    279         private boolean mHadOnJsPrompt;
    280         private boolean mHadOnJsBeforeUnload;
    281         private String mMessage;
    282         private String mPromptResult;
    283         private boolean mHadOnCloseWindow;
    284         private boolean mHadOnCreateWindow;
    285         private boolean mHadOnRequestFocus;
    286         private boolean mHadOnReceivedIcon;
    287 
    288         public MockWebChromeClient() {
    289             super(mOnUiThread);
    290         }
    291 
    292         public void setPromptResult(String promptResult) {
    293             mPromptResult = promptResult;
    294         }
    295 
    296         public boolean hadOnProgressChanged() {
    297             return mHadOnProgressChanged;
    298         }
    299 
    300         public boolean hadOnReceivedTitle() {
    301             return mHadOnReceivedTitle;
    302         }
    303 
    304         public String getPageTitle() {
    305             return mPageTitle;
    306         }
    307 
    308         public boolean hadOnJsAlert() {
    309             return mHadOnJsAlert;
    310         }
    311 
    312         public boolean hadOnJsConfirm() {
    313             return mHadOnJsConfirm;
    314         }
    315 
    316         public boolean hadOnJsPrompt() {
    317             return mHadOnJsPrompt;
    318         }
    319 
    320         public boolean hadOnJsBeforeUnload() {
    321             return mHadOnJsBeforeUnload;
    322         }
    323 
    324         public boolean hadOnCreateWindow() {
    325             return mHadOnCreateWindow;
    326         }
    327 
    328         public boolean hadOnCloseWindow() {
    329             return mHadOnCloseWindow;
    330         }
    331 
    332         public boolean hadOnRequestFocus() {
    333             return mHadOnRequestFocus;
    334         }
    335 
    336         public boolean hadOnReceivedIcon() {
    337             return mHadOnReceivedIcon;
    338         }
    339 
    340         public String getMessage() {
    341             return mMessage;
    342         }
    343 
    344         @Override
    345         public void onProgressChanged(WebView view, int newProgress) {
    346             super.onProgressChanged(view, newProgress);
    347             mHadOnProgressChanged = true;
    348         }
    349 
    350         @Override
    351         public void onReceivedTitle(WebView view, String title) {
    352             super.onReceivedTitle(view, title);
    353             mPageTitle = title;
    354             mHadOnReceivedTitle = true;
    355         }
    356 
    357         @Override
    358         public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
    359             super.onJsAlert(view, url, message, result);
    360             mHadOnJsAlert = true;
    361             mMessage = message;
    362             result.confirm();
    363             return true;
    364         }
    365 
    366         @Override
    367         public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
    368             super.onJsConfirm(view, url, message, result);
    369             mHadOnJsConfirm = true;
    370             mMessage = message;
    371             result.confirm();
    372             return true;
    373         }
    374 
    375         @Override
    376         public boolean onJsPrompt(WebView view, String url, String message,
    377                 String defaultValue, JsPromptResult result) {
    378             super.onJsPrompt(view, url, message, defaultValue, result);
    379             mHadOnJsPrompt = true;
    380             mMessage = message;
    381             result.confirm(mPromptResult);
    382             return true;
    383         }
    384 
    385         @Override
    386         public boolean onJsBeforeUnload(WebView view, String url, String message, JsResult result) {
    387             super.onJsBeforeUnload(view, url, message, result);
    388             mHadOnJsBeforeUnload = true;
    389             mMessage = message;
    390             result.confirm();
    391             return true;
    392         }
    393 
    394         @Override
    395         public void onCloseWindow(WebView window) {
    396             super.onCloseWindow(window);
    397             mHadOnCloseWindow = true;
    398         }
    399 
    400         @Override
    401         public boolean onCreateWindow(WebView view, boolean dialog, boolean userGesture,
    402                 Message resultMsg) {
    403             mHadOnCreateWindow = true;
    404             if (mBlockWindowCreationSync) {
    405                 return false;
    406             }
    407             WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
    408             if (mBlockWindowCreationAsync) {
    409                 transport.setWebView(null);
    410             } else {
    411                 WebView childView = new WebView(getActivity());
    412                 final WebSettings settings = childView.getSettings();
    413                 settings.setJavaScriptEnabled(true);
    414                 childView.setWebChromeClient(this);
    415                 transport.setWebView(childView);
    416                 getActivity().addContentView(childView, new ViewGroup.LayoutParams(
    417                         ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
    418             }
    419             resultMsg.sendToTarget();
    420             return true;
    421         }
    422 
    423         @Override
    424         public void onRequestFocus(WebView view) {
    425             mHadOnRequestFocus = true;
    426         }
    427 
    428         @Override
    429         public void onReceivedIcon(WebView view, Bitmap icon) {
    430             mHadOnReceivedIcon = true;
    431         }
    432     }
    433 }
    434