Merge "FloatingToolbarEspressoUtils + more TextView selection by touch tests"
This commit is contained in:
committed by
Android (Google) Code Review
commit
66e47b6aa1
@@ -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) {
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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}.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user