Home | History | Annotate | Download | only in shell
      1 // Copyright 2014 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.
      4 
      5 package org.chromium.chrome.shell;
      6 
      7 import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout;
      8 
      9 import android.content.ComponentName;
     10 import android.content.Context;
     11 import android.content.Intent;
     12 import android.net.Uri;
     13 import android.test.ActivityInstrumentationTestCase2;
     14 import android.text.TextUtils;
     15 import android.util.Log;
     16 
     17 import org.chromium.base.CommandLine;
     18 import org.chromium.base.ThreadUtils;
     19 import org.chromium.base.library_loader.ProcessInitException;
     20 import org.chromium.chrome.test.util.ApplicationData;
     21 import org.chromium.content.browser.BrowserStartupController;
     22 import org.chromium.content.browser.test.util.Criteria;
     23 import org.chromium.content.browser.test.util.CriteriaHelper;
     24 
     25 import java.util.concurrent.atomic.AtomicBoolean;
     26 
     27 /**
     28  * Base test class for all ChromeShell based tests.
     29  */
     30 public class ChromeShellTestBase extends ActivityInstrumentationTestCase2<ChromeShellActivity> {
     31     /** The maximum time the waitForActiveShellToBeDoneLoading method will wait. */
     32     private static final long WAIT_FOR_ACTIVE_SHELL_LOADING_TIMEOUT = scaleTimeout(10000);
     33     private static final String TAG = "ChromeShellTestBase";
     34 
     35     public ChromeShellTestBase() {
     36         super(ChromeShellActivity.class);
     37     }
     38 
     39     protected static void startChromeBrowserProcessSync(final Context targetContext) {
     40         ThreadUtils.runOnUiThreadBlocking(new Runnable() {
     41             @Override
     42             public void run() {
     43                 CommandLine.initFromFile("/data/local/tmp/chrome-shell-command-line");
     44                 try {
     45                     BrowserStartupController.get(targetContext).startBrowserProcessesSync(
     46                             BrowserStartupController.MAX_RENDERERS_LIMIT);
     47                 } catch (ProcessInitException e) {
     48                     Log.e(TAG, "Unable to load native library.", e);
     49                     fail("Unable to load native library");
     50                 }
     51             }
     52         });
     53     }
     54 
     55     /**
     56      * Starts the {@link ChromeShellActivity} and loads the given URL.
     57      */
     58     protected ChromeShellActivity launchChromeShellWithUrl(String url) {
     59         Intent intent = new Intent(Intent.ACTION_MAIN);
     60         intent.addCategory(Intent.CATEGORY_LAUNCHER);
     61         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
     62         if (url != null) intent.setData(Uri.parse(url));
     63         intent.setComponent(new ComponentName(getInstrumentation().getTargetContext(),
     64                 ChromeShellActivity.class));
     65         setActivityIntent(intent);
     66         return getActivity();
     67     }
     68 
     69     /**
     70      * Starts the {@link ChromeShellActivity} and loads a blank page.
     71      */
     72     protected ChromeShellActivity launchChromeShellWithBlankPage() {
     73         return launchChromeShellWithUrl("about:blank");
     74     }
     75 
     76     /**
     77      * Waits for the Active shell to finish loading.  This times out after
     78      * WAIT_FOR_ACTIVE_SHELL_LOADING_TIMEOUT milliseconds and it shouldn't be used for long
     79      * loading pages. Instead it should be used more for test initialization. The proper way
     80      * to wait is to use a TestCallbackHelperContainer after the initial load is completed.
     81      * @return Whether or not the Shell was actually finished loading.
     82      * @throws InterruptedException
     83      */
     84     protected boolean waitForActiveShellToBeDoneLoading() throws InterruptedException {
     85         final ChromeShellActivity activity = getActivity();
     86 
     87         // Wait for the Content Shell to be initialized.
     88         return CriteriaHelper.pollForCriteria(new Criteria() {
     89             @Override
     90             public boolean isSatisfied() {
     91                 try {
     92                     final AtomicBoolean isLoaded = new AtomicBoolean(false);
     93                     runTestOnUiThread(new Runnable() {
     94                         @Override
     95                         public void run() {
     96                             ChromeShellTab tab = activity.getActiveTab();
     97                             if (tab != null) {
     98                                 isLoaded.set(!tab.isLoading()
     99                                         && !TextUtils.isEmpty(tab.getContentViewCore().getUrl()));
    100                             } else {
    101                                 isLoaded.set(false);
    102                             }
    103                         }
    104                     });
    105 
    106                     return isLoaded.get();
    107                 } catch (Throwable e) {
    108                     return false;
    109                 }
    110             }
    111         }, WAIT_FOR_ACTIVE_SHELL_LOADING_TIMEOUT, CriteriaHelper.DEFAULT_POLLING_INTERVAL);
    112     }
    113 
    114     /**
    115      * Clear all files and folders in the ChromeShell's application directory except 'lib'.
    116      *
    117      * The 'cache' directory is recreated as an empty directory.
    118      *
    119      * @return Whether clearing the application data was successful.
    120      */
    121     protected boolean clearAppData() throws InterruptedException {
    122         return ApplicationData.clearAppData(getInstrumentation().getTargetContext());
    123     }
    124 
    125     /**
    126      * Navigates the currently active tab to a sanitized version of {@code url}.
    127      * @param url The potentially unsanitized URL to navigate to.
    128      */
    129     public void loadUrlWithSanitization(final String url) throws InterruptedException {
    130         getInstrumentation().runOnMainSync(new Runnable() {
    131             @Override
    132             public void run() {
    133                 getActivity().getActiveTab().loadUrlWithSanitization(url);
    134             }
    135         });
    136         waitForActiveShellToBeDoneLoading();
    137     }
    138 
    139     // TODO(aelias): This method needs to be removed once http://crbug.com/179511 is fixed.
    140     // Meanwhile, we have to wait if the page has the <meta viewport> tag.
    141     /**
    142      * Waits till the ContentViewCore receives the expected page scale factor
    143      * from the compositor and asserts that this happens.
    144      */
    145     protected void assertWaitForPageScaleFactorMatch(final float expectedScale)
    146             throws InterruptedException {
    147         assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
    148             @Override
    149             public boolean isSatisfied() {
    150                 return getActivity().getActiveTab().getContentViewCore().getScale() ==
    151                         expectedScale;
    152             }
    153         }));
    154     }
    155 }
    156