Merge "FloatingToolbarEspressoUtils + more TextView selection by touch tests"

This commit is contained in:
Abodunrinwa Toki
2015-09-29 18:44:41 +00:00
committed by Android (Google) Code Review
5 changed files with 212 additions and 2 deletions

View File

@@ -73,6 +73,8 @@ public final class FloatingToolbar {
// This class is responsible for the public API of the floating toolbar.
// 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 =
new MenuItem.OnMenuItemClickListener() {
@Override
@@ -1460,8 +1462,10 @@ public final class FloatingToolbar {
}
private static ViewGroup createContentContainer(Context context) {
return (ViewGroup) LayoutInflater.from(context)
ViewGroup contentContainer = (ViewGroup) LayoutInflater.from(context)
.inflate(R.layout.floating_popup_container, null);
contentContainer.setTag(FLOATING_TOOLBAR_TAG);
return contentContainer;
}
private static PopupWindow createPopupWindow(View content) {

View File

@@ -18,8 +18,12 @@ package android.widget;
import static android.widget.espresso.TextViewActions.clickOnTextAtIndex;
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.longPressOnTextAtIndex;
import static android.widget.espresso.TextViewAssertions.hasInsertionPointerAtIndex;
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.action.ViewActions.click;
import static android.support.test.espresso.action.ViewActions.pressKey;
@@ -59,6 +63,7 @@ public class TextViewActivityTest extends ActivityInstrumentationTestCase2<TextV
getActivity();
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(clickOnTextAtIndex(helloWorld.indexOf("world")));
@@ -67,11 +72,40 @@ public class TextViewActivityTest extends ActivityInstrumentationTestCase2<TextV
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
public void testLongPressAndDragToSelect() throws Exception {
getActivity();
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(
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"));
}
@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
public void testDoubleTapAndDragToSelect() throws Exception {
getActivity();
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(
doubleTapAndDragOnText(helloWorld.indexOf("young"), helloWorld.indexOf(" girl!")));
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());
}
}

View File

@@ -0,0 +1,49 @@
/*
* 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()));
}
}

View File

@@ -51,6 +51,36 @@ public final class TextViewActions {
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
* TextView.<br>

View File

@@ -47,7 +47,7 @@ public final class TextViewAssertions {
* @param selection The expected 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);
}
/**
* 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}.
*/