| Index: chrome/android/javatests/src/org/chromium/chrome/browser/WebShareTest.java
|
| diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/WebShareTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/WebShareTest.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..bae64b0fae788ccd6f669af7ce5322b13859e266
|
| --- /dev/null
|
| +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/WebShareTest.java
|
| @@ -0,0 +1,279 @@
|
| +// 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.chrome.browser;
|
| +
|
| +import android.content.Context;
|
| +import android.content.Intent;
|
| +import android.os.Build;
|
| +import android.os.Environment;
|
| +import android.support.v7.app.AlertDialog;
|
| +import android.test.suitebuilder.annotation.MediumTest;
|
| +
|
| +import org.chromium.base.test.util.CommandLineFlags;
|
| +import org.chromium.base.test.util.Feature;
|
| +import org.chromium.chrome.browser.share.ShareHelper;
|
| +import org.chromium.chrome.browser.tab.EmptyTabObserver;
|
| +import org.chromium.chrome.browser.tab.Tab;
|
| +import org.chromium.chrome.test.ChromeActivityTestCaseBase;
|
| +import org.chromium.content.browser.test.util.CallbackHelper;
|
| +import org.chromium.net.test.EmbeddedTestServer;
|
| +
|
| +/** Test suite for Web Share (navigator.share) functionality. */
|
| +public class WebShareTest extends ChromeActivityTestCaseBase<ChromeActivity> {
|
| + private static final String TEST_FILE = "/content/test/data/android/webshare.html";
|
| +
|
| + private EmbeddedTestServer mTestServer;
|
| +
|
| + private String mUrl;
|
| +
|
| + private Tab mTab;
|
| + private WebShareUpdateWaiter mUpdateWaiter;
|
| +
|
| + private Intent mReceivedIntent;
|
| +
|
| + /** Waits until the JavaScript code supplies a result. */
|
| + private class WebShareUpdateWaiter extends EmptyTabObserver {
|
| + private CallbackHelper mCallbackHelper;
|
| + private String mStatus;
|
| +
|
| + public WebShareUpdateWaiter() {
|
| + mCallbackHelper = new CallbackHelper();
|
| + }
|
| +
|
| + @Override
|
| + public void onTitleUpdated(Tab tab) {
|
| + String title = getActivity().getActivityTab().getTitle();
|
| + // Wait until the title indicates either success or failure.
|
| + if (!title.equals("Success") && !title.startsWith("Fail:")) return;
|
| + mStatus = title;
|
| + mCallbackHelper.notifyCalled();
|
| + }
|
| +
|
| + public String waitForUpdate() throws Exception {
|
| + mCallbackHelper.waitForCallback(0);
|
| + return mStatus;
|
| + }
|
| + }
|
| +
|
| + public WebShareTest() {
|
| + super(ChromeActivity.class);
|
| + }
|
| +
|
| + @Override
|
| + protected void setUp() throws Exception {
|
| + super.setUp();
|
| +
|
| + mTestServer = EmbeddedTestServer.createAndStartFileServer(
|
| + getInstrumentation().getContext(), Environment.getExternalStorageDirectory());
|
| +
|
| + mUrl = mTestServer.getURL(TEST_FILE);
|
| +
|
| + mTab = getActivity().getActivityTab();
|
| + mUpdateWaiter = new WebShareUpdateWaiter();
|
| + mTab.addObserver(mUpdateWaiter);
|
| +
|
| + mReceivedIntent = null;
|
| + }
|
| +
|
| + @Override
|
| + protected void tearDown() throws Exception {
|
| + mTab.removeObserver(mUpdateWaiter);
|
| + mTestServer.stopAndDestroyServer();
|
| +
|
| + // Clean up some state that might have been changed by tests.
|
| + ShareHelper.setForceCustomChooserForTesting(false);
|
| + ShareHelper.setFakeIntentReceiverForTesting(null);
|
| +
|
| + super.tearDown();
|
| + }
|
| +
|
| + /**
|
| + * Verify that WebShare is missing by default (without a flag).
|
| + * @throws Exception
|
| + */
|
| + @MediumTest
|
| + @Feature({"WebShare"})
|
| + public void testWebShareMissingWithoutFlag() throws Exception {
|
| + loadUrl(mUrl);
|
| + runJavaScriptCodeInCurrentTab("initiate_share()");
|
| + assertEquals("Fail: navigator.share === undefined", mUpdateWaiter.waitForUpdate());
|
| + }
|
| +
|
| + /**
|
| + * Verify that WebShare fails if called without a user gesture.
|
| + * @throws Exception
|
| + */
|
| + @MediumTest
|
| + @CommandLineFlags.Add("enable-blink-features=WebShare")
|
| + @Feature({"WebShare"})
|
| + public void testWebShareNoUserGesture() throws Exception {
|
| + loadUrl(mUrl);
|
| + runJavaScriptCodeInCurrentTab("initiate_share()");
|
| + assertEquals(
|
| + "Fail: SecurityError: Must be handling a user gesture to perform a share request.",
|
| + mUpdateWaiter.waitForUpdate());
|
| + }
|
| +
|
| + /**
|
| + * Verify WebShare fails if share is called from a user gesture, and canceled.
|
| + * @throws Exception
|
| + */
|
| + @MediumTest
|
| + @CommandLineFlags.Add("enable-blink-features=WebShare")
|
| + @Feature({"WebShare"})
|
| + public void testWebShareCancel() throws Exception {
|
| + // This test tests functionality that is only available post Lollipop MR1.
|
| + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) return;
|
| +
|
| + // Set up ShareHelper to ignore the intent (without showing a picker). This simulates the
|
| + // user canceling the dialog.
|
| + ShareHelper.setFakeIntentReceiverForTesting(new ShareHelper.FakeIntentReceiver() {
|
| + public void setIntentToSendBack(Intent intent) {}
|
| +
|
| + public void onCustomChooserShown(AlertDialog dialog) {}
|
| +
|
| + public void fireIntent(Context context, Intent intent) {
|
| + // Click again to start another share. This is necessary to work around
|
| + // https://crbug.com/636274 (callback is not canceled until next share is
|
| + // initiated). This also serves as a regression test for https://crbug.com/640324.
|
| + singleClickView(mTab.getView());
|
| + }
|
| + });
|
| +
|
| + loadUrl(mUrl);
|
| + // Click (instead of directly calling the JavaScript function) to simulate a user gesture.
|
| + singleClickView(mTab.getView());
|
| + assertEquals("Fail: AbortError: Share canceled", mUpdateWaiter.waitForUpdate());
|
| + }
|
| +
|
| + /**
|
| + * Verify WebShare succeeds if share is called from a user gesture, and app chosen.
|
| + * @throws Exception
|
| + */
|
| + @MediumTest
|
| + @CommandLineFlags.Add("enable-blink-features=WebShare")
|
| + @Feature({"WebShare"})
|
| + public void testWebShareSuccess() throws Exception {
|
| + // This test tests functionality that is only available post Lollipop MR1.
|
| + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) return;
|
| +
|
| + // Set up ShareHelper to immediately succeed (without showing a picker).
|
| + ShareHelper.setFakeIntentReceiverForTesting(new ShareHelper.FakeIntentReceiver() {
|
| + private Intent mIntentToSendBack;
|
| +
|
| + public void setIntentToSendBack(Intent intent) {
|
| + mIntentToSendBack = intent;
|
| + }
|
| +
|
| + public void onCustomChooserShown(AlertDialog dialog) {}
|
| +
|
| + public void fireIntent(Context context, Intent intent) {
|
| + mReceivedIntent = intent;
|
| +
|
| + if (context == null) return;
|
| +
|
| + // Send the intent back, which indicates that the user made a choice. (Normally,
|
| + // this would have EXTRA_CHOSEN_COMPONENT set, but for the test, we do not set any
|
| + // chosen target app.)
|
| + context.sendBroadcast(mIntentToSendBack);
|
| + }
|
| + });
|
| +
|
| + loadUrl(mUrl);
|
| + // Click (instead of directly calling the JavaScript function) to simulate a user gesture.
|
| + singleClickView(mTab.getView());
|
| + assertEquals("Success", mUpdateWaiter.waitForUpdate());
|
| +
|
| + // The actual intent to be delivered to the target is in the EXTRA_INTENT of the chooser
|
| + // intent.
|
| + assertNotNull(mReceivedIntent);
|
| + assertTrue(mReceivedIntent.hasExtra(Intent.EXTRA_INTENT));
|
| + Intent innerIntent = mReceivedIntent.getParcelableExtra(Intent.EXTRA_INTENT);
|
| + assertNotNull(innerIntent);
|
| + assertEquals(Intent.ACTION_SEND, innerIntent.getAction());
|
| + assertTrue(innerIntent.hasExtra(Intent.EXTRA_SUBJECT));
|
| + assertEquals("Test Title", innerIntent.getStringExtra(Intent.EXTRA_SUBJECT));
|
| + assertTrue(innerIntent.hasExtra(Intent.EXTRA_TEXT));
|
| + assertEquals("Test Text https://test.url/", innerIntent.getStringExtra(Intent.EXTRA_TEXT));
|
| + }
|
| +
|
| + /**
|
| + * Verify WebShare fails if share is called from a user gesture, and canceled.
|
| + *
|
| + * Simulates pre-Lollipop-LMR1 system (different intent picker).
|
| + *
|
| + * @throws Exception
|
| + */
|
| + @MediumTest
|
| + @CommandLineFlags.Add("enable-blink-features=WebShare")
|
| + @Feature({"WebShare"})
|
| + public void testWebShareCancelPreLMR1() throws Exception {
|
| + ShareHelper.setFakeIntentReceiverForTesting(new ShareHelper.FakeIntentReceiver() {
|
| + public void setIntentToSendBack(Intent intent) {}
|
| +
|
| + public void onCustomChooserShown(AlertDialog dialog) {
|
| + // Cancel the chooser dialog.
|
| + dialog.dismiss();
|
| + }
|
| +
|
| + public void fireIntent(Context context, Intent intent) {}
|
| + });
|
| +
|
| + ShareHelper.setForceCustomChooserForTesting(true);
|
| +
|
| + loadUrl(mUrl);
|
| + // Click (instead of directly calling the JavaScript function) to simulate a user gesture.
|
| + singleClickView(mTab.getView());
|
| + assertEquals("Fail: AbortError: Share canceled", mUpdateWaiter.waitForUpdate());
|
| + }
|
| +
|
| + /**
|
| + * Verify WebShare succeeds if share is called from a user gesture, and app chosen.
|
| + *
|
| + * Simulates pre-Lollipop-LMR1 system (different intent picker).
|
| + *
|
| + * @throws Exception
|
| + */
|
| + @MediumTest
|
| + @CommandLineFlags.Add("enable-blink-features=WebShare")
|
| + @Feature({"WebShare"})
|
| + public void testWebShareSuccessPreLMR1() throws Exception {
|
| + ShareHelper.setFakeIntentReceiverForTesting(new ShareHelper.FakeIntentReceiver() {
|
| + public void setIntentToSendBack(Intent intent) {}
|
| +
|
| + public void onCustomChooserShown(AlertDialog dialog) {
|
| + // Click on an app (it doesn't matter which, because we will hook the intent).
|
| + assert dialog.getListView().getCount() > 0;
|
| + dialog
|
| + .getListView()
|
| + .performItemClick(null, 0, dialog.getListView().getItemIdAtPosition(0));
|
| + }
|
| +
|
| + public void fireIntent(Context context, Intent intent) {
|
| + mReceivedIntent = intent;
|
| + }
|
| + });
|
| +
|
| + ShareHelper.setForceCustomChooserForTesting(true);
|
| +
|
| + loadUrl(mUrl);
|
| + // Click (instead of directly calling the JavaScript function) to simulate a user gesture.
|
| + singleClickView(mTab.getView());
|
| + assertEquals("Success", mUpdateWaiter.waitForUpdate());
|
| +
|
| + assertNotNull(mReceivedIntent);
|
| + assertEquals(Intent.ACTION_SEND, mReceivedIntent.getAction());
|
| + assertTrue(mReceivedIntent.hasExtra(Intent.EXTRA_SUBJECT));
|
| + assertEquals("Test Title", mReceivedIntent.getStringExtra(Intent.EXTRA_SUBJECT));
|
| + assertTrue(mReceivedIntent.hasExtra(Intent.EXTRA_TEXT));
|
| + assertEquals("Test Text https://test.url/",
|
| + mReceivedIntent.getStringExtra(Intent.EXTRA_TEXT));
|
| + }
|
| +
|
| + @Override
|
| + public void startMainActivity() throws InterruptedException {
|
| + startMainActivityOnBlankPage();
|
| + }
|
| +}
|
|
|