Home | History | Annotate | Download | only in documentsui
      1 /*
      2  * Copyright (C) 2016 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 com.android.documentsui;
     18 
     19 import android.app.Activity;
     20 import android.app.UiAutomation;
     21 import android.content.ContentProviderClient;
     22 import android.content.ContentResolver;
     23 import android.content.Context;
     24 import android.content.Intent;
     25 import android.os.RemoteException;
     26 import android.provider.DocumentsContract;
     27 import android.provider.DocumentsContract.Document;
     28 import android.support.test.uiautomator.Configurator;
     29 import android.support.test.uiautomator.UiDevice;
     30 import android.support.test.uiautomator.UiObjectNotFoundException;
     31 import android.test.ActivityInstrumentationTestCase2;
     32 import android.view.MotionEvent;
     33 
     34 import com.android.documentsui.base.RootInfo;
     35 import com.android.documentsui.bots.Bots;
     36 import com.android.documentsui.bots.UiBot;
     37 
     38 import javax.annotation.Nullable;
     39 
     40 /**
     41  * Provides basic test environment for UI tests:
     42  * - Launches activity
     43  * - Creates and gives access to test root directories and test files
     44  * - Cleans up the test environment
     45  */
     46 public abstract class ActivityTest<T extends Activity> extends ActivityInstrumentationTestCase2<T> {
     47 
     48     static final int TIMEOUT = 5000;
     49 
     50     // Testing files. For custom ones, override initTestFiles().
     51     public static final String dirName1 = "Dir1";
     52     public static final String childDir1 = "ChildDir1";
     53     public static final String fileName1 = "file1.log";
     54     public static final String fileName2 = "file12.png";
     55     public static final String fileName3 = "anotherFile0.log";
     56     public static final String fileName4 = "poodles.text";
     57     public static final String fileNameNoRename = "NO_RENAMEfile.txt";
     58 
     59     public Bots bots;
     60     public UiDevice device;
     61     public Context context;
     62     public UiAutomation automation;
     63 
     64     public RootInfo rootDir0;
     65     public RootInfo rootDir1;
     66     protected ContentResolver mResolver;
     67     protected DocumentsProviderHelper mDocsHelper;
     68     protected ContentProviderClient mClient;
     69 
     70     public ActivityTest(Class<T> activityClass) {
     71         super(activityClass);
     72     }
     73 
     74     /*
     75      * Returns the root that will be opened within the activity.
     76      * By default tests are started with one of the test roots.
     77      * Override the method if you want to open different root on start.
     78      * @return Root that will be opened. Return null if you want to open activity's default root.
     79      */
     80     protected @Nullable RootInfo getInitialRoot() {
     81         return rootDir0;
     82     }
     83 
     84     /**
     85      * Returns the authority of the testing provider begin used.
     86      * By default it's StubProvider's authority.
     87      * @return Authority of the provider.
     88      */
     89     protected String getTestingProviderAuthority() {
     90         return StubProvider.DEFAULT_AUTHORITY;
     91     }
     92 
     93     /**
     94      * Resolves testing roots.
     95      */
     96     protected void setupTestingRoots() throws RemoteException {
     97         rootDir0 = mDocsHelper.getRoot(StubProvider.ROOT_0_ID);
     98         rootDir1 = mDocsHelper.getRoot(StubProvider.ROOT_1_ID);
     99     }
    100 
    101     @Override
    102     public void setUp() throws Exception {
    103         device = UiDevice.getInstance(getInstrumentation());
    104         // NOTE: Must be the "target" context, else security checks in content provider will fail.
    105         context = getInstrumentation().getTargetContext();
    106         automation = getInstrumentation().getUiAutomation();
    107 
    108         bots = new Bots(device, automation, context, TIMEOUT);
    109 
    110         Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_MOUSE);
    111 
    112         mResolver = context.getContentResolver();
    113         mClient = mResolver.acquireUnstableContentProviderClient(getTestingProviderAuthority());
    114         mDocsHelper = new DocumentsProviderHelper(getTestingProviderAuthority(), mClient);
    115 
    116         device.setOrientationNatural();
    117         setupTestingRoots();
    118 
    119         launchActivity();
    120         resetStorage();
    121 
    122         // Since at the launch of activity, ROOT_0 and ROOT_1 have no files, drawer will
    123         // automatically open for phone devices. Espresso register click() as (x, y) MotionEvents,
    124         // so if a drawer is on top of a file we want to select, it will actually click the drawer.
    125         // Thus to start a clean state, we always try to close first.
    126         bots.roots.closeDrawer();
    127     }
    128 
    129     @Override
    130     public void tearDown() throws Exception {
    131         device.unfreezeRotation();
    132         mClient.release();
    133         super.tearDown();
    134     }
    135 
    136     private void launchActivity() {
    137         final Intent intent = context.getPackageManager().getLaunchIntentForPackage(
    138                 UiBot.TARGET_PKG);
    139         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
    140         if (getInitialRoot() != null) {
    141             intent.setAction(Intent.ACTION_VIEW);
    142             intent.setDataAndType(getInitialRoot().getUri(), DocumentsContract.Root.MIME_TYPE_ITEM);
    143         }
    144         setActivityIntent(intent);
    145         getActivity();  // Launch the activity.
    146     }
    147 
    148     protected void resetStorage() throws RemoteException {
    149         mClient.call("clear", null, null);
    150         device.waitForIdle();
    151     }
    152 
    153     protected void initTestFiles() throws RemoteException {
    154         mDocsHelper.createFolder(rootDir0, dirName1);
    155         mDocsHelper.createDocument(rootDir0, "text/plain", fileName1);
    156         mDocsHelper.createDocument(rootDir0, "image/png", fileName2);
    157         mDocsHelper.createDocumentWithFlags(rootDir0.documentId, "text/plain", fileNameNoRename,
    158                 Document.FLAG_SUPPORTS_WRITE);
    159 
    160         mDocsHelper.createDocument(rootDir1, "text/plain", fileName3);
    161         mDocsHelper.createDocument(rootDir1, "text/plain", fileName4);
    162     }
    163 
    164     void assertDefaultContentOfTestDir0() throws UiObjectNotFoundException {
    165         bots.directory.waitForDocument(fileName1);
    166         bots.directory.waitForDocument(fileName2);
    167         bots.directory.waitForDocument(dirName1);
    168         bots.directory.waitForDocument(fileNameNoRename);
    169         bots.directory.assertDocumentsCount(4);
    170     }
    171 
    172     void assertDefaultContentOfTestDir1() throws UiObjectNotFoundException {
    173         bots.directory.waitForDocument(fileName3);
    174         bots.directory.waitForDocument(fileName4);
    175         bots.directory.assertDocumentsCount(2);
    176     }
    177 }
    178