diff --git a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java index df88726f68..094fd4c823 100644 --- a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java +++ b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java @@ -205,11 +205,10 @@ public class NavigationModeSwitchRule implements TestRule { boolean condition, Description description) { launcher.checkForAnomaly(true, true); if (!condition) { - final AssertionError assertionError = new AssertionError(message); if (description != null) { - FailureWatcher.onError(launcher, description, assertionError); + FailureWatcher.onError(launcher, description); } - throw assertionError; + throw new AssertionError(message); } } } diff --git a/quickstep/tests/src/com/android/quickstep/TaskbarModeSwitchRule.java b/quickstep/tests/src/com/android/quickstep/TaskbarModeSwitchRule.java index e5657fb644..84ceb332d9 100644 --- a/quickstep/tests/src/com/android/quickstep/TaskbarModeSwitchRule.java +++ b/quickstep/tests/src/com/android/quickstep/TaskbarModeSwitchRule.java @@ -130,11 +130,10 @@ public class TaskbarModeSwitchRule implements TestRule { boolean condition, Description description) { launcher.checkForAnomaly(true, true); if (!condition) { - final AssertionError assertionError = new AssertionError(message); if (description != null) { - FailureWatcher.onError(launcher, description, assertionError); + FailureWatcher.onError(launcher, description); } - throw assertionError; + throw new AssertionError(message); } } } diff --git a/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java b/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java index c4e74f20fa..e5c5c196bf 100644 --- a/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java +++ b/tests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java @@ -57,7 +57,7 @@ public class PortraitLandscapeRunner implements true)); } catch (Throwable e) { - FailureWatcher.onError(mTest.mLauncher, description, e); + FailureWatcher.onError(mTest.mLauncher, description); throw e; } diff --git a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java index 7fba33ec81..7bdc040afc 100644 --- a/tests/src/com/android/launcher3/util/rule/FailureWatcher.java +++ b/tests/src/com/android/launcher3/util/rule/FailureWatcher.java @@ -30,6 +30,8 @@ import java.util.zip.ZipOutputStream; public class FailureWatcher extends TestWatcher { private static final String TAG = "FailureWatcher"; private static boolean sSavedBugreport = false; + private static Description sDescriptionForLastSavedArtifacts; + private final LauncherInstrumentation mLauncher; @NonNull private final Supplier mViewCaptureDataSupplier; @@ -40,6 +42,18 @@ public class FailureWatcher extends TestWatcher { mViewCaptureDataSupplier = viewCaptureDataSupplier; } + @Override + protected void starting(Description description) { + mLauncher.setOnFailure(() -> onError(mLauncher, description, mViewCaptureDataSupplier)); + super.starting(description); + } + + @Override + protected void finished(Description description) { + super.finished(description); + mLauncher.setOnFailure(null); + } + @Override protected void succeeded(Description description) { super.succeeded(description); @@ -70,7 +84,7 @@ public class FailureWatcher extends TestWatcher { @Override protected void failed(Throwable e, Description description) { - onError(mLauncher, description, e, mViewCaptureDataSupplier); + onError(mLauncher, description, mViewCaptureDataSupplier); } static File diagFile(Description description, String prefix, String ext) { @@ -79,13 +93,18 @@ public class FailureWatcher extends TestWatcher { + description.getMethodName() + "." + ext); } - public static void onError(LauncherInstrumentation launcher, Description description, - Throwable e) { - onError(launcher, description, e, null); + /** Action executed when an error condition is expected. Saves artifacts. */ + public static void onError(LauncherInstrumentation launcher, Description description) { + onError(launcher, description, null); } private static void onError(LauncherInstrumentation launcher, Description description, - Throwable e, @Nullable Supplier viewCaptureDataSupplier) { + @Nullable Supplier viewCaptureDataSupplier) { + if (description.equals(sDescriptionForLastSavedArtifacts)) { + // This test has already saved its artifacts. + return; + } + sDescriptionForLastSavedArtifacts = description; final File sceenshot = diagFile(description, "TestScreenshot", "png"); final File hierarchy = diagFile(description, "Hierarchy", "zip"); @@ -114,7 +133,7 @@ public class FailureWatcher extends TestWatcher { Log.e(TAG, "Failed test " + description.getMethodName() + ",\nscreenshot will be saved to " + sceenshot + ",\nUI dump at: " + hierarchy - + " (use go/web-hv to open the dump file)", e); + + " (use go/web-hv to open the dump file)"); final UiDevice device = launcher.getDevice(); device.takeScreenshot(sceenshot); diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 764a4551cf..aa8d33906b 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -204,6 +204,7 @@ public final class LauncherInstrumentation { private Runnable mTestAnomalyChecker; private boolean mCheckEventsForSuccessfulGestures = false; + private Runnable mOnFailure; private Runnable mOnLauncherCrashed; private TrackpadGestureType mTrackpadGestureType = TrackpadGestureType.NONE; @@ -342,6 +343,11 @@ public final class LauncherInstrumentation { mCheckEventsForSuccessfulGestures = true; } + /** Sets a runnable that will be invoked upon assertion failures. */ + public void setOnFailure(Runnable onFailure) { + mOnFailure = onFailure; + } + public void setOnLauncherCrashed(Runnable onLauncherCrashed) { mOnLauncherCrashed = onLauncherCrashed; } @@ -623,6 +629,7 @@ public final class LauncherInstrumentation { final String systemAnomalyMessage = getSystemAnomalyMessage(ignoreNavmodeChangeStates, ignoreOnlySystemUiViews); if (systemAnomalyMessage != null) { + if (mOnFailure != null) mOnFailure.run(); Assert.fail(formatSystemHealthMessage(formatErrorWithEvents( "http://go/tapl : Tests are broken by a non-Launcher system error: " + systemAnomalyMessage, false))); @@ -742,6 +749,7 @@ public final class LauncherInstrumentation { void fail(String message) { checkForAnomaly(); + if (mOnFailure != null) mOnFailure.run(); Assert.fail(formatSystemHealthMessage(formatErrorWithEvents( "http://go/tapl test failure: " + message + ";\nContext: " + getContextDescription() + "; now visible state is " + getVisibleStateMessage(), true)));