Home | History | Annotate | Download | only in content_shell_apk
      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.
      4 
      5 package org.chromium.content_shell_apk;
      6 
      7 import android.content.ComponentName;
      8 import android.content.Intent;
      9 import android.net.Uri;
     10 import android.test.ActivityInstrumentationTestCase2;
     11 import android.text.TextUtils;
     12 
     13 import static org.chromium.base.test.util.ScalableTimeout.ScaleTimeout;
     14 
     15 import org.chromium.base.test.util.UrlUtils;
     16 import org.chromium.content.browser.ContentView;
     17 import org.chromium.content.browser.ContentViewCore;
     18 import org.chromium.content.browser.LoadUrlParams;
     19 import org.chromium.content.browser.test.util.CallbackHelper;
     20 import org.chromium.content.browser.test.util.Criteria;
     21 import org.chromium.content.browser.test.util.CriteriaHelper;
     22 import org.chromium.content.browser.test.util.TestCallbackHelperContainer;
     23 import org.chromium.content_shell.Shell;
     24 
     25 import java.util.concurrent.TimeUnit;
     26 import java.util.concurrent.atomic.AtomicBoolean;
     27 
     28 /**
     29  * Base test class for all ContentShell based tests.
     30  */
     31 public class ContentShellTestBase extends ActivityInstrumentationTestCase2<ContentShellActivity> {
     32 
     33     /** The maximum time the waitForActiveShellToBeDoneLoading method will wait. */
     34     private static final long WAIT_FOR_ACTIVE_SHELL_LOADING_TIMEOUT = ScaleTimeout(10000);
     35 
     36     protected static final long WAIT_PAGE_LOADING_TIMEOUT_SECONDS = ScaleTimeout(15);
     37 
     38     public ContentShellTestBase() {
     39         super(ContentShellActivity.class);
     40     }
     41 
     42     /**
     43      * Starts the ContentShell activity and loads the given URL.
     44      * The URL can be null, in which case will default to ContentShellActivity.DEFAULT_SHELL_URL.
     45      */
     46     protected ContentShellActivity launchContentShellWithUrl(String url) {
     47         return launchContentShellWithUrlAndCommandLineArgs(url, null);
     48     }
     49 
     50     /**
     51      * Starts the ContentShell activity appending the provided command line arguments
     52      * and loads the given URL. The URL can be null, in which case will default to
     53      * ContentShellActivity.DEFAULT_SHELL_URL.
     54      */
     55     protected ContentShellActivity launchContentShellWithUrlAndCommandLineArgs(String url,
     56             String[] commandLineArgs) {
     57         Intent intent = new Intent(Intent.ACTION_MAIN);
     58         intent.addCategory(Intent.CATEGORY_LAUNCHER);
     59         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
     60         if (url != null) intent.setData(Uri.parse(url));
     61         intent.setComponent(new ComponentName(getInstrumentation().getTargetContext(),
     62               ContentShellActivity.class));
     63         if (commandLineArgs != null) {
     64             intent.putExtra(ContentShellActivity.COMMAND_LINE_ARGS_KEY, commandLineArgs);
     65         }
     66         setActivityIntent(intent);
     67         return getActivity();
     68     }
     69 
     70     // TODO(cjhopman): These functions are inconsistent with launchContentShell***. Should be
     71     // startContentShell*** and should use the url exactly without the getTestFileUrl call. Possibly
     72     // these two ways of starting the activity (launch* and start*) should be merged into one.
     73     /**
     74      * Starts the content shell activity with the provided test url.
     75      * The url is synchronously loaded.
     76      * @param url Test url to load.
     77      */
     78     protected void startActivityWithTestUrl(String url) throws Throwable {
     79         launchContentShellWithUrl(UrlUtils.getTestFileUrl(url));
     80         assertNotNull(getActivity());
     81         assertTrue(waitForActiveShellToBeDoneLoading());
     82         assertEquals(UrlUtils.getTestFileUrl(url), getContentView().getUrl());
     83     }
     84 
     85     /**
     86      * Starts the content shell activity with the provided test url and optional command line
     87      * arguments to append.
     88      * The url is synchronously loaded.
     89      * @param url Test url to load.
     90      * @param commandLineArgs Optional command line args to append when launching the activity.
     91      */
     92     protected void startActivityWithTestUrlAndCommandLineArgs(
     93             String url, String[] commandLineArgs) throws Throwable {
     94         launchContentShellWithUrlAndCommandLineArgs(
     95                 UrlUtils.getTestFileUrl(url), commandLineArgs);
     96         assertNotNull(getActivity());
     97         assertTrue(waitForActiveShellToBeDoneLoading());
     98     }
     99 
    100     /**
    101      * Returns the current ContentView.
    102      */
    103     protected ContentView getContentView() {
    104         return getActivity().getActiveShell().getContentView();
    105     }
    106 
    107     /**
    108      * Returns the current ContentViewCore or null if there is no ContentView.
    109      */
    110     protected ContentViewCore getContentViewCore() {
    111         return getContentView() == null ? null : getContentView().getContentViewCore();
    112     }
    113 
    114     /**
    115      * Waits for the Active shell to finish loading.  This times out after
    116      * WAIT_FOR_ACTIVE_SHELL_LOADING_TIMEOUT milliseconds and it shouldn't be used for long
    117      * loading pages. Instead it should be used more for test initialization. The proper way
    118      * to wait is to use a TestCallbackHelperContainer after the initial load is completed.
    119      * @return Whether or not the Shell was actually finished loading.
    120      * @throws InterruptedException
    121      */
    122     protected boolean waitForActiveShellToBeDoneLoading() throws InterruptedException {
    123         final ContentShellActivity activity = getActivity();
    124 
    125         // Wait for the Content Shell to be initialized.
    126         return CriteriaHelper.pollForCriteria(new Criteria() {
    127             @Override
    128             public boolean isSatisfied() {
    129                 try {
    130                     final AtomicBoolean isLoaded = new AtomicBoolean(false);
    131                     runTestOnUiThread(new Runnable() {
    132                         @Override
    133                         public void run() {
    134                             Shell shell = activity.getActiveShell();
    135                             if (shell != null) {
    136                                 // There are two cases here that need to be accounted for.
    137                                 // The first is that we've just created a Shell and it isn't
    138                                 // loading because it has no URL set yet.  The second is that
    139                                 // we've set a URL and it actually is loading.
    140                                 isLoaded.set(!shell.isLoading()
    141                                         && !TextUtils.isEmpty(shell.getContentView().getUrl()));
    142                             } else {
    143                                 isLoaded.set(false);
    144                             }
    145                         }
    146                     });
    147 
    148                     return isLoaded.get();
    149                 } catch (Throwable e) {
    150                     return false;
    151                 }
    152             }
    153         }, WAIT_FOR_ACTIVE_SHELL_LOADING_TIMEOUT, CriteriaHelper.DEFAULT_POLLING_INTERVAL);
    154     }
    155 
    156     /**
    157      * Loads a URL in the specified content view.
    158      *
    159      * @param contentView The content view to load the URL in.
    160      * @param callbackHelperContainer The callback helper container used to monitor progress.
    161      * @param params The URL params to use.
    162      */
    163     protected void loadUrl(
    164             final ContentView contentView, TestCallbackHelperContainer callbackHelperContainer,
    165             final LoadUrlParams params) throws Throwable {
    166         handleBlockingCallbackAction(
    167                 callbackHelperContainer.getOnPageFinishedHelper(),
    168                 new Runnable() {
    169                     @Override
    170                     public void run() {
    171                         contentView.loadUrl(params);
    172                     }
    173                 });
    174     }
    175 
    176     /**
    177      * Handles performing an action on the UI thread that will return when the specified callback
    178      * is incremented.
    179      *
    180      * @param callbackHelper The callback helper that will be blocked on.
    181      * @param action The action to be performed on the UI thread.
    182      */
    183     protected void handleBlockingCallbackAction(
    184             CallbackHelper callbackHelper, Runnable action) throws Throwable {
    185         int currentCallCount = callbackHelper.getCallCount();
    186         runTestOnUiThread(action);
    187         callbackHelper.waitForCallback(
    188                 currentCallCount, 1, WAIT_PAGE_LOADING_TIMEOUT_SECONDS, TimeUnit.SECONDS);
    189     }
    190 
    191     // TODO(aelias): This method needs to be removed once http://crbug.com/179511 is fixed.
    192     // Meanwhile, we have to wait if the page has the <meta viewport> tag.
    193     /**
    194      * Waits till the ContentViewCore receives the expected page scale factor
    195      * from the compositor and asserts that this happens.
    196      */
    197     protected void assertWaitForPageScaleFactorMatch(final float expectedScale)
    198             throws InterruptedException {
    199         assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
    200             @Override
    201             public boolean isSatisfied() {
    202                 return getContentViewCore().getScale() == expectedScale;
    203             }
    204         }));
    205     }
    206 }
    207