Chromium Code Reviews| Index: android_webview/tools/automated_ui_tests/javatests/src/org/chromium/webview_ui_test/test/ActionModeTest.java |
| diff --git a/android_webview/tools/automated_ui_tests/javatests/src/org/chromium/webview_ui_test/test/ActionModeTest.java b/android_webview/tools/automated_ui_tests/javatests/src/org/chromium/webview_ui_test/test/ActionModeTest.java |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..0cd2c3111ab8831a2ab62122a37e18da618e6ea4 |
| --- /dev/null |
| +++ b/android_webview/tools/automated_ui_tests/javatests/src/org/chromium/webview_ui_test/test/ActionModeTest.java |
| @@ -0,0 +1,203 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +package org.chromium.webview_ui_test.test; |
| + |
| +import static android.support.test.espresso.Espresso.onData; |
| +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.longClick; |
| +import static android.support.test.espresso.assertion.ViewAssertions.matches; |
| +import static android.support.test.espresso.intent.Intents.assertNoUnverifiedIntents; |
| +import static android.support.test.espresso.intent.Intents.intended; |
| +import static android.support.test.espresso.intent.Intents.intending; |
| +import static android.support.test.espresso.intent.matcher.BundleMatchers.hasEntry; |
| +import static android.support.test.espresso.intent.matcher.IntentMatchers.anyIntent; |
| +import static android.support.test.espresso.intent.matcher.IntentMatchers.hasAction; |
| +import static android.support.test.espresso.intent.matcher.IntentMatchers.hasExtra; |
| +import static android.support.test.espresso.intent.matcher.IntentMatchers.hasExtras; |
| +import static android.support.test.espresso.intent.matcher.IntentMatchers.hasType; |
| +import static android.support.test.espresso.matcher.RootMatchers.withDecorView; |
| +import static android.support.test.espresso.matcher.ViewMatchers.isEnabled; |
| +import static android.support.test.espresso.matcher.ViewMatchers.withContentDescription; |
| +import static android.support.test.espresso.matcher.ViewMatchers.withId; |
| +import static android.support.test.espresso.matcher.ViewMatchers.withText; |
| +import static android.support.test.espresso.web.assertion.WebViewAssertions.webMatches; |
| +import static android.support.test.espresso.web.sugar.Web.onWebView; |
| +import static android.support.test.espresso.web.webdriver.DriverAtoms.findElement; |
| +import static android.support.test.espresso.web.webdriver.DriverAtoms.getText; |
| + |
| +import static org.hamcrest.CoreMatchers.allOf; |
| +import static org.hamcrest.Matchers.containsString; |
| +import static org.hamcrest.Matchers.equalTo; |
| + |
| +import android.app.Activity; |
| +import android.app.Instrumentation; |
| +import android.content.Intent; |
| +import android.os.Build; |
| + |
| +import android.support.test.InstrumentationRegistry; |
| + |
| +import android.support.test.espresso.NoMatchingViewException; |
| +import android.support.test.espresso.PerformException; |
| +import android.support.test.espresso.intent.Intents; |
| +import android.support.test.espresso.web.webdriver.Locator; |
| + |
| +import android.support.test.uiautomator.UiDevice; |
| +import android.support.test.uiautomator.UiObject; |
| +import android.support.test.uiautomator.UiObjectNotFoundException; |
| +import android.support.test.uiautomator.UiSelector; |
| + |
| +import android.test.suitebuilder.annotation.SmallTest; |
| +import android.view.MenuItem; |
| +import android.webkit.WebView; |
| + |
| +import org.chromium.webview_ui_test.R; |
| + |
| +import org.hamcrest.Description; |
| +import org.hamcrest.Matcher; |
| +import org.hamcrest.TypeSafeMatcher; |
| + |
| + |
| +/** |
| + * Tests for WebView ActionMode. |
| + */ |
| +public class ActionModeTest extends WebViewTestBase { |
| + private static final long UI_TIMEOUT = 10 * 1000; |
|
mikecase (-- gone --)
2016/07/25 21:19:01
Use a org.chromium.base.test.util.ScalableTimeout
aluo
2016/08/08 23:20:05
Done. Actually this isn't used so I removed it.
|
| + |
| + @Override |
| + protected String getLayout() { |
| + return "edittext_webview"; |
| + } |
| + |
| + @Override |
| + public void setUp() throws Exception { |
| + super.setUp(); |
| + getInstrumentation().runOnMainSync(new Runnable() { |
| + @Override |
| + public void run() { |
| + WebView w = (WebView) getWebViewActivity().findViewById(R.id.webview); |
| + w.getSettings().setJavaScriptEnabled(true); |
| + w.loadData("<html><body><p>Hello world</p></body></html>", "text/html", "utf-8"); |
| + } |
| + }); |
| + onWebView(withId(R.id.webview)) |
| + .withElement(findElement(Locator.TAG_NAME, "p")) |
| + .check(webMatches(getText(), containsString("Hello world"))); |
| + } |
| + |
| + /** Test Copy and Paste */ |
| + @SmallTest |
| + public void testCopyPaste() { |
| + onView(withId(R.id.webview)).perform(longClick()); |
| + clickPopupAction("Copy"); |
| + // This is needed to get the popup to work correctly in the next step |
| + onView(withId(R.id.edittext)).perform(click()); |
| + onView(withId(R.id.edittext)).perform(longClick()); |
| + clickPopupAction("Paste"); |
| + onView(withId(R.id.edittext)).check(matches(withText("world"))); |
| + } |
| + |
| + /** Test Select All */ |
| + @SmallTest |
| + public void testSelectAll() { |
| + onView(withId(R.id.webview)).perform(longClick()); |
| + clickPopupAction("Select all"); |
| + clickPopupAction("Copy"); |
| + // This is needed to get the popup to work correctly in the next step |
| + onView(withId(R.id.edittext)).perform(click()); |
| + onView(withId(R.id.edittext)).perform(longClick()); |
| + clickPopupAction("Paste"); |
| + onView(withId(R.id.edittext)).check(matches(withText("Hello world"))); |
| + } |
| + |
| + /** Test Share */ |
| + @SmallTest |
| + public void testShare() { |
| + Intents.init(); |
| + intending(anyIntent()) |
| + .respondWith(new Instrumentation.ActivityResult(Activity.RESULT_OK, new Intent())); |
| + |
| + onView(withId(R.id.webview)).perform(longClick()); |
| + clickPopupAction("Share"); |
| + |
| + intended(allOf(hasAction(Intent.ACTION_CHOOSER), |
| + hasExtras(allOf(hasEntry(Intent.EXTRA_TITLE, "Share"), |
| + hasEntry(Intent.EXTRA_INTENT, |
| + allOf(hasAction(Intent.ACTION_SEND), hasType("text/plain"), |
| + hasExtra(Intent.EXTRA_TEXT, "world"))))))); |
| + assertNoUnverifiedIntents(); |
| + } |
| + |
| + /** Test Web Search */ |
| + @SmallTest |
| + public void testWebSearch() { |
| + Intents.init(); |
| + intending(anyIntent()) |
| + .respondWith(new Instrumentation.ActivityResult(Activity.RESULT_OK, new Intent())); |
| + onView(withId(R.id.webview)).perform(longClick()); |
| + clickPopupAction("Web search"); |
| + intended(allOf(hasAction(Intent.ACTION_WEB_SEARCH), |
| + hasExtras(allOf(hasEntry("com.android.browser.application_id", |
| + "org.chromium.webview_ui_test"), |
| + hasEntry("query", "world"), hasEntry("new_search", true))))); |
| + assertNoUnverifiedIntents(); |
| + } |
| + |
| + /** Test Assist */ |
|
mikecase (-- gone --)
2016/07/25 21:19:01
nit: I have usually seen javadoc in the format
/*
aluo
2016/08/08 23:20:05
Done.
|
| + @SmallTest |
| + public void testAssist() { |
| + /** TODO(aluo): Get SdkSuppress to work with the test runner */ |
| + if (Build.VERSION.SDK_INT < 24) return; |
|
mikecase (-- gone --)
2016/07/25 21:19:01
I think TODOs should use one-line comments. e.g.
aluo
2016/08/08 23:20:06
Done.
|
| + onView(withId(R.id.webview)).perform(longClick()); |
| + clickPopupAction("Assist"); |
| + UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()); |
| + UiObject assistCancel = |
| + device.findObject(new UiSelector() |
| + .packageName("com.google.android.googlequicksearchbox") |
| + .text("NO THANKS")); |
| + assistCancel.waitForExists(5000); |
| + assertTrue(assistCancel.exists()); |
| + try { |
| + assistCancel.clickAndWaitForNewWindow(); |
| + device.pressBack(); |
| + } catch (UiObjectNotFoundException e) { |
| + e.printStackTrace(); |
| + } |
| + } |
| + |
| + /** Matches an item on the Action Mode popup by the title */ |
| + private static class MenuItemMatcher extends TypeSafeMatcher<MenuItem> { |
| + private Matcher<String> mTitleMatcher; |
| + public MenuItemMatcher(Matcher<String> titleMatcher) { |
| + mTitleMatcher = titleMatcher; |
| + } |
| + @Override |
| + protected boolean matchesSafely(MenuItem item) { |
| + return mTitleMatcher.matches(item.getTitle()); |
| + } |
| + @Override |
| + public void describeTo(Description description) { |
| + description.appendText("has MenuItem with title: "); |
| + description.appendDescriptionOf(mTitleMatcher); |
| + } |
| + } |
| + |
| + /** Click an item on the Action Mode popup */ |
| + public void clickPopupAction(final String name) { |
| + try { |
| + onView(withContentDescription(name)) |
| + .inRoot(withDecorView(isEnabled())) |
| + .perform(click()); |
| + } catch (PerformException | NoMatchingViewException e) { |
| + onView(withContentDescription("More options")) |
| + .inRoot(withDecorView(isEnabled())) |
| + .perform(click()); |
| + onData(new MenuItemMatcher(equalTo(name))) |
| + .inRoot(withDecorView(isEnabled())) |
| + .perform(click()); |
| + } |
| + } |
| +} |