Commit 54010ef0 authored by Yue Zhang's avatar Yue Zhang Committed by Commit Bot

Add e2e tests for ungrouping through TabGridDialog selection mode

Bug: 983170, 1035995
Change-Id: Iecc3809a4578bee16f80f93f00fc68047db61422
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1976300
Commit-Queue: Yue Zhang <yuezhanggg@chromium.org>
Reviewed-by: default avatarWei-Yin Chen (陳威尹) <wychen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#738632}
parent 628ee921
...@@ -29,6 +29,7 @@ import static org.junit.Assert.assertTrue; ...@@ -29,6 +29,7 @@ import static org.junit.Assert.assertTrue;
import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.clickFirstCardFromTabSwitcher; import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.clickFirstCardFromTabSwitcher;
import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.clickFirstTabInDialog; import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.clickFirstTabInDialog;
import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.clickScrimToExitDialog;
import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.closeFirstTabInDialog; import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.closeFirstTabInDialog;
import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.createTabs; import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.createTabs;
import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.enterTabSwitcher; import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.enterTabSwitcher;
...@@ -68,6 +69,7 @@ import org.chromium.chrome.browser.ChromeTabbedActivity; ...@@ -68,6 +69,7 @@ import org.chromium.chrome.browser.ChromeTabbedActivity;
import org.chromium.chrome.browser.compositor.layouts.Layout; import org.chromium.chrome.browser.compositor.layouts.Layout;
import org.chromium.chrome.browser.flags.CachedFeatureFlags; import org.chromium.chrome.browser.flags.CachedFeatureFlags;
import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.tasks.tab_groups.TabGroupModelFilter;
import org.chromium.chrome.features.start_surface.StartSurfaceLayout; import org.chromium.chrome.features.start_surface.StartSurfaceLayout;
import org.chromium.chrome.tab_ui.R; import org.chromium.chrome.tab_ui.R;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
...@@ -87,6 +89,8 @@ public class TabGridDialogTest { ...@@ -87,6 +89,8 @@ public class TabGridDialogTest {
// clang-format on // clang-format on
private boolean mHasReceivedSourceRect; private boolean mHasReceivedSourceRect;
private TabSelectionEditorTestingRobot mSelectionEditorRobot =
new TabSelectionEditorTestingRobot();
@Rule @Rule
public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule(); public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
...@@ -133,7 +137,7 @@ public class TabGridDialogTest { ...@@ -133,7 +137,7 @@ public class TabGridDialogTest {
// Press back and dialog should be hidden. // Press back and dialog should be hidden.
Espresso.pressBack(); Espresso.pressBack();
CriteriaHelper.pollInstrumentationThread(() -> !isDialogShowing(cta)); waitForDialogHidingAnimationInTabSwitcher(cta);
verifyTabSwitcherCardCount(cta, 1); verifyTabSwitcherCardCount(cta, 1);
...@@ -146,7 +150,7 @@ public class TabGridDialogTest { ...@@ -146,7 +150,7 @@ public class TabGridDialogTest {
// Press back and dialog should be hidden. // Press back and dialog should be hidden.
Espresso.pressBack(); Espresso.pressBack();
CriteriaHelper.pollInstrumentationThread(() -> !isDialogShowing(cta)); waitForDialogHidingAnimation(cta);
} }
@Test @Test
...@@ -258,8 +262,8 @@ public class TabGridDialogTest { ...@@ -258,8 +262,8 @@ public class TabGridDialogTest {
verifyShowingDialog(cta, 1); verifyShowingDialog(cta, 1);
// Exit dialog, wait for the undo bar showing and undo the closure. // Exit dialog, wait for the undo bar showing and undo the closure.
TabUiTestHelper.clickScrimToExitDialog(cta); clickScrimToExitDialog(cta);
CriteriaHelper.pollInstrumentationThread(() -> !isDialogShowing(cta)); waitForDialogHidingAnimationInTabSwitcher(cta);
CriteriaHelper.pollInstrumentationThread(this::verifyUndoBarShowingAndClickUndo); CriteriaHelper.pollInstrumentationThread(this::verifyUndoBarShowingAndClickUndo);
// Verify the undo has happened. // Verify the undo has happened.
...@@ -295,8 +299,8 @@ public class TabGridDialogTest { ...@@ -295,8 +299,8 @@ public class TabGridDialogTest {
verifyShowingDialog(cta, 1); verifyShowingDialog(cta, 1);
// Exit dialog, wait for the undo bar showing and undo the closure. // Exit dialog, wait for the undo bar showing and undo the closure.
TabUiTestHelper.clickScrimToExitDialog(cta); clickScrimToExitDialog(cta);
CriteriaHelper.pollInstrumentationThread(() -> !isDialogShowing(cta)); waitForDialogHidingAnimation(cta);
CriteriaHelper.pollInstrumentationThread(this::verifyUndoBarShowingAndClickUndo); CriteriaHelper.pollInstrumentationThread(this::verifyUndoBarShowingAndClickUndo);
// Verify the undo has happened. // Verify the undo has happened.
...@@ -327,6 +331,100 @@ public class TabGridDialogTest { ...@@ -327,6 +331,100 @@ public class TabGridDialogTest {
triggerShareGroupAndVerify(cta); triggerShareGroupAndVerify(cta);
} }
@Test
@MediumTest
@Features.EnableFeatures(ChromeFeatureList.TAB_GROUPS_CONTINUATION_ANDROID)
public void testSelectionEditorShowHide() throws InterruptedException {
final ChromeTabbedActivity cta = mActivityTestRule.getActivity();
createTabs(cta, false, 2);
enterTabSwitcher(cta);
verifyTabSwitcherCardCount(cta, 2);
// Create a tab group.
mergeAllNormalTabsToAGroup(cta);
verifyTabSwitcherCardCount(cta, 1);
// Open dialog and open selection editor.
openDialogFromTabSwitcherAndVerify(cta, 2);
openSelectionEditorAndVerify(cta, 2);
// Click navigation button should close selection editor but not tab grid dialog.
mSelectionEditorRobot.actionRobot.clickToolbarNavigationButton();
mSelectionEditorRobot.resultRobot.verifyTabSelectionEditorIsHidden();
assertTrue(isDialogShowing(cta));
// Back press should close both the dialog and selection editor.
openSelectionEditorAndVerify(cta, 2);
Espresso.pressBack();
mSelectionEditorRobot.resultRobot.verifyTabSelectionEditorIsHidden();
waitForDialogHidingAnimationInTabSwitcher(cta);
verifyTabSwitcherCardCount(cta, 1);
// Clicking ScrimView should close both the dialog and selection editor.
openDialogFromTabSwitcherAndVerify(cta, 2);
openSelectionEditorAndVerify(cta, 2);
clickScrimToExitDialog(cta);
mSelectionEditorRobot.resultRobot.verifyTabSelectionEditorIsHidden();
waitForDialogHidingAnimationInTabSwitcher(cta);
verifyTabSwitcherCardCount(cta, 1);
}
@Test
@MediumTest
@Features.EnableFeatures(ChromeFeatureList.TAB_GROUPS_CONTINUATION_ANDROID)
public void testSelectionEditorUngroup() throws InterruptedException {
final ChromeTabbedActivity cta = mActivityTestRule.getActivity();
assertTrue(cta.getTabModelSelector().getTabModelFilterProvider().getCurrentTabModelFilter()
instanceof TabGroupModelFilter);
final TabGroupModelFilter filter = (TabGroupModelFilter) cta.getTabModelSelector()
.getTabModelFilterProvider()
.getCurrentTabModelFilter();
createTabs(cta, false, 3);
enterTabSwitcher(cta);
verifyTabSwitcherCardCount(cta, 3);
// Create a tab group.
mergeAllNormalTabsToAGroup(cta);
verifyTabSwitcherCardCount(cta, 1);
assertEquals(1, filter.getCount());
// Open dialog and open selection editor.
openDialogFromTabSwitcherAndVerify(cta, 3);
openSelectionEditorAndVerify(cta, 3);
// Select and ungroup the first tab.
mSelectionEditorRobot.actionRobot.clickItemAtAdapterPosition(0);
mSelectionEditorRobot.resultRobot.verifyItemSelectedAtAdapterPosition(0)
.verifyToolbarActionButtonEnabled()
.verifyToolbarSelectionText("1 selected");
mSelectionEditorRobot.actionRobot.clickToolbarActionButton();
mSelectionEditorRobot.resultRobot.verifyTabSelectionEditorIsHidden();
verifyShowingDialog(cta, 2);
clickScrimToExitDialog(cta);
waitForDialogHidingAnimationInTabSwitcher(cta);
verifyTabSwitcherCardCount(cta, 2);
assertEquals(2, filter.getCount());
// Open dialog and open selection editor.
openDialogFromTabSwitcherAndVerify(cta, 2);
openSelectionEditorAndVerify(cta, 2);
// Select and ungroup all two tabs in dialog.
mSelectionEditorRobot.actionRobot.clickItemAtAdapterPosition(0).clickItemAtAdapterPosition(
1);
mSelectionEditorRobot.resultRobot.verifyItemSelectedAtAdapterPosition(0)
.verifyItemSelectedAtAdapterPosition(1)
.verifyToolbarActionButtonEnabled()
.verifyToolbarSelectionText("2 selected");
mSelectionEditorRobot.actionRobot.clickToolbarActionButton();
mSelectionEditorRobot.resultRobot.verifyTabSelectionEditorIsHidden();
waitForDialogHidingAnimationInTabSwitcher(cta);
verifyTabSwitcherCardCount(cta, 3);
assertEquals(3, filter.getCount());
}
private void openDialogFromTabSwitcherAndVerify(ChromeTabbedActivity cta, int tabCount) { private void openDialogFromTabSwitcherAndVerify(ChromeTabbedActivity cta, int tabCount) {
clickFirstCardFromTabSwitcher(cta); clickFirstCardFromTabSwitcher(cta);
CriteriaHelper.pollInstrumentationThread(() -> isDialogShowing(cta)); CriteriaHelper.pollInstrumentationThread(() -> isDialogShowing(cta));
...@@ -450,4 +548,42 @@ public class TabGridDialogTest { ...@@ -450,4 +548,42 @@ public class TabGridDialogTest {
} }
Intents.release(); Intents.release();
} }
private void waitForDialogHidingAnimation(ChromeTabbedActivity cta) {
CriteriaHelper.pollInstrumentationThread(() -> !isDialogShowing(cta));
}
private void waitForDialogHidingAnimationInTabSwitcher(ChromeTabbedActivity cta) {
waitForDialogHidingAnimation(cta);
// Animation source card becomes alpha = 0f when dialog is showing and animates back to 1f
// when dialog hides. Make sure the source card has restored its alpha change.
CriteriaHelper.pollUiThread(() -> {
RecyclerView recyclerView = cta.findViewById(R.id.tab_list_view);
for (int i = 0; i < recyclerView.getAdapter().getItemCount(); i++) {
RecyclerView.ViewHolder viewHolder =
recyclerView.findViewHolderForAdapterPosition(i);
if (viewHolder == null) continue;
if (viewHolder.itemView.getAlpha() != 1f) return false;
}
return true;
});
}
private void openSelectionEditorAndVerify(ChromeTabbedActivity cta, int count) {
// Open tab selection editor by selecting ungroup item in tab grid dialog menu.
onView(withId(R.id.toolbar_menu_button))
.inRoot(withDecorView(not(cta.getWindow().getDecorView())))
.perform(click());
onView(withText(cta.getString(R.string.tab_grid_dialog_toolbar_remove_from_group)))
.inRoot(withDecorView(not(cta.getWindow().getDecorView())))
.perform(click());
mSelectionEditorRobot.resultRobot.verifyTabSelectionEditorIsVisible()
.verifyToolbarActionButtonDisabled()
.verifyToolbarActionButtonWithResourceId(
R.string.tab_grid_dialog_selection_mode_remove)
.verifyToolbarSelectionTextWithResourceId(
R.string.tab_selection_editor_toolbar_select_tabs)
.verifyAdapterHasItemCount(count);
}
} }
...@@ -30,6 +30,7 @@ import static org.chromium.chrome.browser.tasks.tab_management.RecyclerViewMatch ...@@ -30,6 +30,7 @@ import static org.chromium.chrome.browser.tasks.tab_management.RecyclerViewMatch
import android.os.Build; import android.os.Build;
import android.support.test.espresso.NoMatchingRootException; import android.support.test.espresso.NoMatchingRootException;
import android.support.test.espresso.NoMatchingViewException;
import android.support.test.espresso.Root; import android.support.test.espresso.Root;
import android.support.test.espresso.matcher.BoundedMatcher; import android.support.test.espresso.matcher.BoundedMatcher;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
...@@ -181,7 +182,7 @@ public class TabSelectionEditorTestingRobot { ...@@ -181,7 +182,7 @@ public class TabSelectionEditorTestingRobot {
onView(withId(org.chromium.chrome.tab_ui.R.id.selectable_list)) onView(withId(org.chromium.chrome.tab_ui.R.id.selectable_list))
.inRoot(isTabSelectionEditorPopup()) .inRoot(isTabSelectionEditorPopup())
.check(matches(isDisplayed())); .check(matches(isDisplayed()));
} catch (NoMatchingRootException e) { } catch (NoMatchingRootException | NoMatchingViewException e) {
return this; return this;
} }
......
...@@ -31,6 +31,7 @@ import android.support.annotation.Nullable; ...@@ -31,6 +31,7 @@ import android.support.annotation.Nullable;
import android.support.test.InstrumentationRegistry; import android.support.test.InstrumentationRegistry;
import android.support.test.espresso.NoMatchingRootException; import android.support.test.espresso.NoMatchingRootException;
import android.support.test.espresso.NoMatchingViewException; import android.support.test.espresso.NoMatchingViewException;
import android.support.test.espresso.Root;
import android.support.test.espresso.UiController; import android.support.test.espresso.UiController;
import android.support.test.espresso.ViewAction; import android.support.test.espresso.ViewAction;
import android.support.test.espresso.ViewAssertion; import android.support.test.espresso.ViewAssertion;
...@@ -38,7 +39,9 @@ import android.support.test.espresso.contrib.RecyclerViewActions; ...@@ -38,7 +39,9 @@ import android.support.test.espresso.contrib.RecyclerViewActions;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.view.View; import android.view.View;
import org.hamcrest.Description;
import org.hamcrest.Matcher; import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.chromium.base.ContextUtils; import org.chromium.base.ContextUtils;
import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.ChromeTabbedActivity;
...@@ -462,7 +465,22 @@ public class TabUiTestHelper { ...@@ -462,7 +465,22 @@ public class TabUiTestHelper {
*/ */
static void clickScrimToExitDialog(ChromeTabbedActivity cta) { static void clickScrimToExitDialog(ChromeTabbedActivity cta) {
onView(instanceOf(ScrimView.class)) onView(instanceOf(ScrimView.class))
.inRoot(withDecorView(not(cta.getWindow().getDecorView()))) .inRoot(new TypeSafeMatcher<Root>() {
@Override
protected boolean matchesSafely(Root root) {
// Make sure we match the root window that takes up the whole screen.
return root.getDecorView() != cta.getWindow().getDecorView()
&& root.getDecorView().getWidth()
>= cta.getCompositorViewHolder().getWidth()
&& root.getDecorView().getHeight()
>= cta.getCompositorViewHolder().getHeight();
}
@Override
public void describeTo(Description description) {
description.appendText("is full screen PopupWindow");
}
})
.perform(new ViewAction() { .perform(new ViewAction() {
@Override @Override
public Matcher<View> getConstraints() { public Matcher<View> getConstraints() {
...@@ -485,7 +503,7 @@ public class TabUiTestHelper { ...@@ -485,7 +503,7 @@ public class TabUiTestHelper {
/** /**
* Implementation of {@link ViewAssertion} to verify the {@link RecyclerView} has correct number * Implementation of {@link ViewAssertion} to verify the {@link RecyclerView} has correct number
* of children, and children are showing correctly. * of children.
*/ */
public static class ChildrenCountAssertion implements ViewAssertion { public static class ChildrenCountAssertion implements ViewAssertion {
private int mExpectedCount; private int mExpectedCount;
...@@ -506,16 +524,6 @@ public class TabUiTestHelper { ...@@ -506,16 +524,6 @@ public class TabUiTestHelper {
RecyclerView.Adapter adapter = recyclerView.getAdapter(); RecyclerView.Adapter adapter = recyclerView.getAdapter();
CriteriaHelper.pollUiThread( CriteriaHelper.pollUiThread(
Criteria.equals(mExpectedCount, () -> adapter.getItemCount())); Criteria.equals(mExpectedCount, () -> adapter.getItemCount()));
recyclerView.setItemAnimator(null); // Disable animation to reduce flakiness.
for (int i = 0; i < mExpectedCount; i++) {
RecyclerView.ViewHolder viewHolder =
recyclerView.findViewHolderForAdapterPosition(i);
if (viewHolder == null) return;
// This is to check if dialog hiding animation plays properly.
assertTrue(1f == viewHolder.itemView.getAlpha());
assertEquals(View.VISIBLE, viewHolder.itemView.getVisibility());
}
} }
} }
} }
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