diff options
Diffstat (limited to 'tests')
16 files changed, 319 insertions, 209 deletions
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index abc93cd4b..4a0ca5c24 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -35,7 +35,6 @@ import android.content.pm.PackageManager; import android.os.Process; import android.os.RemoteException; import android.util.Log; -import android.view.Surface; import androidx.test.InstrumentationRegistry; import androidx.test.uiautomator.By; @@ -67,7 +66,6 @@ import org.junit.Before; import org.junit.Rule; import org.junit.rules.RuleChain; import org.junit.rules.TestRule; -import org.junit.runners.model.Statement; import java.io.IOException; import java.lang.annotation.ElementType; @@ -124,46 +122,10 @@ public abstract class AbstractLauncherUiTest { protected @interface PortraitLandscape { } - @Rule - public TestRule mPortraitLandscapeExecutor = - (base, description) -> false && description.getAnnotation(PortraitLandscape.class) - != null ? new Statement() { - @Override - public void evaluate() throws Throwable { - try { - // Create launcher activity if necessary and bring it to the front. - mLauncher.pressHome(); - waitForLauncherCondition("Launcher activity wasn't created", - launcher -> launcher != null); - - executeOnLauncher(launcher -> - launcher.getRotationHelper().forceAllowRotationForTesting(true)); - - evaluateInPortrait(); - evaluateInLandscape(); - } finally { - mDevice.setOrientationNatural(); - executeOnLauncher(launcher -> - launcher.getRotationHelper().forceAllowRotationForTesting(false)); - mLauncher.setExpectedRotation(Surface.ROTATION_0); - } - } - - private void evaluateInPortrait() throws Throwable { - mDevice.setOrientationNatural(); - mLauncher.setExpectedRotation(Surface.ROTATION_0); - base.evaluate(); - } - - private void evaluateInLandscape() throws Throwable { - mDevice.setOrientationLeft(); - mLauncher.setExpectedRotation(Surface.ROTATION_90); - base.evaluate(); - } - } : base; - protected TestRule getRulesInsideActivityMonitor() { - return new FailureWatcher(this); + return RuleChain. + outerRule(new PortraitLandscapeRunner(this)). + around(new FailureWatcher(mDevice)); } @Rule diff --git a/tests/src/com/android/launcher3/ui/DefaultLayoutProviderTest.java b/tests/src/com/android/launcher3/ui/DefaultLayoutProviderTest.java index 48335a602..58c74cef1 100644 --- a/tests/src/com/android/launcher3/ui/DefaultLayoutProviderTest.java +++ b/tests/src/com/android/launcher3/ui/DefaultLayoutProviderTest.java @@ -25,26 +25,23 @@ import android.net.Uri; import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor.AutoCloseOutputStream; +import androidx.test.InstrumentationRegistry; +import androidx.test.filters.MediumTest; +import androidx.test.runner.AndroidJUnit4; + import com.android.launcher3.LauncherAppWidgetProviderInfo; import com.android.launcher3.testcomponent.TestCommandReceiver; import com.android.launcher3.util.LauncherLayoutBuilder; import com.android.launcher3.util.rule.ShellCommandRule; -import com.android.launcher3.widget.LauncherAppWidgetHostView; import org.junit.After; import org.junit.Before; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import java.io.OutputStreamWriter; -import androidx.test.InstrumentationRegistry; -import androidx.test.filters.MediumTest; -import androidx.test.runner.AndroidJUnit4; -import androidx.test.uiautomator.UiSelector; - @MediumTest @RunWith(AndroidJUnit4.class) public class DefaultLayoutProviderTest extends AbstractLauncherUiTest { @@ -71,7 +68,6 @@ public class DefaultLayoutProviderTest extends AbstractLauncherUiTest { } @Test - // Convert test to TAPL; b/131116002 public void testCustomProfileLoaded_with_icon_on_hotseat() throws Exception { writeLayout(new LauncherLayoutBuilder().atHotseat(0).putApp(SETTINGS_APP, SETTINGS_APP)); @@ -79,14 +75,10 @@ public class DefaultLayoutProviderTest extends AbstractLauncherUiTest { mActivityMonitor.startLauncher(); waitForModelLoaded(); - // Verify widget present - UiSelector selector = new UiSelector().packageName(mTargetContext.getPackageName()) - .description(getSettingsApp().getLabel().toString()); - assertTrue(mDevice.findObject(selector).waitForExists(DEFAULT_UI_TIMEOUT)); + mLauncher.getWorkspace().getHotseatAppIcon(getSettingsApp().getLabel().toString()); } @Test - // Convert test to TAPL; b/131116002 public void testCustomProfileLoaded_with_widget() throws Exception { // A non-restored widget with no config screen gets restored automatically. LauncherAppWidgetProviderInfo info = TestViewHelpers.findWidgetProvider(this, false); @@ -100,13 +92,11 @@ public class DefaultLayoutProviderTest extends AbstractLauncherUiTest { waitForModelLoaded(); // Verify widget present - UiSelector selector = new UiSelector().packageName(mTargetContext.getPackageName()) - .className(LauncherAppWidgetHostView.class).description(info.label); - assertTrue(mDevice.findObject(selector).waitForExists(DEFAULT_UI_TIMEOUT)); + assertTrue("Widget is not present", + mLauncher.getWorkspace().tryGetWidget(info.label, DEFAULT_UI_TIMEOUT) != null); } @Test - // Convert test to TAPL; b/131116002 public void testCustomProfileLoaded_with_folder() throws Exception { writeLayout(new LauncherLayoutBuilder().atHotseat(0).putFolder(android.R.string.copy) .addApp(SETTINGS_APP, SETTINGS_APP) @@ -118,10 +108,7 @@ public class DefaultLayoutProviderTest extends AbstractLauncherUiTest { mActivityMonitor.startLauncher(); waitForModelLoaded(); - // Verify widget present - UiSelector selector = new UiSelector().packageName(mTargetContext.getPackageName()) - .descriptionContains(mTargetContext.getString(android.R.string.copy)); - assertTrue(mDevice.findObject(selector).waitForExists(DEFAULT_UI_TIMEOUT)); + mLauncher.getWorkspace().getHotseatFolder("Folder: Copy"); } @After diff --git a/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java b/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java new file mode 100644 index 000000000..0f36292f9 --- /dev/null +++ b/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java @@ -0,0 +1,63 @@ +package com.android.launcher3.ui; + +import android.view.Surface; + +import com.android.launcher3.tapl.TestHelpers; + +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +class PortraitLandscapeRunner implements TestRule { + private AbstractLauncherUiTest mTest; + + public PortraitLandscapeRunner(AbstractLauncherUiTest test) { + mTest = test; + } + + @Override + public Statement apply(Statement base, Description description) { + if (!TestHelpers.isInLauncherProcess() || + description.getAnnotation(AbstractLauncherUiTest.PortraitLandscape.class) == null) { + return base; + } + + return new Statement() { + @Override + public void evaluate() throws Throwable { + try { + mTest.mDevice.pressHome(); + mTest.waitForLauncherCondition("Launcher activity wasn't created", + launcher -> launcher != null); + + mTest.executeOnLauncher(launcher -> + launcher.getRotationHelper().forceAllowRotationForTesting( + true)); + + evaluateInPortrait(); + evaluateInLandscape(); + } finally { + mTest.mDevice.setOrientationNatural(); + mTest.executeOnLauncher(launcher -> + launcher.getRotationHelper().forceAllowRotationForTesting( + false)); + mTest.mLauncher.setExpectedRotation(Surface.ROTATION_0); + } + } + + private void evaluateInPortrait() throws Throwable { + mTest.mDevice.setOrientationNatural(); + mTest.mLauncher.setExpectedRotation(Surface.ROTATION_0); + base.evaluate(); + mTest.getDevice().pressHome(); + } + + private void evaluateInLandscape() throws Throwable { + mTest.mDevice.setOrientationLeft(); + mTest.mLauncher.setExpectedRotation(Surface.ROTATION_90); + base.evaluate(); + mTest.getDevice().pressHome(); + } + }; + } +} diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java index d171004fc..c3168f812 100644 --- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java +++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java @@ -59,11 +59,7 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest { public static void initialize(AbstractLauncherUiTest test) throws Exception { test.clearLauncherData(); - if (TestHelpers.isInLauncherProcess()) { - test.mActivityMonitor.returnToHome(); - } else { - test.mDevice.pressHome(); - } + test.mDevice.pressHome(); test.waitForLauncherCondition("Launcher didn't start", launcher -> launcher != null); test.waitForState("Launcher internal state didn't switch to Home", LauncherState.NORMAL); test.waitForResumed("Launcher internal state is still Background"); @@ -279,8 +275,6 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest { @Test @PortraitLandscape public void testLaunchMenuItem() throws Exception { - if (!TestHelpers.isInLauncherProcess()) return; - final AllApps allApps = mLauncher. getWorkspace(). switchToAllApps(); @@ -327,8 +321,6 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest { @Test @PortraitLandscape public void testDragShortcut() throws Throwable { - if (!TestHelpers.isInLauncherProcess()) return; - // 1. Open all apps and wait for load complete. // 2. Find the app and long press it to show shortcuts. // 3. Press icon center until shortcuts appear diff --git a/tests/src/com/android/launcher3/ui/TestViewHelpers.java b/tests/src/com/android/launcher3/ui/TestViewHelpers.java index a73bde011..d13d31952 100644 --- a/tests/src/com/android/launcher3/ui/TestViewHelpers.java +++ b/tests/src/com/android/launcher3/ui/TestViewHelpers.java @@ -54,21 +54,6 @@ public class TestViewHelpers { return UiDevice.getInstance(getInstrumentation()); } - /** - * Opens all apps and returns the recycler view - */ - public static UiObject2 openAllApps() { - final UiDevice device = getDevice(); - device.waitForIdle(); - UiObject2 hotseat = device.wait( - Until.findObject(getSelectorForId(R.id.hotseat)), 2500); - Point start = hotseat.getVisibleCenter(); - int endY = (int) (device.getDisplayHeight() * 0.1f); - // 100 px/step - device.swipe(start.x, start.y, start.x, endY, (start.y - endY) / 100); - return findViewById(R.id.apps_list_view); - } - public static UiObject2 findViewById(int id) { return getDevice().wait(Until.findObject(getSelectorForId(id)), AbstractLauncherUiTest.DEFAULT_UI_TIMEOUT); diff --git a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java index 874ff1995..d36126bb1 100644 --- a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java +++ b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java @@ -15,8 +15,9 @@ */ package com.android.launcher3.ui.widget; +import static com.android.launcher3.WorkspaceLayoutManager.FIRST_SCREEN_ID; + import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -24,43 +25,37 @@ import android.appwidget.AppWidgetHost; import android.appwidget.AppWidgetManager; import android.content.ComponentName; import android.content.ContentResolver; -import android.content.ContentValues; import android.content.pm.PackageInstaller; import android.content.pm.PackageInstaller.SessionParams; import android.content.pm.PackageManager; import android.database.Cursor; import android.os.Bundle; +import androidx.test.filters.LargeTest; +import androidx.test.runner.AndroidJUnit4; + import com.android.launcher3.LauncherAppWidgetHost; import com.android.launcher3.LauncherAppWidgetInfo; import com.android.launcher3.LauncherAppWidgetProviderInfo; import com.android.launcher3.LauncherSettings; -import com.android.launcher3.Workspace; import com.android.launcher3.compat.AppWidgetManagerCompat; import com.android.launcher3.compat.PackageInstallerCompat; +import com.android.launcher3.tapl.Workspace; import com.android.launcher3.ui.AbstractLauncherUiTest; import com.android.launcher3.ui.TestViewHelpers; import com.android.launcher3.util.ContentWriter; import com.android.launcher3.util.rule.ShellCommandRule; -import com.android.launcher3.widget.LauncherAppWidgetHostView; import com.android.launcher3.widget.PendingAddWidgetInfo; -import com.android.launcher3.widget.PendingAppWidgetHostView; import com.android.launcher3.widget.WidgetHostViewLoader; import org.junit.After; import org.junit.Before; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import java.util.Set; -import androidx.test.filters.LargeTest; -import androidx.test.runner.AndroidJUnit4; -import androidx.test.uiautomator.UiSelector; -import java.util.concurrent.Callable; - /** * Tests for bind widget flow. * @@ -131,16 +126,14 @@ public class BindWidgetTest extends AbstractLauncherUiTest { setupContents(item); - // Since there is no widget to verify, just wait until the workspace is ready. - // TODO: fix LauncherInstrumentation#LAUNCHER_PKG - mLauncher.getWorkspace(); + final Workspace workspace = mLauncher.getWorkspace(); // Item deleted from db mCursor = mResolver.query(LauncherSettings.Favorites.getContentUri(item.id), null, null, null, null, null); assertEquals(0, mCursor.getCount()); // The view does not exist - assertFalse(mDevice.findObject(new UiSelector().description(info.label)).exists()); + assertTrue("Widget exists", workspace.tryGetWidget(info.label, 0) == null); } @Test @@ -189,12 +182,8 @@ public class BindWidgetTest extends AbstractLauncherUiTest { setupContents(item); - // Since there is no widget to verify, just wait until the workspace is ready. - // TODO: fix LauncherInstrumentation#LAUNCHER_PKG - mLauncher.getWorkspace(); - // The view does not exist - assertFalse(mDevice.findObject( - new UiSelector().className(PendingAppWidgetHostView.class)).exists()); + assertTrue("Pending widget exists", + mLauncher.getWorkspace().tryGetPendingWidget(0) == null); // Item deleted from db mCursor = mResolver.query(LauncherSettings.Favorites.getContentUri(item.id), null, null, null, null, null); @@ -258,12 +247,12 @@ public class BindWidgetTest extends AbstractLauncherUiTest { * widget class is displayed on the homescreen. */ private void setupContents(LauncherAppWidgetInfo item) { - int screenId = Workspace.FIRST_SCREEN_ID; + int screenId = FIRST_SCREEN_ID; // Update the screen id counter for the provider. LauncherSettings.Settings.call(mResolver, LauncherSettings.Settings.METHOD_NEW_SCREEN_ID); - if (screenId > Workspace.FIRST_SCREEN_ID) { - screenId = Workspace.FIRST_SCREEN_ID; + if (screenId > FIRST_SCREEN_ID) { + screenId = FIRST_SCREEN_ID; } // Insert the item @@ -283,15 +272,13 @@ public class BindWidgetTest extends AbstractLauncherUiTest { } private void verifyWidgetPresent(LauncherAppWidgetProviderInfo info) { - UiSelector selector = new UiSelector().packageName(mTargetContext.getPackageName()) - .className(LauncherAppWidgetHostView.class).description(info.label); - assertTrue(mDevice.findObject(selector).waitForExists(DEFAULT_UI_TIMEOUT)); + assertTrue("Widget is not present", + mLauncher.getWorkspace().tryGetWidget(info.label, DEFAULT_UI_TIMEOUT) != null); } private void verifyPendingWidgetPresent() { - UiSelector selector = new UiSelector().packageName(mTargetContext.getPackageName()) - .className(PendingAppWidgetHostView.class); - assertTrue(mDevice.findObject(selector).waitForExists(DEFAULT_UI_TIMEOUT)); + assertTrue("Pending widget is not present", + mLauncher.getWorkspace().tryGetPendingWidget(DEFAULT_UI_TIMEOUT) != null); } /** diff --git a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java index a57d7bab8..6122daec2 100644 --- a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java +++ b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java @@ -15,6 +15,8 @@ */ package com.android.launcher3.ui.widget; +import static com.android.launcher3.ui.TaplTestsLauncher3.getAppPackageName; + import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; @@ -26,9 +28,6 @@ import android.view.View; import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; -import androidx.test.uiautomator.By; -import androidx.test.uiautomator.UiObject2; -import androidx.test.uiautomator.Until; import com.android.launcher3.ItemInfo; import com.android.launcher3.LauncherAppWidgetInfo; @@ -37,15 +36,14 @@ import com.android.launcher3.Utilities; import com.android.launcher3.Workspace.ItemOperator; import com.android.launcher3.WorkspaceItemInfo; import com.android.launcher3.shortcuts.ShortcutKey; +import com.android.launcher3.tapl.AddToHomeScreenPrompt; import com.android.launcher3.testcomponent.AppWidgetNoConfig; import com.android.launcher3.testcomponent.AppWidgetWithConfig; import com.android.launcher3.testcomponent.RequestPinItemActivity; import com.android.launcher3.ui.AbstractLauncherUiTest; -import com.android.launcher3.ui.TestViewHelpers; import com.android.launcher3.util.Condition; import com.android.launcher3.util.Wait; import com.android.launcher3.util.rule.ShellCommandRule; -import com.android.launcher3.widget.WidgetCell; import org.junit.Before; import org.junit.Rule; @@ -80,15 +78,10 @@ public class RequestPinItemTest extends AbstractLauncherUiTest { @Test public void testPinWidgetNoConfig() throws Throwable { - runTest("pinWidgetNoConfig", true, new ItemOperator() { - @Override - public boolean evaluate(ItemInfo info, View view) { - return info instanceof LauncherAppWidgetInfo && - ((LauncherAppWidgetInfo) info).appWidgetId == mAppWidgetId && - ((LauncherAppWidgetInfo) info).providerName.getClassName() - .equals(AppWidgetNoConfig.class.getName()); - } - }); + runTest("pinWidgetNoConfig", true, (info, view) -> info instanceof LauncherAppWidgetInfo && + ((LauncherAppWidgetInfo) info).appWidgetId == mAppWidgetId && + ((LauncherAppWidgetInfo) info).providerName.getClassName() + .equals(AppWidgetNoConfig.class.getName())); } @Test @@ -98,28 +91,19 @@ public class RequestPinItemTest extends AbstractLauncherUiTest { RequestPinItemActivity.class, "setRemoteViewColor").putExtra( RequestPinItemActivity.EXTRA_PARAM + "0", Color.RED); - runTest("pinWidgetNoConfig", true, new ItemOperator() { - @Override - public boolean evaluate(ItemInfo info, View view) { - return info instanceof LauncherAppWidgetInfo && - ((LauncherAppWidgetInfo) info).appWidgetId == mAppWidgetId && - ((LauncherAppWidgetInfo) info).providerName.getClassName() - .equals(AppWidgetNoConfig.class.getName()); - } - }, command); + runTest("pinWidgetNoConfig", true, (info, view) -> info instanceof LauncherAppWidgetInfo && + ((LauncherAppWidgetInfo) info).appWidgetId == mAppWidgetId && + ((LauncherAppWidgetInfo) info).providerName.getClassName() + .equals(AppWidgetNoConfig.class.getName()), command); } @Test public void testPinWidgetWithConfig() throws Throwable { - runTest("pinWidgetWithConfig", true, new ItemOperator() { - @Override - public boolean evaluate(ItemInfo info, View view) { - return info instanceof LauncherAppWidgetInfo && + runTest("pinWidgetWithConfig", true, + (info, view) -> info instanceof LauncherAppWidgetInfo && ((LauncherAppWidgetInfo) info).appWidgetId == mAppWidgetId && ((LauncherAppWidgetInfo) info).providerName.getClassName() - .equals(AppWidgetWithConfig.class.getName()); - } - }); + .equals(AppWidgetWithConfig.class.getName())); } @Test @@ -149,14 +133,14 @@ public class RequestPinItemTest extends AbstractLauncherUiTest { clearHomescreen(); mActivityMonitor.startLauncher(); - // Open all apps and wait for load complete - final UiObject2 appsContainer = TestViewHelpers.openAllApps(); - Wait.atMost(null, Condition.minChildCount(appsContainer, 2), DEFAULT_UI_TIMEOUT); - // Open Pin item activity BlockingBroadcastReceiver openMonitor = new BlockingBroadcastReceiver( RequestPinItemActivity.class.getName()); - scrollAndFind(appsContainer, By.text("Test Pin Item")).click(); + mLauncher. + getWorkspace(). + switchToAllApps(). + getAppIcon("Test Pin Item"). + launch(getAppPackageName()); assertNotNull(openMonitor.blockingGetExtraIntent()); // Set callback @@ -173,15 +157,11 @@ public class RequestPinItemTest extends AbstractLauncherUiTest { // call the requested method to start the flow mTargetContext.sendBroadcast(RequestPinItemActivity.getCommandIntent( RequestPinItemActivity.class, activityMethod)); - UiObject2 widgetCell = mDevice.wait( - Until.findObject(By.clazz(WidgetCell.class)), DEFAULT_ACTIVITY_TIMEOUT); - assertNotNull(widgetCell); + final AddToHomeScreenPrompt addToHomeScreenPrompt = mLauncher.getAddToHomeScreenPrompt(); // Accept confirmation: BlockingBroadcastReceiver resultReceiver = new BlockingBroadcastReceiver(mCallbackAction); - mDevice.wait(Until.findObject( - By.text(mLauncher.isAvd() ? "ADD AUTOMATICALLY" : "Add automatically")), - DEFAULT_UI_TIMEOUT).click(); + addToHomeScreenPrompt.addAutomatically(); Intent result = resultReceiver.blockingGetIntent(); assertNotNull(result); mAppWidgetId = result.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1); @@ -190,7 +170,7 @@ public class RequestPinItemTest extends AbstractLauncherUiTest { } // Go back to home - mActivityMonitor.returnToHome(); + mLauncher.pressHome(); Wait.atMost(null, new ItemSearchCondition(itemMatcher), DEFAULT_ACTIVITY_TIMEOUT); } diff --git a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java index 09cc98de0..eef2f24ba 100644 --- a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java +++ b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java @@ -4,7 +4,7 @@ import static androidx.test.InstrumentationRegistry.getInstrumentation; import android.util.Log; -import com.android.launcher3.ui.AbstractLauncherUiTest; +import androidx.test.uiautomator.UiDevice; import org.junit.rules.TestWatcher; import org.junit.runner.Description; @@ -16,16 +16,16 @@ import java.io.IOException; public class FailureWatcher extends TestWatcher { private static final String TAG = "FailureWatcher"; private static int sScreenshotCount = 0; - private AbstractLauncherUiTest mAbstractLauncherUiTest; + final private UiDevice mDevice; - public FailureWatcher(AbstractLauncherUiTest abstractLauncherUiTest) { - mAbstractLauncherUiTest = abstractLauncherUiTest; + public FailureWatcher(UiDevice device) { + mDevice = device; } private void dumpViewHierarchy() { final ByteArrayOutputStream stream = new ByteArrayOutputStream(); try { - mAbstractLauncherUiTest.getDevice().dumpWindowHierarchy(stream); + mDevice.dumpWindowHierarchy(stream); stream.flush(); stream.close(); for (String line : stream.toString().split("\\r?\\n")) { @@ -38,7 +38,7 @@ public class FailureWatcher extends TestWatcher { @Override protected void failed(Throwable e, Description description) { - if (mAbstractLauncherUiTest.getDevice() == null) return; + if (mDevice == null) return; final String pathname = getInstrumentation().getTargetContext(). getFilesDir().getPath() + "/TaplTestScreenshot" + sScreenshotCount++ + ".png"; Log.e(TAG, "Failed test " + description.getMethodName() + @@ -48,12 +48,12 @@ public class FailureWatcher extends TestWatcher { dumpViewHierarchy(); try { - final String dumpsysResult = mAbstractLauncherUiTest.getDevice().executeShellCommand( + final String dumpsysResult = mDevice.executeShellCommand( "dumpsys activity service TouchInteractionService"); Log.d(TAG, "TouchInteractionService: " + dumpsysResult); } catch (IOException ex) { } - mAbstractLauncherUiTest.getDevice().takeScreenshot(new File(pathname)); + mDevice.takeScreenshot(new File(pathname)); } } diff --git a/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java b/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java index 145c3c89e..2aba7a56d 100644 --- a/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java +++ b/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java @@ -72,11 +72,6 @@ public class LauncherActivityRule implements TestRule { getInstrumentation().startActivitySync(getHomeIntentInPackage(getTargetContext())); } - public void returnToHome() { - getTargetContext().startActivity(getHomeIntentInPackage(getTargetContext())); - getInstrumentation().waitForIdleSync(); - } - private class MyStatement extends Statement implements ActivityLifecycleCallbacks { private final Statement mBase; diff --git a/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java b/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java new file mode 100644 index 000000000..7f561a2af --- /dev/null +++ b/tests/tapl/com/android/launcher3/tapl/AddToHomeScreenPrompt.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.tapl; + +import androidx.test.uiautomator.By; +import androidx.test.uiautomator.UiObject2; + +public class AddToHomeScreenPrompt { + private final LauncherInstrumentation mLauncher; + private final UiObject2 mWidgetCell; + + AddToHomeScreenPrompt(LauncherInstrumentation launcher) { + mLauncher = launcher; + mWidgetCell = launcher.waitForLauncherObject(By.clazz( + "com.android.launcher3.widget.WidgetCell")); + mLauncher.assertNotNull("Can't find widget cell object", mWidgetCell); + } + + public void addAutomatically() { + mLauncher.waitForObjectInContainer( + mWidgetCell.getParent().getParent().getParent().getParent(), + By.text(LauncherInstrumentation.isAvd() + ? "ADD AUTOMATICALLY" + : "Add automatically")). + click(); + } +} diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java index 6c4619235..c9eaf276d 100644 --- a/tests/tapl/com/android/launcher3/tapl/Background.java +++ b/tests/tapl/com/android/launcher3/tapl/Background.java @@ -87,16 +87,24 @@ public class Background extends LauncherInstrumentation.VisibleContainer { } case TWO_BUTTON: { - final int centerX = mLauncher.getDevice().getDisplayWidth() / 2; - final int startY = getSwipeStartY(); - final int swipeHeight = mLauncher.getTestInfo(getSwipeHeightRequestName()). - getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD); - - mLauncher.swipeToState( - centerX, startY, centerX, - startY - swipeHeight - mLauncher.getTouchSlop(), - 10, - expectedState); + final int startX; + final int startY; + final int endX; + final int endY; + final int swipeLength = mLauncher.getTestInfo(getSwipeHeightRequestName()). + getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD) + mLauncher.getTouchSlop(); + + if (mLauncher.getDevice().isNaturalOrientation()) { + startX = endX = mLauncher.getDevice().getDisplayWidth() / 2; + startY = getSwipeStartY(); + endY = startY - swipeLength; + } else { + startX = getSwipeStartX(); + endX = startX - swipeLength; + startY = endY = mLauncher.getDevice().getDisplayHeight() / 2; + } + + mLauncher.swipeToState(startX, startY, endX, endY, 10, expectedState); break; } @@ -111,6 +119,10 @@ public class Background extends LauncherInstrumentation.VisibleContainer { return TestProtocol.REQUEST_BACKGROUND_TO_OVERVIEW_SWIPE_HEIGHT; } + protected int getSwipeStartX() { + return mLauncher.getRealDisplaySize().x - 1; + } + protected int getSwipeStartY() { return mLauncher.getRealDisplaySize().y - 1; } diff --git a/tests/tapl/com/android/launcher3/tapl/Folder.java b/tests/tapl/com/android/launcher3/tapl/Folder.java new file mode 100644 index 000000000..6e6734d81 --- /dev/null +++ b/tests/tapl/com/android/launcher3/tapl/Folder.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.tapl; + +import android.widget.FrameLayout; + +import androidx.test.uiautomator.By; +import androidx.test.uiautomator.BySelector; +import androidx.test.uiautomator.UiObject2; + +/** + * App folder in workspace/ + */ +public final class Folder { + Folder(LauncherInstrumentation launcher, UiObject2 icon) { + } + + static BySelector getSelector(String folderName, LauncherInstrumentation launcher) { + return By.clazz(FrameLayout.class).desc(folderName).pkg(launcher.getLauncherPackageName()); + } +} diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 2db9d0826..a7e633619 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -122,7 +122,7 @@ public final class LauncherInstrumentation { private static final String APPS_RES_ID = "apps_view"; private static final String OVERVIEW_RES_ID = "overview_panel"; private static final String WIDGETS_RES_ID = "widgets_list_view"; - public static final int WAIT_TIME_MS = 10000; + public static final int WAIT_TIME_MS = 60000; private static final String SYSTEMUI_PACKAGE = "com.android.systemui"; private static WeakReference<VisibleContainer> sActiveContainer = new WeakReference<>(null); @@ -315,25 +315,37 @@ public final class LauncherInstrumentation { mExpectedRotation = expectedRotation; } - private UiObject2 verifyContainerType(ContainerType containerType) { - assertEquals("Unexpected display rotation", - mExpectedRotation, mDevice.getDisplayRotation()); + public String getNavigationModeMismatchError() { final NavigationModel navigationModel = getNavigationModel(); final boolean hasRecentsButton = hasSystemUiObject("recent_apps"); final boolean hasHomeButton = hasSystemUiObject("home"); - assertTrue("Presence of recents button doesn't match the interaction mode, mode=" - + navigationModel.name() + ", hasRecents=" + hasRecentsButton, - (navigationModel == NavigationModel.THREE_BUTTON) == hasRecentsButton); - assertTrue("Presence of home button doesn't match the interaction mode, mode=" - + navigationModel.name() + ", hasHome=" + hasHomeButton, - (navigationModel != NavigationModel.ZERO_BUTTON) == hasHomeButton); + if ((navigationModel == NavigationModel.THREE_BUTTON) != hasRecentsButton) { + return "Presence of recents button doesn't match the interaction mode, mode=" + + navigationModel.name() + ", hasRecents=" + hasRecentsButton; + } + if ((navigationModel != NavigationModel.ZERO_BUTTON) != hasHomeButton) { + return "Presence of home button doesn't match the interaction mode, mode=" + + navigationModel.name() + ", hasHome=" + hasHomeButton; + } + return null; + } + + private UiObject2 verifyContainerType(ContainerType containerType) { + assertEquals("Unexpected display rotation", + mExpectedRotation, mDevice.getDisplayRotation()); + final String error = getNavigationModeMismatchError(); + assertTrue(error, error == null); log("verifyContainerType: " + containerType); try (Closable c = addContextLayer( "but the current state is not " + containerType.name())) { switch (containerType) { case WORKSPACE: { - waitForLauncherObject(APPS_RES_ID); + if (mDevice.isNaturalOrientation()) { + waitForLauncherObject(APPS_RES_ID); + } else { + waitUntilGone(APPS_RES_ID); + } waitUntilGone(OVERVIEW_RES_ID); waitUntilGone(WIDGETS_RES_ID); return waitForLauncherObject(WORKSPACE_RES_ID); @@ -490,6 +502,13 @@ public final class LauncherInstrumentation { } } + @NonNull + public AddToHomeScreenPrompt getAddToHomeScreenPrompt() { + try (LauncherInstrumentation.Closable c = addContextLayer("want to get widget cell")) { + return new AddToHomeScreenPrompt(this); + } + } + /** * Gets the Overview object if the current state is showing the overview panel. Fails if the * launcher is not in that state. @@ -504,17 +523,6 @@ public final class LauncherInstrumentation { } /** - * Gets the Base overview object if either Launcher is in overview state or the fallback - * overview activity is showing. Fails otherwise. - * - * @return BaseOverview object. - */ - @NonNull - public BaseOverview getBaseOverview() { - return new BaseOverview(this); - } - - /** * Gets the All Apps object if the current state is showing the all apps panel opened by swiping * from workspace. Fails if the launcher is not in that state. Please don't call this method if * App Apps was opened by swiping up from Overview, as it won't fail and will return an @@ -605,6 +613,16 @@ public final class LauncherInstrumentation { } @NonNull + UiObject2 waitForLauncherObject(BySelector selector) { + return waitForObjectBySelector(selector.pkg(getLauncherPackageName())); + } + + @NonNull + UiObject2 tryWaitForLauncherObject(BySelector selector, long timeout) { + return tryWaitForObjectBySelector(selector.pkg(getLauncherPackageName()), timeout); + } + + @NonNull UiObject2 waitForFallbackLauncherObject(String resName) { return waitForObjectBySelector(getFallbackLauncherObjectSelector(resName)); } @@ -615,6 +633,10 @@ public final class LauncherInstrumentation { return object; } + private UiObject2 tryWaitForObjectBySelector(BySelector selector, long timeout) { + return mDevice.wait(Until.findObject(selector), timeout); + } + BySelector getLauncherObjectSelector(String resName) { return By.res(getLauncherPackageName(), resName); } @@ -688,7 +710,7 @@ public final class LauncherInstrumentation { // Inject a swipe gesture. Inject exactly 'steps' motion points, incrementing event time by a // fixed interval each time. - private void linearGesture(int startX, int startY, int endX, int endY, int steps) { + void linearGesture(int startX, int startY, int endX, int endY, int steps) { final long downTime = SystemClock.uptimeMillis(); final Point start = new Point(startX, startY); final Point end = new Point(endX, endY); diff --git a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java index 8b124641f..641c41353 100644 --- a/tests/tapl/com/android/launcher3/tapl/OverviewTask.java +++ b/tests/tapl/com/android/launcher3/tapl/OverviewTask.java @@ -16,7 +16,8 @@ package com.android.launcher3.tapl; -import androidx.test.uiautomator.Direction; +import android.graphics.Rect; + import androidx.test.uiautomator.UiObject2; import androidx.test.uiautomator.Until; @@ -26,7 +27,6 @@ import com.android.launcher3.testing.TestProtocol; * A recent task in the overview panel carousel. */ public final class OverviewTask { - static final int FLING_SPEED = 3000; private static final long WAIT_TIME_MS = 60000; private final LauncherInstrumentation mLauncher; private final UiObject2 mTask; @@ -51,7 +51,10 @@ public final class OverviewTask { "want to dismiss a task")) { verifyActiveContainer(); // Dismiss the task via flinging it up. - mTask.fling(Direction.DOWN, (int) (FLING_SPEED * mLauncher.getDisplayDensity())); + final Rect taskBounds = mTask.getVisibleBounds(); + final int centerX = taskBounds.centerX(); + final int centerY = taskBounds.centerY(); + mLauncher.linearGesture(centerX, centerY, centerX, 0, 10); mLauncher.waitForIdle(); } } diff --git a/tests/tapl/com/android/launcher3/tapl/Widget.java b/tests/tapl/com/android/launcher3/tapl/Widget.java new file mode 100644 index 000000000..128789dbc --- /dev/null +++ b/tests/tapl/com/android/launcher3/tapl/Widget.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.tapl; + +import androidx.test.uiautomator.UiObject2; + +public class Widget { + Widget(LauncherInstrumentation launcher, UiObject2 widget) { + } +} diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java index 33754c125..b01b6f363 100644 --- a/tests/tapl/com/android/launcher3/tapl/Workspace.java +++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java @@ -27,6 +27,7 @@ import android.view.MotionEvent; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.test.uiautomator.By; import androidx.test.uiautomator.Direction; import androidx.test.uiautomator.UiObject2; @@ -142,11 +143,17 @@ public final class Workspace extends Home { } @NonNull - private AppIcon getHotseatAppIcon(String appName) { + public AppIcon getHotseatAppIcon(String appName) { return new AppIcon(mLauncher, mLauncher.getObjectInContainer( mHotseat, AppIcon.getAppIconSelector(appName, mLauncher))); } + @NonNull + public Folder getHotseatFolder(String appName) { + return new Folder(mLauncher, mLauncher.getObjectInContainer( + mHotseat, Folder.getSelector(appName, mLauncher))); + } + static void dragIconToWorkspace( LauncherInstrumentation launcher, Launchable launchable, Point dest, String longPressIndicator) { @@ -213,6 +220,21 @@ public final class Workspace extends Home { @Override protected int getSwipeStartY() { - return mLauncher.waitForLauncherObject("hotseat").getVisibleBounds().top; + return mLauncher.getRealDisplaySize().y - 1; + } + + @Nullable + public Widget tryGetWidget(String label, long timeout) { + final UiObject2 widget = mLauncher.tryWaitForLauncherObject( + By.clazz("com.android.launcher3.widget.LauncherAppWidgetHostView").desc(label), + timeout); + return widget != null ? new Widget(mLauncher, widget) : null; + } + + @Nullable + public Widget tryGetPendingWidget(long timeout) { + final UiObject2 widget = mLauncher.tryWaitForLauncherObject( + By.clazz("com.android.launcher3.widget.PendingAppWidgetHostView"), timeout); + return widget != null ? new Widget(mLauncher, widget) : null; } }
\ No newline at end of file |