From 654adf657ed8906b2f5405a02ecf41785c0053b8 Mon Sep 17 00:00:00 2001 From: Pinyao Ting Date: Wed, 8 Jan 2020 18:48:24 +0000 Subject: [PATCH] integration test for open settings menu from workspace. compare pid of launcher process after test execution to verify launcher isn't crashed when running in oop test. Bug: 147235759 Change-Id: Id13c47f5c4e388cc8e95b19d099e94a2e540bf3f Test: fun flake locally --- .../testing/TestInformationHandler.java | 6 +++ .../launcher3/testing/TestProtocol.java | 1 + .../launcher3/views/OptionsPopupView.java | 1 - .../launcher3/ui/TaplTestsLauncher3.java | 23 ++++++++++ .../com/android/launcher3/tapl/AppIcon.java | 13 +----- .../tapl/LauncherInstrumentation.java | 28 +++++++++++ .../launcher3/tapl/OptionsPopupMenu.java | 41 +++++++++++++++++ .../launcher3/tapl/OptionsPopupMenuItem.java | 46 +++++++++++++++++++ 8 files changed, 147 insertions(+), 12 deletions(-) create mode 100644 tests/tapl/com/android/launcher3/tapl/OptionsPopupMenu.java create mode 100644 tests/tapl/com/android/launcher3/tapl/OptionsPopupMenuItem.java diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java index 40e267b17a..ecfc77ccf1 100644 --- a/src/com/android/launcher3/testing/TestInformationHandler.java +++ b/src/com/android/launcher3/testing/TestInformationHandler.java @@ -24,6 +24,7 @@ import android.graphics.Bitmap; import android.graphics.Color; import android.os.Bundle; import android.os.Debug; +import android.system.Os; import android.view.View; import androidx.annotation.Keep; @@ -136,6 +137,11 @@ public class TestInformationHandler implements ResourceBasedOverride { break; } + case TestProtocol.REQUEST_PID: { + response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, Os.getpid()); + break; + } + case TestProtocol.REQUEST_TOTAL_PSS_KB: { runGcAndFinalizersSync(); Debug.MemoryInfo mem = new Debug.MemoryInfo(); diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java index dd8df88d4f..929315a703 100644 --- a/src/com/android/launcher3/testing/TestProtocol.java +++ b/src/com/android/launcher3/testing/TestProtocol.java @@ -73,6 +73,7 @@ public final class TestProtocol { public static final String REQUEST_APPS_LIST_SCROLL_Y = "apps-list-scroll-y"; public static final String REQUEST_OVERVIEW_LEFT_GESTURE_MARGIN = "overview-left-margin"; public static final String REQUEST_OVERVIEW_RIGHT_GESTURE_MARGIN = "overview-right-margin"; + public static final String REQUEST_PID = "pid"; public static final String REQUEST_TOTAL_PSS_KB = "total_pss"; public static final String REQUEST_JAVA_LEAK = "java-leak"; public static final String REQUEST_NATIVE_LEAK = "native-leak"; diff --git a/src/com/android/launcher3/views/OptionsPopupView.java b/src/com/android/launcher3/views/OptionsPopupView.java index 88d34daac9..5ba931d41d 100644 --- a/src/com/android/launcher3/views/OptionsPopupView.java +++ b/src/com/android/launcher3/views/OptionsPopupView.java @@ -47,7 +47,6 @@ import com.android.launcher3.widget.WidgetsFullSheet; import java.util.ArrayList; import java.util.List; - /** * Popup shown on long pressing an empty space in launcher */ diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java index d7096b0c20..61f515052a 100644 --- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java +++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java @@ -18,6 +18,9 @@ package com.android.launcher3.ui; import static androidx.test.InstrumentationRegistry.getInstrumentation; +import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL; +import static com.android.launcher3.util.rule.TestStabilityRule.UNBUNDLED_POSTSUBMIT; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -36,10 +39,12 @@ 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.TestStabilityRule.Stability; import com.android.launcher3.views.OptionsPopupView; import com.android.launcher3.widget.WidgetsFullSheet; import com.android.launcher3.widget.WidgetsRecyclerView; +import org.junit.After; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; @@ -50,10 +55,18 @@ import org.junit.runner.RunWith; public class TaplTestsLauncher3 extends AbstractLauncherUiTest { private static final String APP_NAME = "LauncherTestApp"; + private int mLauncherPid; + @Before public void setUp() throws Exception { super.setUp(); initialize(this); + mLauncherPid = mLauncher.getPid(); + } + + @After + public void teardown() { + assertEquals("Launcher crashed, pid mismatch:", mLauncherPid, mLauncher.getPid()); } public static void initialize(AbstractLauncherUiTest test) throws Exception { @@ -100,6 +113,16 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest { mLauncher.pressHome(); } + // b/146432215: remove @Stability after 2/1/2020 if this test doesn't flake + @Test + @Stability(flavors = LOCAL | UNBUNDLED_POSTSUBMIT) + public void testOpenHomeSettingsFromWorkspace() { + mDevice.pressMenu(); + mDevice.waitForIdle(); + mLauncher.getOptionsPopupMenu().getMenuItem("Home settings") + .launch(mDevice.getLauncherPackageName()); + } + @Test @Ignore public void testPressHomeOnAllAppsContextMenu() throws Exception { diff --git a/tests/tapl/com/android/launcher3/tapl/AppIcon.java b/tests/tapl/com/android/launcher3/tapl/AppIcon.java index 44fc3f74fd..2da6344634 100644 --- a/tests/tapl/com/android/launcher3/tapl/AppIcon.java +++ b/tests/tapl/com/android/launcher3/tapl/AppIcon.java @@ -16,9 +16,6 @@ package com.android.launcher3.tapl; -import android.graphics.Point; -import android.os.SystemClock; -import android.view.MotionEvent; import android.widget.TextView; import androidx.test.uiautomator.By; @@ -41,14 +38,8 @@ public final class AppIcon extends Launchable { * Long-clicks the icon to open its menu. */ public AppIconMenu openMenu() { - final Point iconCenter = mObject.getVisibleCenter(); - final long downTime = SystemClock.uptimeMillis(); - mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, iconCenter); - final UiObject2 deepShortcutsContainer = mLauncher.waitForLauncherObject( - "deep_shortcuts_container"); - mLauncher.sendPointer( - downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, iconCenter); - return new AppIconMenu(mLauncher, deepShortcutsContainer); + return new AppIconMenu(mLauncher, mLauncher.clickAndGet( + mObject, "deep_shortcuts_container")); } @Override diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 28c9e7a577..217f696928 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -691,6 +691,20 @@ public final class LauncherInstrumentation { } } + /** + * Gets the Options Popup Menu object if the current state is showing the popup menu. Fails if + * the launcher is not in that state. + * + * @return Options Popup Menu object. + */ + @NonNull + public OptionsPopupMenu getOptionsPopupMenu() { + try (LauncherInstrumentation.Closable c = addContextLayer( + "want to get context menu object")) { + return new OptionsPopupMenu(this); + } + } + void waitUntilGone(String resId) { assertTrue("Unexpected launcher object visible: " + resId, mDevice.wait(Until.gone(getLauncherObjectSelector(resId)), @@ -999,6 +1013,16 @@ public final class LauncherInstrumentation { return getSystemIntegerRes(context, "config_navBarInteractionMode"); } + @NonNull + UiObject2 clickAndGet(@NonNull final UiObject2 target, @NonNull String resName) { + final Point targetCenter = target.getVisibleCenter(); + final long downTime = SystemClock.uptimeMillis(); + sendPointer(downTime, downTime, MotionEvent.ACTION_DOWN, targetCenter); + final UiObject2 result = waitForLauncherObject(resName); + sendPointer(downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, targetCenter); + return result; + } + private static int getSystemIntegerRes(Context context, String resName) { Resources res = context.getResources(); int resId = res.getIdentifier(resName, "integer", "android"); @@ -1058,6 +1082,10 @@ public final class LauncherInstrumentation { getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD); } + public int getPid() { + return getTestInfo(TestProtocol.REQUEST_PID).getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD); + } + public void produceJavaLeak() { getTestInfo(TestProtocol.REQUEST_JAVA_LEAK); } diff --git a/tests/tapl/com/android/launcher3/tapl/OptionsPopupMenu.java b/tests/tapl/com/android/launcher3/tapl/OptionsPopupMenu.java new file mode 100644 index 0000000000..282fca9333 --- /dev/null +++ b/tests/tapl/com/android/launcher3/tapl/OptionsPopupMenu.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2020 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.annotation.NonNull; +import androidx.test.uiautomator.By; +import androidx.test.uiautomator.UiObject2; + +public class OptionsPopupMenu { + + private final LauncherInstrumentation mLauncher; + private final UiObject2 mDeepShortcutsContainer; + + OptionsPopupMenu(LauncherInstrumentation launcher) { + mLauncher = launcher; + mDeepShortcutsContainer = launcher.waitForLauncherObject("deep_shortcuts_container"); + } + + /** + * Returns a menu item with a given label. Fails if it doesn't exist. + */ + @NonNull + public OptionsPopupMenuItem getMenuItem(@NonNull final String label) { + final UiObject2 menuItem = mLauncher.waitForObjectInContainer(mDeepShortcutsContainer, + By.text(label)); + return new OptionsPopupMenuItem(mLauncher, menuItem); + } +} diff --git a/tests/tapl/com/android/launcher3/tapl/OptionsPopupMenuItem.java b/tests/tapl/com/android/launcher3/tapl/OptionsPopupMenuItem.java new file mode 100644 index 0000000000..8527d05998 --- /dev/null +++ b/tests/tapl/com/android/launcher3/tapl/OptionsPopupMenuItem.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 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.annotation.NonNull; +import androidx.test.uiautomator.By; +import androidx.test.uiautomator.UiObject2; +import androidx.test.uiautomator.Until; + +public class OptionsPopupMenuItem { + + private final LauncherInstrumentation mLauncher; + private final UiObject2 mObject; + + OptionsPopupMenuItem(@NonNull LauncherInstrumentation launcher, @NonNull UiObject2 shortcut) { + mLauncher = launcher; + mObject = shortcut; + } + + /** + * Clicks the option. + */ + @NonNull + public void launch(@NonNull String expectedPackageName) { + LauncherInstrumentation.log("OptionsPopupMenuItem before click " + + mObject.getVisibleCenter() + " in " + mObject.getVisibleBounds()); + mObject.click(); + mLauncher.assertTrue( + "App didn't start: " + By.pkg(expectedPackageName), + mLauncher.getDevice().wait(Until.hasObject(By.pkg(expectedPackageName)), + LauncherInstrumentation.WAIT_TIME_MS)); + } +}