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