Files
Lawnchair/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java
T
vadimt d4c90e12e9 Freezing all apps updates during certain tests
This CL adds a very low risk because most (but not all) changes affect
only Launcher behavior during the test.

This should fix a lab-only flake when all apps keeps changing while
the test is working with it.

Example: test figures out which icon to click, by the moment it clicks
there, there is another icon there, or the icon is under the search box,
and clicking opens IME.

Switching test devices to airplane mode didn't help. The earlier change
that prevents popup menu cancellation is not general enough.

Now the tests are given an API to explicitly freeze and unfreeze
all-apps, which should be a final solution.

Bug: 132900132
Bug: 133765434
Change-Id: I8b81cc9be004482beb6cdcdd05406e2d9b4c7629
2019-06-06 11:10:56 -07:00

362 lines
14 KiB
Java

/*
* 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.ui;
import static androidx.test.InstrumentationRegistry.getInstrumentation;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.popup.ArrowPopup;
import com.android.launcher3.tapl.AllApps;
import com.android.launcher3.tapl.AppIcon;
import com.android.launcher3.tapl.AppIconMenu;
import com.android.launcher3.tapl.AppIconMenuItem;
import com.android.launcher3.tapl.TestHelpers;
import com.android.launcher3.tapl.Widgets;
import com.android.launcher3.tapl.Workspace;
import com.android.launcher3.views.OptionsPopupView;
import com.android.launcher3.widget.WidgetsFullSheet;
import com.android.launcher3.widget.WidgetsRecyclerView;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@LargeTest
@RunWith(AndroidJUnit4.class)
public class TaplTestsLauncher3 extends AbstractLauncherUiTest {
private static final String APP_NAME = "LauncherTestApp";
@Before
public void setUp() throws Exception {
super.setUp();
initialize(this);
}
public static void initialize(AbstractLauncherUiTest test) throws Exception {
test.clearLauncherData();
if (TestHelpers.isInLauncherProcess()) {
test.mActivityMonitor.returnToHome();
} else {
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");
// Check that we switched to home.
test.mLauncher.getWorkspace();
}
// Please don't add negative test cases for methods that fail only after a long wait.
public static void expectFail(String message, Runnable action) {
boolean failed = false;
try {
action.run();
} catch (AssertionError e) {
failed = true;
}
assertTrue(message, failed);
}
private boolean isWorkspaceScrollable(Launcher launcher) {
return launcher.getWorkspace().getPageCount() > 1;
}
private int getCurrentWorkspacePage(Launcher launcher) {
return launcher.getWorkspace().getCurrentPage();
}
private WidgetsRecyclerView getWidgetsView(Launcher launcher) {
return WidgetsFullSheet.getWidgetsView(launcher);
}
@Test
public void testDevicePressMenu() throws Exception {
mDevice.pressMenu();
mDevice.waitForIdle();
executeOnLauncher(
launcher -> assertTrue("Launcher internal state didn't switch to Showing Menu",
OptionsPopupView.getOptionsPopup(launcher) != null));
// Check that pressHome works when the menu is shown.
mLauncher.pressHome();
}
@Test
@Ignore
public void testPressHomeOnAllAppsContextMenu() throws Exception {
final AllApps allApps = mLauncher.getWorkspace().switchToAllApps();
allApps.freeze();
try {
allApps.getAppIcon("TestActivity7").openMenu();
} finally {
allApps.unfreeze();
}
mLauncher.pressHome();
}
public static void runAllAppsTest(AbstractLauncherUiTest test, AllApps allApps) {
allApps.freeze();
try {
assertNotNull("allApps parameter is null", allApps);
assertTrue(
"Launcher internal state is not All Apps",
test.isInState(LauncherState.ALL_APPS));
// Test flinging forward and backward.
test.executeOnLauncher(launcher -> assertEquals(
"All Apps started in already scrolled state", 0,
test.getAllAppsScroll(launcher)));
allApps.flingForward();
assertTrue("Launcher internal state is not All Apps",
test.isInState(LauncherState.ALL_APPS));
final Integer flingForwardY = test.getFromLauncher(
launcher -> test.getAllAppsScroll(launcher));
test.executeOnLauncher(
launcher -> assertTrue("flingForward() didn't scroll App Apps",
flingForwardY > 0));
allApps.flingBackward();
assertTrue(
"Launcher internal state is not All Apps",
test.isInState(LauncherState.ALL_APPS));
final Integer flingBackwardY = test.getFromLauncher(
launcher -> test.getAllAppsScroll(launcher));
test.executeOnLauncher(launcher -> assertTrue("flingBackward() didn't scroll App Apps",
flingBackwardY < flingForwardY));
// Test scrolling down to YouTube.
assertNotNull("All apps: can't fine YouTube", allApps.getAppIcon("YouTube"));
// Test scrolling up to Camera.
assertNotNull("All apps: can't fine Camera", allApps.getAppIcon("Camera"));
// Test failing to find a non-existing app.
final AllApps allAppsFinal = allApps;
expectFail("All apps: could find a non-existing app",
() -> allAppsFinal.getAppIcon("NO APP"));
assertTrue(
"Launcher internal state is not All Apps",
test.isInState(LauncherState.ALL_APPS));
} finally {
allApps.unfreeze();
}
}
@Test
@PortraitLandscape
public void testWorkspaceSwitchToAllApps() {
assertNotNull("switchToAllApps() returned null",
mLauncher.getWorkspace().switchToAllApps());
assertTrue("Launcher internal state is not All Apps", isInState(LauncherState.ALL_APPS));
}
@Test
public void testWorkspace() throws Exception {
final Workspace workspace = mLauncher.getWorkspace();
// Test that ensureWorkspaceIsScrollable adds a page by dragging an icon there.
executeOnLauncher(launcher -> assertFalse("Initial workspace state is scrollable",
isWorkspaceScrollable(launcher)));
assertNull("Chrome app was found on empty workspace",
workspace.tryGetWorkspaceAppIcon("Chrome"));
workspace.ensureWorkspaceIsScrollable();
executeOnLauncher(
launcher -> assertEquals("Ensuring workspace scrollable didn't switch to page #1",
1, getCurrentWorkspacePage(launcher)));
executeOnLauncher(
launcher -> assertTrue("ensureScrollable didn't make workspace scrollable",
isWorkspaceScrollable(launcher)));
assertNotNull("ensureScrollable didn't add Chrome app",
workspace.tryGetWorkspaceAppIcon("Chrome"));
// Test flinging workspace.
workspace.flingBackward();
assertTrue("Launcher internal state is not Home", isInState(LauncherState.NORMAL));
executeOnLauncher(
launcher -> assertEquals("Flinging back didn't switch workspace to page #0",
0, getCurrentWorkspacePage(launcher)));
workspace.flingForward();
executeOnLauncher(
launcher -> assertEquals("Flinging forward didn't switch workspace to page #1",
1, getCurrentWorkspacePage(launcher)));
assertTrue("Launcher internal state is not Home", isInState(LauncherState.NORMAL));
// Test starting a workspace app.
final AppIcon app = workspace.tryGetWorkspaceAppIcon("Chrome");
assertNotNull("No Chrome app in workspace", app);
}
public static void runIconLaunchFromAllAppsTest(AbstractLauncherUiTest test, AllApps allApps) {
allApps.freeze();
try {
final AppIcon app = allApps.getAppIcon("TestActivity7");
assertNotNull("AppIcon.launch returned null", app.launch(getAppPackageName()));
test.executeOnLauncher(launcher -> assertTrue(
"Launcher activity is the top activity; expecting another activity to be the top "
+ "one",
test.isInBackground(launcher)));
} finally {
allApps.unfreeze();
}
}
@Test
@PortraitLandscape
public void testAppIconLaunchFromAllAppsFromHome() throws Exception {
final AllApps allApps = mLauncher.getWorkspace().switchToAllApps();
assertTrue("Launcher internal state is not All Apps", isInState(LauncherState.ALL_APPS));
runIconLaunchFromAllAppsTest(this, allApps);
}
@Test
@PortraitLandscape
public void testWidgets() throws Exception {
// Test opening widgets.
executeOnLauncher(launcher ->
assertTrue("Widgets is initially opened", getWidgetsView(launcher) == null));
Widgets widgets = mLauncher.getWorkspace().openAllWidgets();
assertNotNull("openAllWidgets() returned null", widgets);
widgets = mLauncher.getAllWidgets();
assertNotNull("getAllWidgets() returned null", widgets);
executeOnLauncher(launcher ->
assertTrue("Widgets is not shown", getWidgetsView(launcher).isShown()));
executeOnLauncher(launcher -> assertEquals("Widgets is scrolled upon opening",
0, getWidgetsScroll(launcher)));
// Test flinging widgets.
widgets.flingForward();
Integer flingForwardY = getFromLauncher(launcher -> getWidgetsScroll(launcher));
executeOnLauncher(launcher -> assertTrue("Flinging forward didn't scroll widgets",
flingForwardY > 0));
widgets.flingBackward();
executeOnLauncher(launcher -> assertTrue("Flinging backward didn't scroll widgets",
getWidgetsScroll(launcher) < flingForwardY));
mLauncher.pressHome();
waitForLauncherCondition("Widgets were not closed",
launcher -> getWidgetsView(launcher) == null);
}
private int getWidgetsScroll(Launcher launcher) {
return getWidgetsView(launcher).getCurrentScrollY();
}
private boolean isOptionsPopupVisible(Launcher launcher) {
final ArrowPopup popup = OptionsPopupView.getOptionsPopup(launcher);
return popup != null && popup.isShown();
}
@Test
@PortraitLandscape
public void testLaunchMenuItem() throws Exception {
if (!TestHelpers.isInLauncherProcess()) return;
final AllApps allApps = mLauncher.
getWorkspace().
switchToAllApps();
allApps.freeze();
try {
final AppIconMenu menu = allApps.
getAppIcon(APP_NAME).
openMenu();
executeOnLauncher(
launcher -> assertTrue("Launcher internal state didn't switch to Showing Menu",
isOptionsPopupVisible(launcher)));
menu.getMenuItem(1).launch(getAppPackageName());
} finally {
allApps.unfreeze();
}
}
@Test
@PortraitLandscape
public void testDragAppIcon() throws Throwable {
// 1. Open all apps and wait for load complete.
// 2. Drag icon to homescreen.
// 3. Verify that the icon works on homescreen.
final AllApps allApps = mLauncher.getWorkspace().
switchToAllApps();
allApps.freeze();
try {
allApps.
getAppIcon(APP_NAME).
dragToWorkspace().
getWorkspaceAppIcon(APP_NAME).
launch(getAppPackageName());
} finally {
allApps.unfreeze();
}
executeOnLauncher(launcher -> assertTrue(
"Launcher activity is the top activity; expecting another activity to be the top "
+ "one",
isInBackground(launcher)));
}
@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
final AllApps allApps = mLauncher.
getWorkspace().
switchToAllApps();
allApps.freeze();
try {
final AppIconMenuItem menuItem = allApps.
getAppIcon(APP_NAME).
openMenu().
getMenuItem(0);
final String shortcutName = menuItem.getText();
// 4. Drag the first shortcut to the home screen.
// 5. Verify that the shortcut works on home screen
// (the app opens and has the same text as the shortcut).
menuItem.
dragToWorkspace().
getWorkspaceAppIcon(shortcutName).
launch(getAppPackageName());
} finally {
allApps.unfreeze();
}
}
public static String getAppPackageName() {
return getInstrumentation().getContext().getPackageName();
}
}