Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2ccdd08a authored by Vadim Tryshev's avatar Vadim Tryshev Committed by Android (Google) Code Review
Browse files

Merge "Supporting OOP tests" into ub-launcher3-master

parents cf771551 34b6f9f1
Loading
Loading
Loading
Loading
+4 −141
Original line number Diff line number Diff line
@@ -15,29 +15,21 @@
 */
package com.android.launcher3.ui;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;

import static androidx.test.InstrumentationRegistry.getInstrumentation;

import static org.junit.Assert.fail;

import android.app.Instrumentation;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.LauncherActivityInfo;
import android.graphics.Point;
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.Log;
import android.view.MotionEvent;
import android.view.Surface;

import androidx.test.InstrumentationRegistry;
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.BySelector;
import androidx.test.uiautomator.Direction;
import androidx.test.uiautomator.UiDevice;
@@ -46,19 +38,14 @@ import androidx.test.uiautomator.Until;

import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.LauncherModel;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.LauncherState;
import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.compat.AppWidgetManagerCompat;
import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.tapl.LauncherInstrumentation;
import com.android.launcher3.tapl.TestHelpers;
import com.android.launcher3.testcomponent.AppWidgetNoConfig;
import com.android.launcher3.testcomponent.AppWidgetWithConfig;
import com.android.launcher3.util.Wait;
import com.android.launcher3.util.rule.LauncherActivityRule;
import com.android.launcher3.util.rule.ShellCommandRule;
@@ -89,7 +76,6 @@ public abstract class AbstractLauncherUiTest {

    public static final long SHORT_UI_TIMEOUT= 300;
    public static final long DEFAULT_UI_TIMEOUT = 10000;
    public static final long DEFAULT_WORKER_TIMEOUT_SECS = 5;

    protected MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor();
    protected final UiDevice mDevice;
@@ -97,8 +83,6 @@ public abstract class AbstractLauncherUiTest {
    protected Context mTargetContext;
    protected String mTargetPackage;

    private static final String TAG = "AbstractLauncherUiTest";

    protected AbstractLauncherUiTest() {
        final Instrumentation instrumentation = getInstrumentation();
        mDevice = UiDevice.getInstance(instrumentation);
@@ -114,7 +98,8 @@ public abstract class AbstractLauncherUiTest {
    @Rule
    public LauncherActivityRule mActivityMonitor = new LauncherActivityRule();

    @Rule public ShellCommandRule mDefaultLauncherRule = ShellCommandRule.setDefaultLauncher();
    @Rule public ShellCommandRule mDefaultLauncherRule =
            TestHelpers.isInLauncherProcess() ? ShellCommandRule.setDefaultLauncher() : null;

    @Rule public ShellCommandRule mDisableHeadsUpNotification =
            ShellCommandRule.disableHeadsUpNotification();
@@ -183,30 +168,6 @@ public abstract class AbstractLauncherUiTest {
        }
    }

    /**
     * Opens all apps and returns the recycler view
     */
    protected UiObject2 openAllApps() {
        mDevice.waitForIdle();
        UiObject2 hotseat = mDevice.wait(
                Until.findObject(getSelectorForId(R.id.hotseat)), 2500);
        Point start = hotseat.getVisibleCenter();
        int endY = (int) (mDevice.getDisplayHeight() * 0.1f);
        // 100 px/step
        mDevice.swipe(start.x, start.y, start.x, endY, (start.y - endY) / 100);
        return findViewById(R.id.apps_list_view);
    }

    /**
     * Opens widget tray and returns the recycler view.
     */
    protected UiObject2 openWidgetsTray() {
        mDevice.pressMenu(); // Enter overview mode.
        mDevice.wait(Until.findObject(
                By.text(mTargetContext.getString(R.string.widget_button_text))), DEFAULT_UI_TIMEOUT).click();
        return findViewById(R.id.widgets_list_view);
    }

    /**
     * Scrolls the {@param container} until it finds an object matching {@param condition}.
     * @return the matching object.
@@ -228,73 +189,6 @@ public abstract class AbstractLauncherUiTest {
        }
    }

    /**
     * Drags an icon to the center of homescreen.
     * @param icon  object that is either app icon or shortcut icon
     */
    protected void dragToWorkspace(UiObject2 icon, boolean expectedToShowShortcuts) {
        Point center = icon.getVisibleCenter();

        // Action Down
        sendPointer(MotionEvent.ACTION_DOWN, center);

        UiObject2 dragLayer = findViewById(R.id.drag_layer);

        if (expectedToShowShortcuts) {
            // Make sure shortcuts show up, and then move a bit to hide them.
            assertNotNull(findViewById(R.id.deep_shortcuts_container));

            Point moveLocation = new Point(center);
            int distanceToMove = mTargetContext.getResources().getDimensionPixelSize(
                    R.dimen.deep_shortcuts_start_drag_threshold) + 50;
            if (moveLocation.y - distanceToMove >= dragLayer.getVisibleBounds().top) {
                moveLocation.y -= distanceToMove;
            } else {
                moveLocation.y += distanceToMove;
            }
            movePointer(center, moveLocation);

            assertNull(findViewById(R.id.deep_shortcuts_container));
        }

        // Wait until Remove/Delete target is visible
        assertNotNull(findViewById(R.id.delete_target_text));

        Point moveLocation = dragLayer.getVisibleCenter();

        // Move to center
        movePointer(center, moveLocation);
        sendPointer(MotionEvent.ACTION_UP, center);

        // Wait until remove target is gone.
        mDevice.wait(Until.gone(getSelectorForId(R.id.delete_target_text)), DEFAULT_UI_TIMEOUT);
    }

    private void movePointer(Point from, Point to) {
        while(!from.equals(to)) {
            from.x = getNextMoveValue(to.x, from.x);
            from.y = getNextMoveValue(to.y, from.y);
            sendPointer(MotionEvent.ACTION_MOVE, from);
        }
    }

    private int getNextMoveValue(int targetValue, int oldValue) {
        if (targetValue - oldValue > 10) {
            return oldValue + 10;
        } else if (targetValue - oldValue < -10) {
            return oldValue - 10;
        } else {
            return targetValue;
        }
    }

    protected void sendPointer(int action, Point point) {
        MotionEvent event = MotionEvent.obtain(SystemClock.uptimeMillis(),
                SystemClock.uptimeMillis(), action, point.x, point.y, 0);
        getInstrumentation().sendPointerSync(event);
        event.recycle();
    }

    /**
     * Removes all icons from homescreen and hotseat.
     */
@@ -381,37 +275,6 @@ public abstract class AbstractLauncherUiTest {
        Wait.atMost(message, () -> getFromLauncher(condition), timeout);
    }

    /**
     * Finds a widget provider which can fit on the home screen.
     * @param hasConfigureScreen if true, a provider with a config screen is returned.
     */
    protected LauncherAppWidgetProviderInfo findWidgetProvider(final boolean hasConfigureScreen) {
        LauncherAppWidgetProviderInfo info =
                getOnUiThread(new Callable<LauncherAppWidgetProviderInfo>() {
            @Override
            public LauncherAppWidgetProviderInfo call() throws Exception {
                ComponentName cn = new ComponentName(getInstrumentation().getContext(),
                        hasConfigureScreen ? AppWidgetWithConfig.class : AppWidgetNoConfig.class);
                Log.d(TAG, "findWidgetProvider componentName=" + cn.flattenToString());
                return AppWidgetManagerCompat.getInstance(mTargetContext)
                        .findProvider(cn, Process.myUserHandle());
            }
        });
        if (info == null) {
            throw new IllegalArgumentException("No valid widget provider");
        }
        return info;
    }

    protected UiObject2 findViewById(int id) {
        return mDevice.wait(Until.findObject(getSelectorForId(id)), DEFAULT_UI_TIMEOUT);
    }

    protected BySelector getSelectorForId(int id) {
        String name = mTargetContext.getResources().getResourceEntryName(id);
        return By.res(mTargetPackage, name);
    }

    protected LauncherActivityInfo getSettingsApp() {
        return LauncherAppsCompat.getInstance(mTargetContext)
                .getActivityList("com.android.settings",
+2 −2
Original line number Diff line number Diff line
@@ -45,12 +45,12 @@ public class AllAppsIconToHomeTest extends AbstractLauncherUiTest {
        mDevice.waitForIdle();

        // Open all apps and wait for load complete.
        final UiObject2 appsContainer = openAllApps();
        final UiObject2 appsContainer = TestViewHelpers.openAllApps();
        Wait.atMost(null, Condition.minChildCount(appsContainer, 2), DEFAULT_UI_TIMEOUT);

        // Drag icon to homescreen.
        UiObject2 icon = scrollAndFind(appsContainer, By.text(settingsApp.getLabel().toString()));
        dragToWorkspace(icon, true);
        TestViewHelpers.dragToWorkspace(icon, true);

        // Verify that the icon works on homescreen.
        mDevice.findObject(By.text(settingsApp.getLabel().toString())).click();
+6 −5
Original line number Diff line number Diff line
@@ -46,24 +46,25 @@ public class ShortcutsLaunchTest extends AbstractLauncherUiTest {
        LauncherActivityInfo testApp = getSettingsApp();

        // Open all apps and wait for load complete
        final UiObject2 appsContainer = openAllApps();
        final UiObject2 appsContainer = TestViewHelpers.openAllApps();
        Wait.atMost(null, Condition.minChildCount(appsContainer, 2), DEFAULT_UI_TIMEOUT);

        // Find settings app and verify shortcuts appear when long pressed
        UiObject2 icon = scrollAndFind(appsContainer, By.text(testApp.getLabel().toString()));
        // Press icon center until shortcuts appear
        Point iconCenter = icon.getVisibleCenter();
        sendPointer(MotionEvent.ACTION_DOWN, iconCenter);
        UiObject2 deepShortcutsContainer = findViewById(R.id.deep_shortcuts_container);
        TestViewHelpers.sendPointer(MotionEvent.ACTION_DOWN, iconCenter);
        UiObject2 deepShortcutsContainer = TestViewHelpers.findViewById(
                R.id.deep_shortcuts_container);
        assertNotNull(deepShortcutsContainer);
        sendPointer(MotionEvent.ACTION_UP, iconCenter);
        TestViewHelpers.sendPointer(MotionEvent.ACTION_UP, iconCenter);

        // Verify that launching a shortcut opens a page with the same text
        assertTrue(deepShortcutsContainer.getChildCount() > 0);

        // Pick second children as it starts showing shortcuts.
        UiObject2 shortcut = deepShortcutsContainer.getChildren().get(1)
                .findObject(getSelectorForId(R.id.bubble_text));
                .findObject(TestViewHelpers.getSelectorForId(R.id.bubble_text));
        shortcut.click();
        assertTrue(mDevice.wait(Until.hasObject(By.pkg(
                testApp.getComponentName().getPackageName())
+7 −6
Original line number Diff line number Diff line
@@ -48,24 +48,25 @@ public class ShortcutsToHomeTest extends AbstractLauncherUiTest {
        LauncherActivityInfo testApp  = getSettingsApp();

        // Open all apps and wait for load complete.
        final UiObject2 appsContainer = openAllApps();
        final UiObject2 appsContainer = TestViewHelpers.openAllApps();
        Wait.atMost(null, Condition.minChildCount(appsContainer, 2), DEFAULT_UI_TIMEOUT);

        // Find the app and long press it to show shortcuts.
        UiObject2 icon = scrollAndFind(appsContainer, By.text(testApp.getLabel().toString()));
        // Press icon center until shortcuts appear
        Point iconCenter = icon.getVisibleCenter();
        sendPointer(MotionEvent.ACTION_DOWN, iconCenter);
        UiObject2 deepShortcutsContainer = findViewById(R.id.deep_shortcuts_container);
        TestViewHelpers.sendPointer(MotionEvent.ACTION_DOWN, iconCenter);
        UiObject2 deepShortcutsContainer = TestViewHelpers.findViewById(
                R.id.deep_shortcuts_container);
        assertNotNull(deepShortcutsContainer);
        sendPointer(MotionEvent.ACTION_UP, iconCenter);
        TestViewHelpers.sendPointer(MotionEvent.ACTION_UP, iconCenter);

        // Drag the first shortcut to the home screen.
        assertTrue(deepShortcutsContainer.getChildCount() > 0);
        UiObject2 shortcut = deepShortcutsContainer.getChildren().get(1)
                .findObject(getSelectorForId(R.id.bubble_text));
                .findObject(TestViewHelpers.getSelectorForId(R.id.bubble_text));
        String shortcutName = shortcut.getText();
        dragToWorkspace(shortcut, false);
        TestViewHelpers.dragToWorkspace(shortcut, false);

        // Verify that the shortcut works on home screen
        // (the app opens and has the same text as the shortcut).
+186 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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 androidx.test.InstrumentationRegistry.getTargetContext;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;

import android.content.ComponentName;
import android.content.Context;
import android.graphics.Point;
import android.os.Process;
import android.os.SystemClock;
import android.util.Log;
import android.view.MotionEvent;

import androidx.test.uiautomator.By;
import androidx.test.uiautomator.BySelector;
import androidx.test.uiautomator.UiDevice;
import androidx.test.uiautomator.UiObject2;
import androidx.test.uiautomator.Until;

import com.android.launcher3.LauncherAppWidgetProviderInfo;
import com.android.launcher3.R;
import com.android.launcher3.compat.AppWidgetManagerCompat;
import com.android.launcher3.testcomponent.AppWidgetNoConfig;
import com.android.launcher3.testcomponent.AppWidgetWithConfig;

import java.util.concurrent.Callable;

public class TestViewHelpers {
    private static final String TAG = "TestViewHelpers";

    private static UiDevice getDevice() {
        return UiDevice.getInstance(getInstrumentation());
    }

    /**
     * Opens all apps and returns the recycler view
     */
    public static UiObject2 openAllApps() {
        final UiDevice device = getDevice();
        device.waitForIdle();
        UiObject2 hotseat = device.wait(
                Until.findObject(getSelectorForId(R.id.hotseat)), 2500);
        Point start = hotseat.getVisibleCenter();
        int endY = (int) (device.getDisplayHeight() * 0.1f);
        // 100 px/step
        device.swipe(start.x, start.y, start.x, endY, (start.y - endY) / 100);
        return findViewById(R.id.apps_list_view);
    }

    public static UiObject2 findViewById(int id) {
        return getDevice().wait(Until.findObject(getSelectorForId(id)),
                AbstractLauncherUiTest.DEFAULT_UI_TIMEOUT);
    }

    public static BySelector getSelectorForId(int id) {
        final Context targetContext = getTargetContext();
        String name = targetContext.getResources().getResourceEntryName(id);
        return By.res(targetContext.getPackageName(), name);
    }

    /**
     * Finds a widget provider which can fit on the home screen.
     *
     * @param test               test suite.
     * @param hasConfigureScreen if true, a provider with a config screen is returned.
     */
    public static LauncherAppWidgetProviderInfo findWidgetProvider(AbstractLauncherUiTest test,
            final boolean hasConfigureScreen) {
        LauncherAppWidgetProviderInfo info =
                test.getOnUiThread(new Callable<LauncherAppWidgetProviderInfo>() {
                    @Override
                    public LauncherAppWidgetProviderInfo call() throws Exception {
                        ComponentName cn = new ComponentName(getInstrumentation().getContext(),
                                hasConfigureScreen ? AppWidgetWithConfig.class
                                        : AppWidgetNoConfig.class);
                        Log.d(TAG, "findWidgetProvider componentName=" + cn.flattenToString());
                        return AppWidgetManagerCompat.getInstance(getTargetContext())
                                .findProvider(cn, Process.myUserHandle());
                    }
                });
        if (info == null) {
            throw new IllegalArgumentException("No valid widget provider");
        }
        return info;
    }

    /**
     * Drags an icon to the center of homescreen.
     *
     * @param icon object that is either app icon or shortcut icon
     */
    public static void dragToWorkspace(UiObject2 icon, boolean expectedToShowShortcuts) {
        Point center = icon.getVisibleCenter();

        // Action Down
        sendPointer(MotionEvent.ACTION_DOWN, center);

        UiObject2 dragLayer = findViewById(R.id.drag_layer);

        if (expectedToShowShortcuts) {
            // Make sure shortcuts show up, and then move a bit to hide them.
            assertNotNull(findViewById(R.id.deep_shortcuts_container));

            Point moveLocation = new Point(center);
            int distanceToMove =
                    getTargetContext().getResources().getDimensionPixelSize(
                            R.dimen.deep_shortcuts_start_drag_threshold) + 50;
            if (moveLocation.y - distanceToMove >= dragLayer.getVisibleBounds().top) {
                moveLocation.y -= distanceToMove;
            } else {
                moveLocation.y += distanceToMove;
            }
            movePointer(center, moveLocation);

            assertNull(findViewById(R.id.deep_shortcuts_container));
        }

        // Wait until Remove/Delete target is visible
        assertNotNull(findViewById(R.id.delete_target_text));

        Point moveLocation = dragLayer.getVisibleCenter();

        // Move to center
        movePointer(center, moveLocation);
        sendPointer(MotionEvent.ACTION_UP, center);

        // Wait until remove target is gone.
        getDevice().wait(Until.gone(getSelectorForId(R.id.delete_target_text)),
                AbstractLauncherUiTest.DEFAULT_UI_TIMEOUT);
    }

    private static void movePointer(Point from, Point to) {
        while (!from.equals(to)) {
            from.x = getNextMoveValue(to.x, from.x);
            from.y = getNextMoveValue(to.y, from.y);
            sendPointer(MotionEvent.ACTION_MOVE, from);
        }
    }

    private static int getNextMoveValue(int targetValue, int oldValue) {
        if (targetValue - oldValue > 10) {
            return oldValue + 10;
        } else if (targetValue - oldValue < -10) {
            return oldValue - 10;
        } else {
            return targetValue;
        }
    }

    public static void sendPointer(int action, Point point) {
        MotionEvent event = MotionEvent.obtain(SystemClock.uptimeMillis(),
                SystemClock.uptimeMillis(), action, point.x, point.y, 0);
        getInstrumentation().sendPointerSync(event);
        event.recycle();
    }

    /**
     * Opens widget tray and returns the recycler view.
     */
    public static UiObject2 openWidgetsTray() {
        final UiDevice device = getDevice();
        device.pressMenu(); // Enter overview mode.
        device.wait(Until.findObject(
                By.text(getTargetContext().getString(R.string.widget_button_text))),
                AbstractLauncherUiTest.DEFAULT_UI_TIMEOUT).click();
        return findViewById(R.id.widgets_list_view);
    }
}
Loading