blob: b4f2c91f27b7b4ce7279b93edbe68a1dcdfea6a1 [file] [log] [blame]
/*
* Copyright (C) 2019 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;
import static android.widget.espresso.TextViewActions.dragOnText;
import static android.widget.espresso.TextViewAssertions.hasInsertionPointerAtIndex;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.replaceText;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import android.app.Activity;
import android.app.Instrumentation;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;
import com.android.frameworks.coretests.R;
import com.google.common.base.Strings;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
@SmallTest
public class EditorCursorDragTest {
@Rule
public ActivityTestRule<TextViewActivity> mActivityRule = new ActivityTestRule<>(
TextViewActivity.class);
private boolean mOriginalFlagValue;
private Instrumentation mInstrumentation;
private Activity mActivity;
@Before
public void before() throws Throwable {
mInstrumentation = InstrumentationRegistry.getInstrumentation();
mActivity = mActivityRule.getActivity();
mOriginalFlagValue = Editor.FLAG_ENABLE_CURSOR_DRAG;
Editor.FLAG_ENABLE_CURSOR_DRAG = true;
}
@After
public void after() throws Throwable {
Editor.FLAG_ENABLE_CURSOR_DRAG = mOriginalFlagValue;
}
@Test
public void testCursorDrag_horizontal_whenTextViewContentsFitOnScreen() throws Throwable {
String text = "Hello world!";
onView(withId(R.id.textview)).perform(replaceText(text));
onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(0));
// Drag left to right. The cursor should end up at the position where the finger is lifted.
onView(withId(R.id.textview)).perform(dragOnText(text.indexOf("llo"), text.indexOf("!")));
onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(11));
// Drag right to left. The cursor should end up at the position where the finger is lifted.
onView(withId(R.id.textview)).perform(dragOnText(text.indexOf("!"), text.indexOf("llo")));
onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(2));
}
@Test
public void testCursorDrag_horizontal_whenTextViewContentsLargerThanScreen() throws Throwable {
String text = "Hello world!"
+ Strings.repeat("\n", 500) + "012345middle"
+ Strings.repeat("\n", 10) + "012345last";
onView(withId(R.id.textview)).perform(replaceText(text));
onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(0));
// Drag left to right. The cursor should end up at the position where the finger is lifted.
onView(withId(R.id.textview)).perform(dragOnText(text.indexOf("llo"), text.indexOf("!")));
onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(11));
// Drag right to left. The cursor should end up at the position where the finger is lifted.
onView(withId(R.id.textview)).perform(dragOnText(text.indexOf("!"), text.indexOf("llo")));
onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(2));
}
@Test
public void testCursorDrag_diagonal_whenTextViewContentsLargerThanScreen() throws Throwable {
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 9; i++) {
sb.append("line").append(i).append("\n");
}
sb.append(Strings.repeat("0123456789\n\n", 500)).append("Last line");
String text = sb.toString();
onView(withId(R.id.textview)).perform(replaceText(text));
onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(0));
// Drag along a diagonal path.
onView(withId(R.id.textview)).perform(dragOnText(text.indexOf("line1"), text.indexOf("2")));
onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("2")));
// Drag along a steeper diagonal path.
onView(withId(R.id.textview)).perform(dragOnText(text.indexOf("line1"), text.indexOf("9")));
onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("9")));
// Drag along an almost vertical path.
// TODO(b/145833335): Consider whether this should scroll instead of dragging the cursor.
onView(withId(R.id.textview)).perform(dragOnText(text.indexOf("ne1"), text.indexOf("9")));
onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("9")));
// Drag along a vertical path from line 1 to line 9.
// TODO(b/145833335): Consider whether this should scroll instead of dragging the cursor.
onView(withId(R.id.textview)).perform(dragOnText(text.indexOf("e1"), text.indexOf("e9")));
onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("e9")));
// Drag along a vertical path from line 9 to line 1.
// TODO(b/145833335): Consider whether this should scroll instead of dragging the cursor.
onView(withId(R.id.textview)).perform(dragOnText(text.indexOf("e9"), text.indexOf("e1")));
onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("e1")));
}
@Test
public void testCursorDrag_vertical_whenTextViewContentsFitOnScreen() throws Throwable {
String text = "012first\n\n" + Strings.repeat("012345\n\n", 10) + "012last";
onView(withId(R.id.textview)).perform(replaceText(text));
onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(0));
// Drag down. Since neither the TextView nor its container require scrolling, the cursor
// drag should execute and the cursor should end up at the position where the finger is
// lifted.
onView(withId(R.id.textview)).perform(
dragOnText(text.indexOf("first"), text.indexOf("last")));
onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.length() - 4));
// Drag up. Since neither the TextView nor its container require scrolling, the cursor
// drag should execute and the cursor should end up at the position where the finger is
// lifted.
onView(withId(R.id.textview)).perform(
dragOnText(text.indexOf("last"), text.indexOf("first")));
onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(3));
}
@Test
public void testCursorDrag_vertical_whenTextViewContentsLargerThanScreen() throws Throwable {
String text = "012345first\n\n"
+ Strings.repeat("0123456789\n\n", 10) + "012345middle"
+ Strings.repeat("0123456789\n\n", 500) + "012345last";
onView(withId(R.id.textview)).perform(replaceText(text));
int initialCursorPosition = 0;
onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(initialCursorPosition));
// Drag up.
// TODO(b/145833335): Consider whether this should scroll instead of dragging the cursor.
onView(withId(R.id.textview)).perform(
dragOnText(text.indexOf("middle"), text.indexOf("first")));
onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("first")));
// Drag down.
// TODO(b/145833335): Consider whether this should scroll instead of dragging the cursor.
onView(withId(R.id.textview)).perform(
dragOnText(text.indexOf("first"), text.indexOf("middle")));
onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("middle")));
}
}