Commit df2505c9 authored by Yun Liu's avatar Yun Liu Committed by Commit Bot

Convert and add several tests by Espresso API and a custom test rule for DownloadActivity.

Add a custom ActivityTestRule for DownloadActivity which can turn off animation scales during tests.

Spinner is removed in Download Home V2

Bug: 904030
Change-Id: If00ea1400b17bdbbc49fe2414d0c80a5ec47885b
Reviewed-on: https://chromium-review.googlesource.com/c/1278207
Commit-Queue: Yun Liu <yliuyliu@google.com>
Reviewed-by: default avatarDavid Trainor <dtrainor@chromium.org>
Reviewed-by: default avatarXing Liu <xingliu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#612390}
parent ea36de23
......@@ -1935,6 +1935,7 @@ chrome_test_java_sources = [
"javatests/src/org/chromium/chrome/browser/dom_distiller/DistillabilityServiceTest.java",
"javatests/src/org/chromium/chrome/browser/dom_distiller/DistilledPagePrefsTest.java",
"javatests/src/org/chromium/chrome/browser/download/ChromeDownloadDelegateTest.java",
"javatests/src/org/chromium/chrome/browser/download/DisableAnimationsRule.java",
"javatests/src/org/chromium/chrome/browser/download/DownloadActivityTest.java",
"javatests/src/org/chromium/chrome/browser/download/DownloadInfoBarControllerTest.java",
"javatests/src/org/chromium/chrome/browser/download/DownloadManagerServiceTest.java",
......
......@@ -9,6 +9,7 @@
{% block extra_uses_permissions %}
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
<uses-permission android:name="android.permission.READ_LOGS"/>
<uses-permission android:name="android.permission.SET_ANIMATION_SCALE"/>
{% endblock %}
{% block extra_application_definitions_for_test %}
......
// Copyright 2018 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.download;
import android.os.IBinder;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.chromium.base.Log;
import java.lang.reflect.Method;
import java.util.Arrays;
/**
* {@link TestRule} to disable animations for UI testing.
*/
public class DisableAnimationsRule implements TestRule {
private Method mSetAnimationScalesMethod;
private Method mGetAnimationScalesMethod;
private Object mWindowManagerObject;
private static final float DISABLED_SCALE_FACTOR = 0.0f;
private static final float DEFAULT_SCALE_FACTOR = 1.0f;
private static final String TAG = "disable_animations";
/**
* Invoke setAnimationScalesMethod to turn off system animations, such as Window animation
* scale, Transition animation scale, Animator duration scale, which can improve stability
* and reduce flakiness for UI testing.
*/
public DisableAnimationsRule() {
try {
Class<?> windowManagerStubClazz = Class.forName("android.view.IWindowManager$Stub");
Method asInterface =
windowManagerStubClazz.getDeclaredMethod("asInterface", IBinder.class);
Class<?> serviceManagerClazz = Class.forName("android.os.ServiceManager");
Method getService = serviceManagerClazz.getDeclaredMethod("getService", String.class);
Class<?> windowManagerClazz = Class.forName("android.view.IWindowManager");
mSetAnimationScalesMethod =
windowManagerClazz.getDeclaredMethod("setAnimationScales", float[].class);
mGetAnimationScalesMethod = windowManagerClazz.getDeclaredMethod("getAnimationScales");
IBinder windowManagerBinder = (IBinder) getService.invoke(null, "window");
mWindowManagerObject = asInterface.invoke(null, windowManagerBinder);
} catch (Exception e) {
Log.w(TAG, "Failed to access animation methods", e);
}
}
@Override
public Statement apply(final Statement statement, Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
setAnimationScaleFactors(DISABLED_SCALE_FACTOR);
try {
statement.evaluate();
} finally {
setAnimationScaleFactors(DEFAULT_SCALE_FACTOR);
}
}
};
}
private void setAnimationScaleFactors(float scaleFactor) {
try {
float[] scaleFactors = (float[]) mGetAnimationScalesMethod.invoke(mWindowManagerObject);
Arrays.fill(scaleFactors, scaleFactor);
mSetAnimationScalesMethod.invoke(mWindowManagerObject, scaleFactors);
} catch (Exception e) {
Log.w(TAG, "Failed to set animation scale factors", e);
}
}
}
......@@ -4,6 +4,18 @@
package org.chromium.chrome.browser.download;
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.doesNotExist;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
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 org.hamcrest.Matchers.not;
import android.content.Intent;
import android.content.SharedPreferences.Editor;
import android.os.Handler;
......@@ -21,6 +33,7 @@ import android.widget.TextView;
import org.junit.Assert;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
......@@ -65,6 +78,10 @@ import java.util.List;
@RunWith(ChromeJUnit4ClassRunner.class)
@Restriction(UiRestriction.RESTRICTION_TYPE_PHONE)
public class DownloadActivityTest {
// Disable animations to reduce flakiness.
@ClassRule
public static DisableAnimationsRule disableAnimationsRule = new DisableAnimationsRule();
@Rule
public ActivityTestRule<DownloadActivity> mActivityTestRule =
new ActivityTestRule<>(DownloadActivity.class);
......@@ -150,15 +167,9 @@ public class DownloadActivityTest {
@Test
@MediumTest
@FlakyTest(message = "crbug.com/855168")
public void testSpaceDisplay() throws Exception {
// This first check is a Criteria because initialization of the Adapter is asynchronous.
CriteriaHelper.pollUiThread(new Criteria() {
@Override
public boolean isSatisfied() {
return TextUtils.equals("6.00 GB downloaded", mSpaceUsedDisplay.getText());
}
});
onView(withText("6.00 GB downloaded")).check(matches(isDisplayed()));
// Add a new item.
int callCount = mAdapterObserver.onChangedCallback.getCallCount();
......@@ -168,13 +179,7 @@ public class DownloadActivityTest {
mAdapterObserver.onChangedCallback.waitForCallback(callCount, 2);
mAdapterObserver.onSpaceDisplayUpdatedCallback.waitForCallback(spaceDisplayCallCount);
// Use Criteria here because the text for SpaceDisplay is updated through an AsyncTask.
// Same for the checks below.
CriteriaHelper.pollUiThread(new Criteria() {
@Override
public boolean isSatisfied() {
return TextUtils.equals("6.50 GB downloaded", mSpaceUsedDisplay.getText());
}
});
onView(withText("6.50 GB downloaded")).check(matches(isDisplayed()));
// Mark one download as deleted on disk, which should prevent it from being counted.
callCount = mAdapterObserver.onChangedCallback.getCallCount();
......@@ -184,12 +189,7 @@ public class DownloadActivityTest {
ThreadUtils.runOnUiThread(() -> mAdapter.onDownloadItemUpdated(deletedItem));
mAdapterObserver.onChangedCallback.waitForCallback(callCount, 2);
mAdapterObserver.onSpaceDisplayUpdatedCallback.waitForCallback(spaceDisplayCallCount);
CriteriaHelper.pollUiThread(new Criteria() {
@Override
public boolean isSatisfied() {
return TextUtils.equals("5.50 GB downloaded", mSpaceUsedDisplay.getText());
}
});
onView(withText("5.50 GB downloaded")).check(matches(isDisplayed()));
// Say that the offline page has been deleted.
callCount = mAdapterObserver.onChangedCallback.getCallCount();
......@@ -201,15 +201,12 @@ public class DownloadActivityTest {
deletedPage.id));
mAdapterObserver.onChangedCallback.waitForCallback(callCount, 2);
mAdapterObserver.onSpaceDisplayUpdatedCallback.waitForCallback(spaceDisplayCallCount);
CriteriaHelper.pollUiThread(new Criteria() {
@Override
public boolean isSatisfied() {
return TextUtils.equals("512.00 MB downloaded", mSpaceUsedDisplay.getText());
}
});
onView(withText("512.00 MB downloaded")).check(matches(isDisplayed()));
}
/** Clicking on filters affects various things in the UI. */
/**
* Clicking on filters affects various things in the UI.
*/
@DisabledTest(message = "crbug.com/855389")
@Test
@MediumTest
......@@ -271,8 +268,13 @@ public class DownloadActivityTest {
Assert.assertEquals(
0, mStubbedProvider.getOfflineContentProvider().deleteItemCallback.getCallCount());
int callCount = mAdapterObserver.onSpaceDisplayUpdatedCallback.getCallCount();
ThreadUtils.runOnUiThread(() -> Assert.assertTrue(mUi.getDownloadManagerToolbarForTests()
.getMenu().performIdentifierAction(R.id.selection_mode_delete_menu_id, 0)));
ThreadUtils.runOnUiThread(
()
-> Assert.assertTrue(
mUi.getDownloadManagerToolbarForTests()
.getMenu()
.performIdentifierAction(
R.id.selection_mode_delete_menu_id, 0)));
mAdapterObserver.onSpaceDisplayUpdatedCallback.waitForCallback(callCount);
Assert.assertEquals(
......@@ -360,8 +362,13 @@ public class DownloadActivityTest {
// Click the delete button.
callCount = mAdapterObserver.onSpaceDisplayUpdatedCallback.getCallCount();
ThreadUtils.runOnUiThread(() -> Assert.assertTrue(mUi.getDownloadManagerToolbarForTests()
.getMenu().performIdentifierAction(R.id.selection_mode_delete_menu_id, 0)));
ThreadUtils.runOnUiThread(
()
-> Assert.assertTrue(
mUi.getDownloadManagerToolbarForTests()
.getMenu()
.performIdentifierAction(
R.id.selection_mode_delete_menu_id, 0)));
mAdapterObserver.onSpaceDisplayUpdatedCallback.waitForCallback(callCount);
// Assert that items are temporarily removed from the adapter. The two selected items,
......@@ -495,8 +502,13 @@ public class DownloadActivityTest {
// Click the delete button.
callCount = mAdapterObserver.onSpaceDisplayUpdatedCallback.getCallCount();
ThreadUtils.runOnUiThread(() -> Assert.assertTrue(mUi.getDownloadManagerToolbarForTests()
.getMenu().performIdentifierAction(R.id.selection_mode_delete_menu_id, 0)));
ThreadUtils.runOnUiThread(
()
-> Assert.assertTrue(
mUi.getDownloadManagerToolbarForTests()
.getMenu()
.performIdentifierAction(
R.id.selection_mode_delete_menu_id, 0)));
mAdapterObserver.onSpaceDisplayUpdatedCallback.waitForCallback(callCount);
// Assert that the two items and their date bucket are temporarily removed from the adapter.
......@@ -606,10 +618,10 @@ public class DownloadActivityTest {
// Select the offline page located at position #3.
toggleItemSelection(3);
List<DownloadHistoryItemWrapper> selected_items =
List<DownloadHistoryItemWrapper> selectedItems =
mUi.getBackendProvider().getSelectionDelegate().getSelectedItemsAsList();
Assert.assertEquals("There should be only one item selected", 1, selected_items.size());
Intent shareIntent = DownloadUtils.createShareIntent(selected_items, null);
Assert.assertEquals("There should be only one item selected", 1, selectedItems.size());
Intent shareIntent = DownloadUtils.createShareIntent(selectedItems, null);
Assert.assertEquals("Incorrect intent action", Intent.ACTION_SEND, shareIntent.getAction());
Assert.assertEquals("Incorrect intent mime type", "*/*", shareIntent.getType());
......@@ -623,9 +635,9 @@ public class DownloadActivityTest {
// Pass a map that contains a new file path.
HashMap<String, String> newFilePathMap = new HashMap<String, String>();
newFilePathMap.put(((OfflineItemWrapper) selected_items.get(0)).getId(),
newFilePathMap.put(((OfflineItemWrapper) selectedItems.get(0)).getId(),
"/data/new_fake_path/Downloads/4");
shareIntent = DownloadUtils.createShareIntent(selected_items, newFilePathMap);
shareIntent = DownloadUtils.createShareIntent(selectedItems, newFilePathMap);
Assert.assertEquals("Incorrect intent action", Intent.ACTION_SEND, shareIntent.getAction());
Assert.assertEquals("Incorrect intent mime type", "*/*", shareIntent.getType());
......@@ -641,56 +653,37 @@ public class DownloadActivityTest {
@Test
@MediumTest
@DisableFeatures(ChromeFeatureList.DOWNLOADS_LOCATION_CHANGE)
public void testToggleSelection() throws Exception {
public void testLongClickItem() throws Exception {
// The selection toolbar should not be showing.
Assert.assertTrue(mAdapterObserver.mOnSelectionItems.isEmpty());
Assert.assertEquals(View.VISIBLE,
mActivityTestRule.getActivity().findViewById(R.id.close_menu_id).getVisibility());
Assert.assertEquals(View.GONE,
mActivityTestRule.getActivity()
.findViewById(R.id.selection_mode_number)
.getVisibility());
Assert.assertNull(mActivityTestRule.getActivity().findViewById(
org.chromium.chrome.download.R.id.selection_mode_share_menu_id));
Assert.assertNull(
mActivityTestRule.getActivity().findViewById(R.id.selection_mode_delete_menu_id));
onView(withContentDescription("Cancel selection")).check(doesNotExist());
onView(withId(R.id.close_menu_id)).check(matches(isDisplayed()));
onView(withId(R.id.selection_mode_number)).check(matches(not(isDisplayed())));
onView(withId(org.chromium.chrome.download.R.id.selection_mode_share_menu_id))
.check(doesNotExist());
onView(withId(R.id.selection_mode_delete_menu_id)).check(doesNotExist());
Assert.assertFalse(mStubbedProvider.getSelectionDelegate().isSelectionEnabled());
// Select an item.
toggleItemSelection(2);
onView(withText("huge_image.png")).perform(longClick());
// The toolbar should flip states to allow doing things with the selected items.
Assert.assertNull(mActivityTestRule.getActivity().findViewById(R.id.close_menu_id));
Assert.assertEquals(View.VISIBLE,
mActivityTestRule.getActivity()
.findViewById(R.id.selection_mode_number)
.getVisibility());
Assert.assertEquals(View.VISIBLE,
mActivityTestRule.getActivity()
.findViewById(
org.chromium.chrome.download.R.id.selection_mode_share_menu_id)
.getVisibility());
Assert.assertEquals(View.VISIBLE,
mActivityTestRule.getActivity()
.findViewById(R.id.selection_mode_delete_menu_id)
.getVisibility());
onView(withId(R.id.close_menu_id)).check(doesNotExist());
onView(withId(R.id.selection_mode_number)).check(matches(isDisplayed()));
onView(withId(org.chromium.chrome.download.R.id.selection_mode_share_menu_id))
.check(matches(isDisplayed()));
onView(withId(R.id.selection_mode_delete_menu_id)).check(matches(isDisplayed()));
Assert.assertTrue(mStubbedProvider.getSelectionDelegate().isSelectionEnabled());
// Deselect the same item.
toggleItemSelection(2);
onView(withText("huge_image.png")).perform(longClick());
// The toolbar should flip back.
Assert.assertTrue(mAdapterObserver.mOnSelectionItems.isEmpty());
Assert.assertEquals(View.VISIBLE,
mActivityTestRule.getActivity().findViewById(R.id.close_menu_id).getVisibility());
Assert.assertEquals(View.GONE,
mActivityTestRule.getActivity()
.findViewById(R.id.selection_mode_number)
.getVisibility());
Assert.assertNull(mActivityTestRule.getActivity().findViewById(
org.chromium.chrome.download.R.id.selection_mode_share_menu_id));
Assert.assertNull(
mActivityTestRule.getActivity().findViewById(R.id.selection_mode_delete_menu_id));
onView(withContentDescription("Cancel selection")).check(doesNotExist());
onView(withId(R.id.close_menu_id)).check(matches(isDisplayed()));
onView(withId(R.id.selection_mode_number)).check(matches(not(isDisplayed())));
onView(withId(org.chromium.chrome.download.R.id.selection_mode_share_menu_id))
.check(doesNotExist());
onView(withId(R.id.selection_mode_delete_menu_id)).check(doesNotExist());
Assert.assertFalse(mStubbedProvider.getSelectionDelegate().isSelectionEnabled());
}
......@@ -699,10 +692,10 @@ public class DownloadActivityTest {
@DisableFeatures(ChromeFeatureList.DOWNLOADS_LOCATION_CHANGE)
public void testSearchView() throws Exception {
final DownloadManagerToolbar toolbar = mUi.getDownloadManagerToolbarForTests();
View toolbarSearchView = toolbar.getSearchViewForTests();
Assert.assertEquals(View.GONE, toolbarSearchView.getVisibility());
onView(withId(R.id.search_text)).check(matches(not(isDisplayed())));
onView(withText("huge_image.png")).perform(longClick());
toggleItemSelection(2);
Assert.assertTrue(mStubbedProvider.getSelectionDelegate().isSelectionEnabled());
int callCount = mAdapterObserver.onSelectionCallback.getCallCount();
......@@ -712,21 +705,70 @@ public class DownloadActivityTest {
// The selection should be cleared when a search is started.
mAdapterObserver.onSelectionCallback.waitForCallback(callCount, 1);
Assert.assertFalse(mStubbedProvider.getSelectionDelegate().isSelectionEnabled());
Assert.assertEquals(View.VISIBLE, toolbarSearchView.getVisibility());
onView(withId(R.id.search_text)).check(matches(isDisplayed()));
// Select an item and assert that the search view is no longer showing.
toggleItemSelection(2);
onView(withText("huge_image.png")).perform(longClick());
Assert.assertTrue(mStubbedProvider.getSelectionDelegate().isSelectionEnabled());
Assert.assertEquals(View.GONE, toolbarSearchView.getVisibility());
onView(withId(R.id.search_text)).check(matches(not(isDisplayed())));
// Clear the selection and assert that the search view is showing again.
toggleItemSelection(2);
onView(withText("huge_image.png")).perform(longClick());
Assert.assertFalse(mStubbedProvider.getSelectionDelegate().isSelectionEnabled());
Assert.assertEquals(View.VISIBLE, toolbarSearchView.getVisibility());
onView(withId(R.id.search_text)).check(matches(isDisplayed()));
// Close the search view.
ThreadUtils.runOnUiThreadBlocking(() -> toolbar.onNavigationBack());
Assert.assertEquals(View.GONE, toolbarSearchView.getVisibility());
onView(withContentDescription("Go back")).perform(click());
onView(withId(R.id.search_text)).check(matches(not(isDisplayed())));
}
@Test
@MediumTest
@DisableFeatures(ChromeFeatureList.DOWNLOADS_LOCATION_CHANGE)
public void testSpinner() throws Exception {
// Open spinner.
onView(withId(org.chromium.chrome.download.R.id.spinner)).perform(click());
// Check all TextViews displayed.
onView(withText("All")).check(matches(isDisplayed()));
onView(withText("Pages")).check(matches(isDisplayed()));
onView(withText("Video")).check(matches(isDisplayed()));
onView(withText("Audio")).check(matches(isDisplayed()));
onView(withText("Images")).check(matches(isDisplayed()));
onView(withText("Documents")).check(matches(isDisplayed()));
onView(withText("Other")).check(matches(isDisplayed()));
// Click Pages.
onView(withText("Pages")).perform(click());
onView(withText("page 4")).check(matches(isDisplayed()));
// Click Video.
onView(withId(org.chromium.chrome.download.R.id.spinner)).perform(click());
onView(withText("Video")).perform(click());
onView(withText("four.webm")).check(matches(isDisplayed()));
// Click Audio.
onView(withId(org.chromium.chrome.download.R.id.spinner)).perform(click());
onView(withText("Audio")).perform(click());
onView(withText("five.mp3")).check(matches(isDisplayed()));
onView(withText("six.mp3")).check(matches(isDisplayed()));
// Click Images.
onView(withId(org.chromium.chrome.download.R.id.spinner)).perform(click());
onView(withText("Images")).perform(click());
onView(withText("huge_image.png")).check(matches(isDisplayed()));
onView(withText("first_file.jpg")).check(matches(isDisplayed()));
onView(withText("second_file.gif")).check(matches(isDisplayed()));
// Click Documents.
onView(withId(org.chromium.chrome.download.R.id.spinner)).perform(click());
onView(withText("Documents")).perform(click());
onView(withText("third_file")).check(matches(isDisplayed()));
// Click Other.
onView(withId(org.chromium.chrome.download.R.id.spinner)).perform(click());
onView(withText("Other")).perform(click());
onView(withText("No downloads here")).check(matches(isDisplayed()));
}
private DownloadActivity startDownloadActivity() throws Exception {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment