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

Commit 8a5e1ae2 authored by Abodunrinwa Toki's avatar Abodunrinwa Toki
Browse files

FloatingToolbarEspressoUtils + more TextView selection by touch tests

Bug: 24102650
Change-Id: Idd7d8b29ad8cfdf10d75137762bb1cb677bda6b7
parent 7e519110
Loading
Loading
Loading
Loading
+5 −1
Original line number Original line Diff line number Diff line
@@ -73,6 +73,8 @@ public final class FloatingToolbar {
    // This class is responsible for the public API of the floating toolbar.
    // This class is responsible for the public API of the floating toolbar.
    // It delegates rendering operations to the FloatingToolbarPopup.
    // It delegates rendering operations to the FloatingToolbarPopup.


    public static final String FLOATING_TOOLBAR_TAG = "floating_toolbar";

    private static final MenuItem.OnMenuItemClickListener NO_OP_MENUITEM_CLICK_LISTENER =
    private static final MenuItem.OnMenuItemClickListener NO_OP_MENUITEM_CLICK_LISTENER =
            new MenuItem.OnMenuItemClickListener() {
            new MenuItem.OnMenuItemClickListener() {
                @Override
                @Override
@@ -1460,8 +1462,10 @@ public final class FloatingToolbar {
    }
    }


    private static ViewGroup createContentContainer(Context context) {
    private static ViewGroup createContentContainer(Context context) {
        return (ViewGroup) LayoutInflater.from(context)
        ViewGroup contentContainer = (ViewGroup) LayoutInflater.from(context)
                .inflate(R.layout.floating_popup_container, null);
                .inflate(R.layout.floating_popup_container, null);
        contentContainer.setTag(FLOATING_TOOLBAR_TAG);
        return contentContainer;
    }
    }


    private static PopupWindow createPopupWindow(View content) {
    private static PopupWindow createPopupWindow(View content) {
+80 −0
Original line number Original line Diff line number Diff line
@@ -18,8 +18,12 @@ package android.widget;


import static android.widget.espresso.TextViewActions.clickOnTextAtIndex;
import static android.widget.espresso.TextViewActions.clickOnTextAtIndex;
import static android.widget.espresso.TextViewActions.doubleTapAndDragOnText;
import static android.widget.espresso.TextViewActions.doubleTapAndDragOnText;
import static android.widget.espresso.TextViewActions.doubleClickOnTextAtIndex;
import static android.widget.espresso.TextViewActions.longPressAndDragOnText;
import static android.widget.espresso.TextViewActions.longPressAndDragOnText;
import static android.widget.espresso.TextViewActions.longPressOnTextAtIndex;
import static android.widget.espresso.TextViewAssertions.hasInsertionPointerAtIndex;
import static android.widget.espresso.TextViewAssertions.hasSelection;
import static android.widget.espresso.TextViewAssertions.hasSelection;
import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarIsDisplayed;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.action.ViewActions.pressKey;
import static android.support.test.espresso.action.ViewActions.pressKey;
@@ -59,6 +63,7 @@ public class TextViewActivityTest extends ActivityInstrumentationTestCase2<TextV
        getActivity();
        getActivity();


        final String helloWorld = "Hello world!";
        final String helloWorld = "Hello world!";
        onView(withId(R.id.textview)).perform(click());
        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(helloWorld.indexOf("world")));
        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(helloWorld.indexOf("world")));


@@ -67,11 +72,40 @@ public class TextViewActivityTest extends ActivityInstrumentationTestCase2<TextV
        onView(withId(R.id.textview)).check(matches(withText("Hello orld!")));
        onView(withId(R.id.textview)).check(matches(withText("Hello orld!")));
    }
    }


    @SmallTest
    public void testLongPressToSelect() throws Exception {
        getActivity();

        final String helloWorld = "Hello Kirk!";
        onView(withId(R.id.textview)).perform(click());
        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
        onView(withId(R.id.textview)).perform(
                longPressOnTextAtIndex(helloWorld.indexOf("Kirk")));

        onView(withId(R.id.textview)).check(hasSelection("Kirk"));
    }

    @SmallTest
    public void testLongPressEmptySpace() throws Exception {
        getActivity();

        final String helloWorld = "Hello big round sun!";
        onView(withId(R.id.textview)).perform(click());
        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
        // Move cursor somewhere else
        onView(withId(R.id.textview)).perform(clickOnTextAtIndex(helloWorld.indexOf("big")));
        // Long-press at end of line.
        onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(helloWorld.length()));

        onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(helloWorld.length()));
    }

    @SmallTest
    @SmallTest
    public void testLongPressAndDragToSelect() throws Exception {
    public void testLongPressAndDragToSelect() throws Exception {
        getActivity();
        getActivity();


        final String helloWorld = "Hello little handsome boy!";
        final String helloWorld = "Hello little handsome boy!";
        onView(withId(R.id.textview)).perform(click());
        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
        onView(withId(R.id.textview)).perform(
        onView(withId(R.id.textview)).perform(
                longPressAndDragOnText(helloWorld.indexOf("little"), helloWorld.indexOf(" boy!")));
                longPressAndDragOnText(helloWorld.indexOf("little"), helloWorld.indexOf(" boy!")));
@@ -79,15 +113,61 @@ public class TextViewActivityTest extends ActivityInstrumentationTestCase2<TextV
        onView(withId(R.id.textview)).check(hasSelection("little handsome"));
        onView(withId(R.id.textview)).check(hasSelection("little handsome"));
    }
    }


    @SmallTest
    public void testDoubleTapToSelect() throws Exception {
        getActivity();

        final String helloWorld = "Hello SuetYi!";
        onView(withId(R.id.textview)).perform(click());
        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
        onView(withId(R.id.textview)).perform(
                doubleClickOnTextAtIndex(helloWorld.indexOf("SuetYi")));

        onView(withId(R.id.textview)).check(hasSelection("SuetYi"));
    }

    @SmallTest
    @SmallTest
    public void testDoubleTapAndDragToSelect() throws Exception {
    public void testDoubleTapAndDragToSelect() throws Exception {
        getActivity();
        getActivity();


        final String helloWorld = "Hello young beautiful girl!";
        final String helloWorld = "Hello young beautiful girl!";
        onView(withId(R.id.textview)).perform(click());
        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
        onView(withId(R.id.textview)).perform(
        onView(withId(R.id.textview)).perform(
                doubleTapAndDragOnText(helloWorld.indexOf("young"), helloWorld.indexOf(" girl!")));
                doubleTapAndDragOnText(helloWorld.indexOf("young"), helloWorld.indexOf(" girl!")));


        onView(withId(R.id.textview)).check(hasSelection("young beautiful"));
        onView(withId(R.id.textview)).check(hasSelection("young beautiful"));
    }
    }

    @SmallTest
    public void testSelectBackwordsByTouch() throws Exception {
        getActivity();

        final String helloWorld = "Hello king of the Jungle!";
        onView(withId(R.id.textview)).perform(click());
        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(helloWorld));
        onView(withId(R.id.textview)).perform(
                doubleTapAndDragOnText(helloWorld.indexOf(" Jungle!"), helloWorld.indexOf("king")));

        onView(withId(R.id.textview)).check(hasSelection("king of the"));
    }

    @SmallTest
    public void testToolbarAppearsAfterSelection() throws Exception {
        getActivity();

        // It'll be nice to check that the toolbar is not visible (or does not exist) here
        // I can't currently find a way to do this. I'll get to it later.

        final String text = "Toolbar appears after selection.";
        onView(withId(R.id.textview)).perform(click());
        onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text));
        onView(withId(R.id.textview)).perform(
                longPressOnTextAtIndex(text.indexOf("appears")));

        // It takes the toolbar less than 100ms to start to animate into screen.
        // Ideally, we'll wait using the UiController, but I guess this works for now.
        Thread.sleep(100);
        assertFloatingToolbarIsDisplayed(getActivity());
    }
}
}
+49 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2015 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 android.widget.espresso;

import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.RootMatchers.withDecorView;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withTagValue;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;

import android.app.Activity;
import com.android.internal.widget.FloatingToolbar;

/**
 * Espresso utility methods for the floating toolbar.
 */
public class FloatingToolbarEspressoUtils {


    private FloatingToolbarEspressoUtils() {}

    /**
     * Asserts that the floating toolbar is displayed on screen.
     *
     * @throws AssertionError if the assertion fails
     */
    public static void assertFloatingToolbarIsDisplayed(Activity activity) {
        onView(withTagValue(is((Object) FloatingToolbar.FLOATING_TOOLBAR_TAG)))
                .inRoot(withDecorView(not(is(activity.getWindow().getDecorView()))))
                .check(matches(isDisplayed()));
    }

}
+30 −0
Original line number Original line Diff line number Diff line
@@ -51,6 +51,36 @@ public final class TextViewActions {
                new GeneralClickAction(Tap.SINGLE, new TextCoordinates(index), Press.FINGER));
                new GeneralClickAction(Tap.SINGLE, new TextCoordinates(index), Press.FINGER));
    }
    }


    /**
     * Returns an action that double-clicks on text at an index on the TextView.<br>
     * <br>
     * View constraints:
     * <ul>
     * <li>must be a TextView displayed on screen
     * <ul>
     *
     * @param index The index of the TextView's text to double-click on.
     */
    public static ViewAction doubleClickOnTextAtIndex(int index) {
        return actionWithAssertions(
                new GeneralClickAction(Tap.DOUBLE, new TextCoordinates(index), Press.FINGER));
    }

    /**
     * Returns an action that long presses on text at an index on the TextView.<br>
     * <br>
     * View constraints:
     * <ul>
     * <li>must be a TextView displayed on screen
     * <ul>
     *
     * @param index The index of the TextView's text to long press on.
     */
    public static ViewAction longPressOnTextAtIndex(int index) {
        return actionWithAssertions(
                new GeneralClickAction(Tap.LONG, new TextCoordinates(index), Press.FINGER));
    }

    /**
    /**
     * Returns an action that long presses then drags on text from startIndex to endIndex on the
     * Returns an action that long presses then drags on text from startIndex to endIndex on the
     * TextView.<br>
     * TextView.<br>
+48 −1
Original line number Original line Diff line number Diff line
@@ -47,7 +47,7 @@ public final class TextViewAssertions {
     * @param selection  The expected selection.
     * @param selection  The expected selection.
     */
     */
    public static ViewAssertion hasSelection(String selection) {
    public static ViewAssertion hasSelection(String selection) {
        return new TextSelectionAssertion(is(selection));
        return hasSelection(is(selection));
    }
    }


    /**
    /**
@@ -65,6 +65,53 @@ public final class TextViewAssertions {
        return new TextSelectionAssertion(selection);
        return new TextSelectionAssertion(selection);
    }
    }


    /**
     * Returns a {@link ViewAssertion} that asserts that the text view insertion pointer is at
     * a specified index.<br>
     * <br>
     * View constraints:
     * <ul>
     * <li>must be a text view displayed on screen
     * <ul>
     *
     * @param index  The expected index.
     */
    public static ViewAssertion hasInsertionPointerAtIndex(int index) {
        return hasInsertionPointerAtIndex(is(index));
    }

    /**
     * Returns a {@link ViewAssertion} that asserts that the text view insertion pointer is at
     * a specified index.<br>
     * <br>
     * View constraints:
     * <ul>
     * <li>must be a text view displayed on screen
     * <ul>
     *
     * @param index  A matcher representing the expected index.
     */
    public static ViewAssertion hasInsertionPointerAtIndex(final Matcher<Integer> index) {
        return new ViewAssertion() {
            @Override
            public void check(View view, NoMatchingViewException exception) {
                if (view instanceof TextView) {
                    TextView textView = (TextView) view;
                    int selectionStart = textView.getSelectionStart();
                    int selectionEnd = textView.getSelectionEnd();
                    try {
                        assertThat(selectionStart, index);
                        assertThat(selectionEnd, index);
                    } catch (IndexOutOfBoundsException e) {
                        throw new AssertionFailedError(e.getMessage());
                    }
                } else {
                    throw new AssertionFailedError("TextView not found");
                }
            }
        };
    }

    /**
    /**
     * A {@link ViewAssertion} to check the selected text in a {@link TextView}.
     * A {@link ViewAssertion} to check the selected text in a {@link TextView}.
     */
     */