Improving TAPL diagnostics

Bug: 128531133
Change-Id: If81861afccb665e2dc2293f2704d99818b3297c8
This commit is contained in:
vadimt 2019-03-22 18:15:35 -07:00
parent 6d862386fb
commit 4397d8d5ea
11 changed files with 308 additions and 193 deletions

View File

@ -60,30 +60,39 @@ public class AllApps extends LauncherInstrumentation.VisibleContainer {
*/
@NonNull
public AppIcon getAppIcon(String appName) {
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"want to get app icon on all apps")) {
final UiObject2 allAppsContainer = verifyActiveContainer();
final BySelector appIconSelector = AppIcon.getAppIconSelector(appName, mLauncher);
if (!hasClickableIcon(allAppsContainer, appIconSelector)) {
scrollBackToBeginning();
int attempts = 0;
try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer("scrolled")) {
while (!hasClickableIcon(allAppsContainer, appIconSelector) &&
allAppsContainer.scroll(Direction.DOWN, 0.8f)) {
LauncherInstrumentation.assertTrue(
mLauncher.assertTrue(
"Exceeded max scroll attempts: " + MAX_SCROLL_ATTEMPTS,
++attempts <= MAX_SCROLL_ATTEMPTS);
verifyActiveContainer();
}
}
verifyActiveContainer();
}
final UiObject2 appIcon = mLauncher.getObjectInContainer(allAppsContainer, appIconSelector);
final UiObject2 appIcon = mLauncher.getObjectInContainer(allAppsContainer,
appIconSelector);
ensureIconVisible(appIcon, allAppsContainer);
return new AppIcon(mLauncher, appIcon);
}
}
private void scrollBackToBeginning() {
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"want to scroll back in all apps")) {
final UiObject2 allAppsContainer = verifyActiveContainer();
final UiObject2 searchBox =
mLauncher.waitForObjectInContainer(allAppsContainer, "search_container_all_apps");
mLauncher.waitForObjectInContainer(allAppsContainer,
"search_container_all_apps");
int attempts = 0;
allAppsContainer.setGestureMargins(0, searchBox.getVisibleBounds().bottom + 1, 0, 5);
@ -91,17 +100,20 @@ public class AllApps extends LauncherInstrumentation.VisibleContainer {
for (int scroll = getScroll(allAppsContainer);
scroll != 0;
scroll = getScroll(allAppsContainer)) {
LauncherInstrumentation.assertTrue("Negative scroll position", scroll > 0);
mLauncher.assertTrue("Negative scroll position", scroll > 0);
LauncherInstrumentation.assertTrue(
mLauncher.assertTrue(
"Exceeded max scroll attempts: " + MAX_SCROLL_ATTEMPTS,
++attempts <= MAX_SCROLL_ATTEMPTS);
allAppsContainer.scroll(Direction.UP, 1);
}
try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer("scrolled up")) {
verifyActiveContainer();
}
}
}
private int getScroll(UiObject2 allAppsContainer) {
return mLauncher.getAnswerFromLauncher(allAppsContainer, TestProtocol.GET_SCROLL_MESSAGE).
@ -115,30 +127,41 @@ public class AllApps extends LauncherInstrumentation.VisibleContainer {
// to reveal the app icon to have the MIN_INTERACT_SIZE
final float pct = Math.max(((float) (MIN_INTERACT_SIZE - appHeight)) / mHeight, 0.2f);
allAppsContainer.scroll(Direction.DOWN, pct);
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"scrolled an icon in all apps to make it visible - and then")) {
mLauncher.waitForIdle();
verifyActiveContainer();
}
}
}
/**
* Flings forward (down) and waits the fling's end.
*/
public void flingForward() {
try(LauncherInstrumentation.Closable c =
mLauncher.addContextLayer("want to fling forward in all apps")) {
final UiObject2 allAppsContainer = verifyActiveContainer();
// Start the gesture in the center to avoid starting at elements near the top.
allAppsContainer.setGestureMargins(0, 0, 0, mHeight / 2);
allAppsContainer.fling(Direction.DOWN, (int) (FLING_SPEED * mLauncher.getDisplayDensity()));
allAppsContainer.fling(Direction.DOWN,
(int) (FLING_SPEED * mLauncher.getDisplayDensity()));
verifyActiveContainer();
}
}
/**
* Flings backward (up) and waits the fling's end.
*/
public void flingBackward() {
try(LauncherInstrumentation.Closable c =
mLauncher.addContextLayer("want to fling backward in all apps")) {
final UiObject2 allAppsContainer = verifyActiveContainer();
// Start the gesture in the center, for symmetry with forward.
allAppsContainer.setGestureMargins(0, mHeight / 2, 0, 0);
allAppsContainer.fling(Direction.UP, (int) (FLING_SPEED * mLauncher.getDisplayDensity()));
allAppsContainer.fling(Direction.UP,
(int) (FLING_SPEED * mLauncher.getDisplayDensity()));
verifyActiveContainer();
}
}
}

View File

@ -42,6 +42,8 @@ public final class AllAppsFromOverview extends AllApps {
*/
@NonNull
public Overview switchBackToOverview() {
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"want to switch back from all apps to overview")) {
final UiObject2 allAppsContainer = verifyActiveContainer();
// Swipe from the search box to the bottom.
final UiObject2 qsb = mLauncher.waitForObjectInContainer(
@ -55,7 +57,9 @@ public final class AllAppsFromOverview extends AllApps {
LauncherInstrumentation.log("AllAppsFromOverview.switchBackToOverview before swipe");
mLauncher.swipe(start.x, start.y, start.x, endY, OVERVIEW_STATE_ORDINAL);
try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer("swiped down")) {
return new Overview(mLauncher);
}
}
}
}

View File

@ -57,12 +57,15 @@ public class Background extends LauncherInstrumentation.VisibleContainer {
*/
@NonNull
public BaseOverview switchToOverview() {
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"want to switch from background to overview")) {
verifyActiveContainer();
goToOverviewUnchecked(BACKGROUND_APP_STATE_ORDINAL);
assertTrue("Overview not visible", mLauncher.getDevice().wait(
Until.hasObject(By.pkg(getOverviewPackageName())), WAIT_TIME_MS));
return new BaseOverview(mLauncher);
}
}
protected void goToOverviewUnchecked(int expectedState) {
switch (mLauncher.getNavigationModel()) {

View File

@ -44,6 +44,8 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer {
* Flings forward (left) and waits the fling's end.
*/
public void flingForward() {
try (LauncherInstrumentation.Closable c =
mLauncher.addContextLayer("want to fling forward in overview")) {
LauncherInstrumentation.log("Overview.flingForward before fling");
final UiObject2 overview = verifyActiveContainer();
final int margin = (int) (50 * mLauncher.getDisplayDensity()) + 1;
@ -52,11 +54,14 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer {
mLauncher.waitForIdle();
verifyActiveContainer();
}
}
/**
* Dismissed all tasks by scrolling to Clear-all button and pressing it.
*/
public Workspace dismissAllTasks() {
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"dismissing all tasks")) {
final BySelector clearAllSelector = mLauncher.getLauncherObjectSelector("clear_all");
for (int i = 0;
i < FLINGS_FOR_DISMISS_LIMIT
@ -66,13 +71,19 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer {
}
mLauncher.getObjectInContainer(verifyActiveContainer(), clearAllSelector).click();
try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
"dismissed all tasks")) {
return new Workspace(mLauncher);
}
}
}
/**
* Flings backward (right) and waits the fling's end.
*/
public void flingBackward() {
try (LauncherInstrumentation.Closable c =
mLauncher.addContextLayer("want to fling backward in overview")) {
LauncherInstrumentation.log("Overview.flingBackward before fling");
final UiObject2 overview = verifyActiveContainer();
final int margin = (int) (50 * mLauncher.getDisplayDensity()) + 1;
@ -81,6 +92,7 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer {
mLauncher.waitForIdle();
verifyActiveContainer();
}
}
/**
* Gets the current task in the carousel, or fails if the carousel is empty.
@ -89,10 +101,12 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer {
*/
@NonNull
public OverviewTask getCurrentTask() {
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"want to get current task")) {
verifyActiveContainer();
final List<UiObject2> taskViews = mLauncher.getDevice().findObjects(
mLauncher.getLauncherObjectSelector("snapshot"));
LauncherInstrumentation.assertNotEquals("Unable to find a task", 0, taskViews.size());
mLauncher.assertNotEquals("Unable to find a task", 0, taskViews.size());
// taskViews contains up to 3 task views: the 'main' (having the widest visible
// part) one in the center, and parts of its right and left siblings. Find the
@ -103,4 +117,5 @@ public class BaseOverview extends LauncherInstrumentation.VisibleContainer {
return new OverviewTask(mLauncher, widestTask, this);
}
}
}

View File

@ -48,8 +48,14 @@ public abstract class Home extends Background {
@NonNull
@Override
public Overview switchToOverview() {
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"want to switch from home to overview")) {
verifyActiveContainer();
goToOverviewUnchecked(OVERVIEW_STATE_ORDINAL);
try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
"performed the switch action")) {
return new Overview(mLauncher);
}
}
}
}

View File

@ -59,10 +59,10 @@ class Launchable {
private Background launch(String errorMessage, BySelector selector) {
LauncherInstrumentation.log("Launchable.launch before click " +
mObject.getVisibleCenter());
LauncherInstrumentation.assertTrue(
mLauncher.assertTrue(
"Launching an app didn't open a new window: " + mObject.getText(),
mObject.clickAndWait(Until.newWindow(), LauncherInstrumentation.WAIT_TIME_MS));
LauncherInstrumentation.assertTrue(
mLauncher.assertTrue(
"App didn't start: " + errorMessage,
mLauncher.getDevice().wait(Until.hasObject(selector),
LauncherInstrumentation.WAIT_TIME_MS));
@ -79,6 +79,9 @@ class Launchable {
this,
new Point(device.getDisplayWidth() / 2, device.getDisplayHeight() / 2),
DRAG_SPEED);
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"dragged launchable to workspace")) {
return new Workspace(mLauncher);
}
}
}

View File

@ -54,6 +54,8 @@ import org.junit.Assert;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeoutException;
@ -91,11 +93,16 @@ public final class LauncherInstrumentation {
* @return UI object for the container.
*/
final UiObject2 verifyActiveContainer() {
assertTrue("Attempt to use a stale container", this == sActiveContainer.get());
mLauncher.assertTrue("Attempt to use a stale container",
this == sActiveContainer.get());
return mLauncher.verifyContainerType(getContainerType());
}
}
interface Closable extends AutoCloseable {
void close();
}
private static final String WORKSPACE_RES_ID = "workspace";
private static final String APPS_RES_ID = "apps_view";
private static final String OVERVIEW_RES_ID = "overview_panel";
@ -109,6 +116,7 @@ public final class LauncherInstrumentation {
private final Instrumentation mInstrumentation;
private int mExpectedRotation = Surface.ROTATION_0;
private final Uri mTestProviderUri;
private final Deque<String> mDiagnosticContext = new LinkedList<>();
/**
* Constructs the root of TAPL hierarchy. You get all other objects from it.
@ -180,31 +188,38 @@ public final class LauncherInstrumentation {
Log.d(TAG, message);
}
private static void fail(String message) {
Assert.fail("http://go/tapl : " + message);
Closable addContextLayer(String piece) {
mDiagnosticContext.addLast(piece);
return () -> mDiagnosticContext.removeLast();
}
static void assertTrue(String message, boolean condition) {
private void fail(String message) {
final String ctxt = mDiagnosticContext.isEmpty() ? "" : String.join(", ",
mDiagnosticContext) + "; ";
Assert.fail("http://go/tapl : " + ctxt + message);
}
void assertTrue(String message, boolean condition) {
if (!condition) {
fail(message);
}
}
static void assertNotNull(String message, Object object) {
void assertNotNull(String message, Object object) {
assertTrue(message, object != null);
}
static private void failEquals(String message, Object actual) {
private void failEquals(String message, Object actual) {
fail(message + ". " + "Actual: " + actual);
}
static private void assertEquals(String message, int expected, int actual) {
private void assertEquals(String message, int expected, int actual) {
if (expected != actual) {
fail(message + " expected: " + expected + " but was: " + actual);
}
}
static void assertNotEquals(String message, int unexpected, int actual) {
void assertNotEquals(String message, int unexpected, int actual) {
if (unexpected == actual) {
failEquals(message, actual);
}
@ -222,6 +237,8 @@ public final class LauncherInstrumentation {
(mDevice.findObject(By.res(SYSTEMUI_PACKAGE, "recent_apps")) == null));
log("verifyContainerType: " + containerType);
try (Closable c = addContextLayer(
"but the current state is not " + containerType.name())) {
switch (containerType) {
case WORKSPACE: {
waitForLauncherObject(APPS_RES_ID);
@ -267,6 +284,7 @@ public final class LauncherInstrumentation {
return null;
}
}
}
private Parcelable executeAndWaitForEvent(Runnable command,
UiAutomation.AccessibilityEventFilter eventFilter, String message) {
@ -356,8 +374,10 @@ public final class LauncherInstrumentation {
*/
@NonNull
public Workspace getWorkspace() {
try (LauncherInstrumentation.Closable c = addContextLayer("want to get workspace object")) {
return new Workspace(this);
}
}
/**
* Gets the Workspace object if the current state is "background home", i.e. some other app is
@ -378,8 +398,10 @@ public final class LauncherInstrumentation {
*/
@NonNull
public Widgets getAllWidgets() {
try (LauncherInstrumentation.Closable c = addContextLayer("want to get widgets")) {
return new Widgets(this);
}
}
/**
* Gets the Overview object if the current state is showing the overview panel. Fails if the
@ -389,8 +411,10 @@ public final class LauncherInstrumentation {
*/
@NonNull
public Overview getOverview() {
try (LauncherInstrumentation.Closable c = addContextLayer("want to get overview")) {
return new Overview(this);
}
}
/**
* Gets the Base overview object if either Launcher is in overview state or the fallback
@ -413,8 +437,10 @@ public final class LauncherInstrumentation {
*/
@NonNull
public AllApps getAllApps() {
try (LauncherInstrumentation.Closable c = addContextLayer("want to get all apps object")) {
return new AllApps(this);
}
}
/**
* Gets the All Apps object if the current state is showing the all apps panel opened by swiping
@ -426,8 +452,10 @@ public final class LauncherInstrumentation {
*/
@NonNull
public AllAppsFromOverview getAllAppsFromOverview() {
try (LauncherInstrumentation.Closable c = addContextLayer("want to get all apps object")) {
return new AllAppsFromOverview(this);
}
}
void waitUntilGone(String resId) {
assertTrue("Unexpected launcher object visible: " + resId,

View File

@ -20,11 +20,11 @@ import static com.android.launcher3.TestProtocol.ALL_APPS_STATE_ORDINAL;
import android.graphics.Point;
import com.android.launcher3.tapl.LauncherInstrumentation.ContainerType;
import androidx.annotation.NonNull;
import androidx.test.uiautomator.UiObject2;
import com.android.launcher3.tapl.LauncherInstrumentation.ContainerType;
/**
* Overview pane.
*/
@ -47,6 +47,8 @@ public final class Overview extends BaseOverview {
*/
@NonNull
public AllAppsFromOverview switchToAllApps() {
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"want to switch from overview to all apps")) {
verifyActiveContainer();
// Swipe from navbar to the top.
@ -55,6 +57,10 @@ public final class Overview extends BaseOverview {
LauncherInstrumentation.log("Overview.switchToAllApps before swipe");
mLauncher.swipe(start.x, start.y, start.x, 0, ALL_APPS_STATE_ORDINAL);
try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
"swiped all way up from overview")) {
return new AllAppsFromOverview(mLauncher);
}
}
}
}

View File

@ -44,18 +44,21 @@ public final class OverviewTask {
* Swipes the task up.
*/
public void dismiss() {
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"want to dismiss a task")) {
verifyActiveContainer();
// Dismiss the task via flinging it up.
mTask.fling(Direction.DOWN, (int) (FLING_SPEED * mLauncher.getDisplayDensity()));
mLauncher.waitForIdle();
}
}
/**
* Clicks at the task.
*/
public Background open() {
verifyActiveContainer();
LauncherInstrumentation.assertTrue("Launching task didn't open a new window: " +
mLauncher.assertTrue("Launching task didn't open a new window: " +
mTask.getParent().getContentDescription(),
mTask.clickAndWait(Until.newWindow(), LauncherInstrumentation.WAIT_TIME_MS));
return new Background(mLauncher);

View File

@ -34,22 +34,34 @@ public final class Widgets extends LauncherInstrumentation.VisibleContainer {
* Flings forward (down) and waits the fling's end.
*/
public void flingForward() {
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"want to fling forward in widgets")) {
final UiObject2 widgetsContainer = verifyActiveContainer();
widgetsContainer.setGestureMargin(100);
widgetsContainer.fling(Direction.DOWN, (int) (FLING_SPEED * mLauncher.getDisplayDensity()));
widgetsContainer.fling(Direction.DOWN,
(int) (FLING_SPEED * mLauncher.getDisplayDensity()));
try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer("flung forward")) {
verifyActiveContainer();
}
}
}
/**
* Flings backward (up) and waits the fling's end.
*/
public void flingBackward() {
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"want to fling backwards in widgets")) {
final UiObject2 widgetsContainer = verifyActiveContainer();
widgetsContainer.setGestureMargin(100);
widgetsContainer.fling(Direction.UP, (int) (FLING_SPEED * mLauncher.getDisplayDensity()));
widgetsContainer.fling(Direction.UP,
(int) (FLING_SPEED * mLauncher.getDisplayDensity()));
mLauncher.waitForIdle();
try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer("flung back")) {
verifyActiveContainer();
}
}
}
@Override
protected LauncherInstrumentation.ContainerType getContainerType() {

View File

@ -50,6 +50,8 @@ public final class Workspace extends Home {
*/
@NonNull
public AllApps switchToAllApps() {
try(LauncherInstrumentation.Closable c =
mLauncher.addContextLayer("want to switch from workspace to all apps")) {
verifyActiveContainer();
final UiObject2 hotseat = mHotseat;
final Point start = hotseat.getVisibleCenter();
@ -64,8 +66,12 @@ public final class Workspace extends Home {
ALL_APPS_STATE_ORDINAL
);
try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer(
"swiped to all apps")) {
return new AllApps(mLauncher);
}
}
}
/**
* Returns an icon for the app, if currently visible.
@ -75,10 +81,14 @@ public final class Workspace extends Home {
*/
@Nullable
public AppIcon tryGetWorkspaceAppIcon(String appName) {
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer(
"want to get a workspace icon")) {
final UiObject2 workspace = verifyActiveContainer();
final UiObject2 icon = workspace.findObject(AppIcon.getAppIconSelector(appName, mLauncher));
final UiObject2 icon = workspace.findObject(
AppIcon.getAppIconSelector(appName, mLauncher));
return icon != null ? new AppIcon(mLauncher, icon) : null;
}
}
/**
@ -165,8 +175,10 @@ public final class Workspace extends Home {
public Widgets openAllWidgets() {
verifyActiveContainer();
mLauncher.getDevice().pressKeyCode(KeyEvent.KEYCODE_W, KeyEvent.META_CTRL_ON);
try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer("pressed Ctrl+W")) {
return new Widgets(mLauncher);
}
}
@Override
protected String getSwipeHeightRequestName() {