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 ActivityTest(Class<T> activityClass)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 */ getInitialRoot()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 */ getTestingProviderAuthority()89 protected String getTestingProviderAuthority() { 90 return StubProvider.DEFAULT_AUTHORITY; 91 } 92 93 /** 94 * Resolves testing roots. 95 */ setupTestingRoots()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 setUp()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 tearDown()130 public void tearDown() throws Exception { 131 device.unfreezeRotation(); 132 mClient.release(); 133 super.tearDown(); 134 } 135 launchActivity()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 resetStorage()148 protected void resetStorage() throws RemoteException { 149 mClient.call("clear", null, null); 150 device.waitForIdle(); 151 } 152 initTestFiles()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 assertDefaultContentOfTestDir0()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 assertDefaultContentOfTestDir1()172 void assertDefaultContentOfTestDir1() throws UiObjectNotFoundException { 173 bots.directory.waitForDocument(fileName3); 174 bots.directory.waitForDocument(fileName4); 175 bots.directory.assertDocumentsCount(2); 176 } 177 } 178