diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index 2712bc02ce..bf4eba0f64 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -65,6 +65,7 @@ import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.Wait; import com.android.launcher3.util.rule.FailureWatcher; import com.android.launcher3.util.rule.LauncherActivityRule; +import com.android.launcher3.util.rule.ScreenRecordRule; import com.android.launcher3.util.rule.ShellCommandRule; import com.android.launcher3.util.rule.TestStabilityRule; @@ -204,6 +205,9 @@ public abstract class AbstractLauncherUiTest { public ShellCommandRule mDisableHeadsUpNotification = ShellCommandRule.disableHeadsUpNotification(); + @Rule + public ScreenRecordRule mScreenRecordRule = new ScreenRecordRule(); + protected void clearPackageData(String pkg) throws IOException, InterruptedException { final CountDownLatch count = new CountDownLatch(2); final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java index 06bc26a2a2..4dd44f4193 100644 --- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java +++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java @@ -36,6 +36,7 @@ import com.android.launcher3.tapl.AppIconMenu; import com.android.launcher3.tapl.AppIconMenuItem; import com.android.launcher3.tapl.Widgets; import com.android.launcher3.tapl.Workspace; +import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord; import com.android.launcher3.views.OptionsPopupView; import com.android.launcher3.widget.picker.WidgetsFullSheet; import com.android.launcher3.widget.picker.WidgetsRecyclerView; @@ -92,6 +93,7 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest { } @Test + @ScreenRecord //b/187080582 public void testDevicePressMenu() throws Exception { mDevice.pressMenu(); mDevice.waitForIdle(); diff --git a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java index 822fefc208..745dc220ba 100644 --- a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java +++ b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java @@ -42,6 +42,7 @@ import com.android.launcher3.testcomponent.RequestPinItemActivity; import com.android.launcher3.ui.AbstractLauncherUiTest; import com.android.launcher3.util.Wait; import com.android.launcher3.util.Wait.Condition; +import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord; import com.android.launcher3.util.rule.ShellCommandRule; import org.junit.Before; @@ -77,6 +78,7 @@ public class RequestPinItemTest extends AbstractLauncherUiTest { public void testEmpty() throws Throwable { /* needed while the broken tests are being fixed */ } @Test + @ScreenRecord //b/192010616 public void testPinWidgetNoConfig() throws Throwable { runTest("pinWidgetNoConfig", true, (info, view) -> info instanceof LauncherAppWidgetInfo && ((LauncherAppWidgetInfo) info).appWidgetId == mAppWidgetId && @@ -85,6 +87,7 @@ public class RequestPinItemTest extends AbstractLauncherUiTest { } @Test + @ScreenRecord //b/192005114 public void testPinWidgetNoConfig_customPreview() throws Throwable { // Command to set custom preview Intent command = RequestPinItemActivity.getCommandIntent( diff --git a/tests/src/com/android/launcher3/util/rule/ScreenRecordRule.java b/tests/src/com/android/launcher3/util/rule/ScreenRecordRule.java new file mode 100644 index 0000000000..00b1cdd35e --- /dev/null +++ b/tests/src/com/android/launcher3/util/rule/ScreenRecordRule.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2021 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.util.rule; + +import static androidx.test.InstrumentationRegistry.getInstrumentation; + +import android.app.Instrumentation; +import android.app.UiAutomation; +import android.os.ParcelFileDescriptor; +import android.util.Log; + +import androidx.test.uiautomator.UiDevice; + +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +import java.io.File; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Rule which captures a screen record for a test. + * After adding this rule to the test class, apply the annotation @ScreenRecord to individual tests + */ +public class ScreenRecordRule implements TestRule { + + private static final String TAG = "ScreenRecordRule"; + + @Override + public Statement apply(Statement base, Description description) { + if (description.getAnnotation(ScreenRecord.class) == null) { + return base; + } + + return new Statement() { + @Override + public void evaluate() throws Throwable { + Instrumentation inst = getInstrumentation(); + UiAutomation automation = inst.getUiAutomation(); + UiDevice device = UiDevice.getInstance(inst); + + File outputFile = new File(inst.getTargetContext().getFilesDir(), + "screenrecord-" + description.getMethodName() + ".mp4"); + device.executeShellCommand("killall screenrecord"); + ParcelFileDescriptor output = + automation.executeShellCommand("screenrecord " + outputFile); + String screenRecordPid = device.executeShellCommand("pidof screenrecord"); + try { + base.evaluate(); + } finally { + device.executeShellCommand("kill -INT " + screenRecordPid); + Log.e(TAG, "Screenrecord captured at: " + outputFile); + output.close(); + } + } + }; + } + + /** + * Interface to indicate that the test should capture screenrecord + */ + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + public @interface ScreenRecord { } +}