Commit 9f7b813b authored by Mei Liang's avatar Mei Liang Committed by Commit Bot

[Test][TabSelectionEditor] Add end to end tests

This CL adds the following:
  * End to end tests for TabSelectionEditor
  * Some customized RecyclerViewMatchers
  * A TabSelectionEditorTestingRobot that allows others to perform and
    verify action within the TabSelectionEditor.

Change-Id: Ic7283772374a0c0ed2a3aca84d4e4d245118fd04
Bug: 983170
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1894413
Commit-Queue: Mei Liang <meiliang@chromium.org>
Reviewed-by: default avatarWei-Yin Chen (陳威尹) <wychen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#712906}
parent 276ce52d
......@@ -100,6 +100,7 @@ class TabGridViewBinder {
} else if (TabProperties.IS_SELECTED == propertyKey) {
int selectedTabBackground =
model.get(TabProperties.SELECTED_TAB_BACKGROUND_DRAWABLE_ID);
view.setSelected(model.get(TabProperties.IS_SELECTED));
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) {
if (model.get(TabProperties.IS_SELECTED)) {
view.fastFindViewById(R.id.selected_view_below_lollipop)
......
......@@ -110,8 +110,11 @@ public class TabListCoordinator implements Destroyable {
RecyclerView.RecyclerListener recyclerListener = null;
if (mMode == TabListMode.GRID || mMode == TabListMode.CAROUSEL) {
mAdapter.registerType(UiType.SELECTABLE, () -> {
return (ViewGroup) LayoutInflater.from(context).inflate(
ViewGroup group = (ViewGroup) LayoutInflater.from(context).inflate(
R.layout.selectable_tab_grid_card_item, parentView, false);
group.setClickable(true);
return group;
}, TabGridViewBinder::bindSelectableTab);
mAdapter.registerType(UiType.CLOSABLE, () -> {
......@@ -121,6 +124,7 @@ public class TabListCoordinator implements Destroyable {
group.getLayoutParams().width = context.getResources().getDimensionPixelSize(
R.dimen.tab_carousel_card_width);
}
group.setClickable(true);
return group;
}, TabGridViewBinder::bindClosableTab);
......
// Copyright 2019 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.tasks.tab_management;
import android.support.test.espresso.matcher.BoundedMatcher;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
/**
* Contains useful RecyclerViewMatcher.
*/
public class RecyclerViewMatcherUtils {
/**
* This view matcher matches a RecyclerView that has a given number of items in its adapter.
*
* @param itemCount The matches item count.
* @return A matcher that matches RecyclerView with its adapter item count.
*/
public static Matcher<View> adapterHasItemCount(int itemCount) {
return new BoundedMatcher<View, RecyclerView>(RecyclerView.class) {
@Override
protected boolean matchesSafely(RecyclerView recyclerView) {
return recyclerView.getAdapter().getItemCount() == itemCount;
}
@Override
public void describeTo(Description description) {
description.appendText("RecyclerView.Adapter has " + itemCount + " items");
}
};
}
/**
* This view matcher matches a RecyclerView that has a view that matches the given view matcher
* at the given adapter position.
*
* First this matcher scrolls the RecyclerView to the given position and then matches with the
* given view matcher.
*
* @param position The matches adapter position.
* @param itemMatcher A view matcher to match.
* @return A matcher that matches RecyclerView with its adapter item position and the given view
* matcher.
*/
public static Matcher<View> atPosition(int position, Matcher<View> itemMatcher) {
return new BoundedMatcher<View, RecyclerView>(RecyclerView.class) {
@Override
protected boolean matchesSafely(RecyclerView recyclerView) {
recyclerView.scrollToPosition(position);
RecyclerView.ViewHolder viewHolder =
recyclerView.findViewHolderForAdapterPosition(position);
if (viewHolder == null) return false;
return itemMatcher.matches(viewHolder.itemView);
}
@Override
public void describeTo(Description description) {
description.appendText("has view " + itemMatcher + " at position " + position);
}
};
}
}
// Copyright 2019 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.tasks.tab_management;
import android.support.test.filters.MediumTest;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.chrome.browser.ChromeSwitches;
import org.chromium.chrome.browser.flags.FeatureUtilities;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tabmodel.TabModel;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.tab_ui.R;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
import org.chromium.chrome.test.util.browser.Features;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
import java.util.ArrayList;
import java.util.List;
/**
* End-to-end test for TabSelectionEditor.
*/
@RunWith(ChromeJUnit4ClassRunner.class)
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
public class TabSelectionEditorTest {
@Rule
public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
@Rule
public TestRule mProcessor = new Features.InstrumentationProcessor();
private TabSelectionEditorTestingRobot mRobot = new TabSelectionEditorTestingRobot();
private TabModelSelector mTabModelSelector;
private TabSelectionEditorCoordinator
.TabSelectionEditorController mTabSelectionEditorController;
@Before
public void setUp() throws Exception {
FeatureUtilities.setTabGroupsAndroidEnabledForTesting(true);
mActivityTestRule.startMainActivityFromLauncher();
TabUiTestHelper.createTabs(mActivityTestRule.getActivity(), false, 2);
mTabModelSelector = mActivityTestRule.getActivity().getTabModelSelector();
TestThreadUtils.runOnUiThreadBlocking(() -> {
TabSelectionEditorCoordinator tabSelectionEditorCoordinator =
new TabSelectionEditorCoordinator(mActivityTestRule.getActivity(),
mActivityTestRule.getActivity().getCurrentFocus(), mTabModelSelector,
mActivityTestRule.getActivity().getTabContentManager(), null);
mTabSelectionEditorController = tabSelectionEditorCoordinator.getController();
});
}
@Test
@MediumTest
public void testShowTabs() {
List<Tab> tabs = getTabsInCurrentTabModel();
TestThreadUtils.runOnUiThreadBlocking(() -> { mTabSelectionEditorController.show(tabs); });
mRobot.resultRobot.verifyTabSelectionEditorIsVisible()
.verifyToolbarActionButtonDisabled()
.verifyToolbarActionButtonWithResourceId(R.string.tab_selection_editor_group)
.verifyToolbarSelectionTextWithResourceId(
R.string.tab_selection_editor_toolbar_select_tabs)
.verifyAdapterHasItemCount(tabs.size())
.verifyHasAtLeastNItemVisible(1);
}
@Test
@MediumTest
public void testToggleItem() {
List<Tab> tabs = getTabsInCurrentTabModel();
TestThreadUtils.runOnUiThreadBlocking(() -> { mTabSelectionEditorController.show(tabs); });
mRobot.resultRobot.verifyItemNotSelectedAtAdapterPosition(0);
mRobot.actionRobot.clickItemAtAdapterPosition(0);
mRobot.resultRobot.verifyItemSelectedAtAdapterPosition(0).verifyToolbarSelectionText(
"1 selected");
mRobot.actionRobot.clickItemAtAdapterPosition(0);
mRobot.resultRobot.verifyItemNotSelectedAtAdapterPosition(0)
.verifyToolbarSelectionTextWithResourceId(
R.string.tab_selection_editor_toolbar_select_tabs);
}
@Test
@MediumTest
public void testToolbarNavigationButtonHideTabSelectionEditor() {
List<Tab> tabs = getTabsInCurrentTabModel();
TestThreadUtils.runOnUiThreadBlocking(() -> { mTabSelectionEditorController.show(tabs); });
mRobot.resultRobot.verifyTabSelectionEditorIsVisible();
mRobot.actionRobot.clickToolbarNavigationButton();
mRobot.resultRobot.verifyTabSelectionEditorIsHidden();
}
@Test
@MediumTest
public void testToolbarGroupButtonEnabledState() {
List<Tab> tabs = getTabsInCurrentTabModel();
TestThreadUtils.runOnUiThreadBlocking(() -> { mTabSelectionEditorController.show(tabs); });
mRobot.resultRobot.verifyToolbarActionButtonDisabled()
.verifyToolbarActionButtonWithResourceId(R.string.tab_selection_editor_group);
mRobot.actionRobot.clickItemAtAdapterPosition(0);
mRobot.resultRobot.verifyToolbarActionButtonDisabled();
mRobot.actionRobot.clickItemAtAdapterPosition(1);
mRobot.resultRobot.verifyToolbarActionButtonEnabled();
mRobot.actionRobot.clickItemAtAdapterPosition(1);
mRobot.resultRobot.verifyToolbarActionButtonDisabled();
}
@Test
@MediumTest
public void testToolbarGroupButton() {
List<Tab> tabs = getTabsInCurrentTabModel();
TestThreadUtils.runOnUiThreadBlocking(() -> { mTabSelectionEditorController.show(tabs); });
mRobot.resultRobot.verifyToolbarActionButtonWithResourceId(
R.string.tab_selection_editor_group);
mRobot.actionRobot.clickItemAtAdapterPosition(0)
.clickItemAtAdapterPosition(1)
.clickToolbarActionButton();
mRobot.resultRobot.verifyTabSelectionEditorIsHidden();
// TODO(1021803): verify the undo snack after the bug is resolved.
// verifyUndoSnackbarWithTextIsShown(mActivityTestRule.getActivity().getString(
// R.string.undo_bar_group_tabs_message, 2));
}
@Test
@MediumTest
public void testConfigureToolbar_ActionButtonEnableThreshold() {
List<Tab> tabs = getTabsInCurrentTabModel();
int enableThreshold = 1;
TestThreadUtils.runOnUiThreadBlocking(() -> {
mTabSelectionEditorController.configureToolbar("Test", null, enableThreshold, null);
mTabSelectionEditorController.show(tabs);
});
mRobot.resultRobot.verifyToolbarActionButtonDisabled().verifyToolbarActionButtonWithText(
"Test");
for (int i = 0; i < enableThreshold; i++) {
mRobot.actionRobot.clickItemAtAdapterPosition(i);
}
mRobot.resultRobot.verifyToolbarActionButtonEnabled();
mRobot.actionRobot.clickItemAtAdapterPosition(enableThreshold - 1);
mRobot.resultRobot.verifyToolbarActionButtonDisabled();
}
private List<Tab> getTabsInCurrentTabModel() {
List<Tab> tabs = new ArrayList<>();
TabModel currentTabModel = mTabModelSelector.getCurrentModel();
for (int i = 0; i < currentTabModel.getCount(); i++) {
tabs.add(currentTabModel.getTabAt(i));
}
return tabs;
}
}
......@@ -35,9 +35,12 @@ tab_management_test_java_sources = [
"//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListContainerViewBinderTest.java",
"//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java",
"//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorLayoutBinderTest.java",
"//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorTest.java",
"//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSelectionEditorTestingRobot.java",
"//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMultiWindowTest.java",
"//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabUiTestHelper.java",
"//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TestRecyclerViewSimpleViewBinder.java",
"//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/RecyclerViewMatcherUtils.java",
]
tab_management_junit_java_sources = [
......
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