Commit 02be7d98 authored by Yue Zhang's avatar Yue Zhang Committed by Commit Bot

Update tab grid card when a closure in tab group is undone

Bug: 1027197
Change-Id: Id30af64014564ee244dade0e84eb7a14abf642bf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1931437
Commit-Queue: Yue Zhang <yuezhanggg@chromium.org>
Reviewed-by: default avatarWei-Yin Chen (陳威尹) <wychen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#718715}
parent 78fc68a2
......@@ -449,6 +449,22 @@ class TabListMediator {
}
sTabClosedFromMapTabClosedFromMap.remove(tab.getId());
}
// TODO(yuezhanggg): clean up updateTab() calls in this class.
if (mActionsOnAllRelatedTabs) {
TabModelFilter filter = mTabModelSelector.getTabModelFilterProvider()
.getCurrentTabModelFilter();
int index = filter.indexOf(tab);
if (index == TabList.INVALID_TAB_INDEX
|| getRelatedTabsForId(tab.getId()).size() == 1) {
return;
}
Tab currentGroupSelectedTab = filter.getTabAt(index);
assert mModel.indexFromId(currentGroupSelectedTab.getId()) == index;
updateTab(index, currentGroupSelectedTab,
mModel.get(index).model.get(TabProperties.IS_SELECTED), false, false);
}
}
@Override
......
......@@ -9,6 +9,7 @@ import static android.support.test.espresso.action.ViewActions.click;
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.RootMatchers.withDecorView;
import static android.support.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withParent;
......@@ -30,13 +31,17 @@ import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.v
import android.graphics.Rect;
import android.support.test.espresso.Espresso;
import android.support.test.espresso.NoMatchingRootException;
import android.support.test.espresso.UiController;
import android.support.test.espresso.ViewAction;
import android.support.test.espresso.contrib.RecyclerViewActions;
import android.support.test.filters.MediumTest;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TextView;
import org.hamcrest.Matcher;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
......@@ -218,6 +223,38 @@ public class TabGridDialogTest {
CriteriaHelper.pollInstrumentationThread(() -> isDialogShowing(cta));
}
@Test
@MediumTest
public void testUndoClosureInDialog() throws InterruptedException {
final ChromeTabbedActivity cta = mActivityTestRule.getActivity();
createTabs(cta, false, 2);
enterTabSwitcher(cta);
verifyTabSwitcherCardCount(cta, 2);
// Create a tab group.
mergeAllTabsToAGroup(cta);
verifyTabSwitcherCardCount(cta, 1);
// Open dialog and verify dialog is showing correct content.
openDialogFromTabSwitcherAndVerify(cta, 2);
// Click close button to close the first tab in group.
closeFirstTabInDialog(cta);
verifyShowingDialog(cta, 1);
// Exit dialog, wait for the undo bar showing and undo the closure.
TabUiTestHelper.clickScrimToExitDialog(cta);
CriteriaHelper.pollInstrumentationThread(() -> !isDialogShowing(cta));
CriteriaHelper.pollInstrumentationThread(this::verifyUndoBarShowingAndClickUndo);
// Verify the undo has happened.
onView(withId(R.id.tab_title)).check((v, noMatchException) -> {
TextView textView = (TextView) v;
assertEquals("2 tabs", textView.getText().toString());
});
openDialogFromTabSwitcherAndVerify(cta, 2);
}
private void mergeAllTabsToAGroup(ChromeTabbedActivity cta) {
List<Tab> tabGroup = new ArrayList<>();
TabModel tabModel = cta.getTabModelSelector().getModel(false);
......@@ -312,4 +349,42 @@ public class TabGridDialogTest {
assertEquals(isEnabled, v.isFocused());
});
}
private void closeFirstTabInDialog(ChromeTabbedActivity cta) {
onView(withId(R.id.tab_list_view))
.inRoot(withDecorView(not(cta.getWindow().getDecorView())))
.perform(new ViewAction() {
@Override
public Matcher<View> getConstraints() {
return isDisplayed();
}
@Override
public String getDescription() {
return "close first tab";
}
@Override
public void perform(UiController uiController, View view) {
RecyclerView recyclerView = (RecyclerView) view;
RecyclerView.ViewHolder viewHolder =
recyclerView.findViewHolderForAdapterPosition(0);
assert viewHolder != null;
viewHolder.itemView.findViewById(R.id.action_button).performClick();
}
});
}
private boolean verifyUndoBarShowingAndClickUndo() {
boolean isShowing = true;
try {
onView(withId(R.id.snackbar_button)).check(matches(isCompletelyDisplayed()));
onView(withId(R.id.snackbar_button)).perform(click());
} catch (NoMatchingRootException | AssertionError e) {
isShowing = false;
} catch (Exception e) {
assert false : "error when verifying undo snack bar.";
}
return isShowing;
}
}
......@@ -12,7 +12,6 @@ import static android.support.test.espresso.matcher.RootMatchers.withDecorView;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
......@@ -24,15 +23,11 @@ import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.r
import android.content.res.Configuration;
import android.os.Build;
import android.support.test.espresso.NoMatchingRootException;
import android.support.test.espresso.UiController;
import android.support.test.espresso.ViewAction;
import android.support.test.filters.MediumTest;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.hamcrest.Matcher;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
......@@ -48,7 +43,6 @@ import org.chromium.chrome.browser.ChromeSwitches;
import org.chromium.chrome.browser.ChromeTabbedActivity;
import org.chromium.chrome.browser.compositor.layouts.Layout;
import org.chromium.chrome.browser.flags.FeatureUtilities;
import org.chromium.chrome.browser.widget.ScrimView;
import org.chromium.chrome.features.start_surface.StartSurfaceLayout;
import org.chromium.chrome.tab_ui.R;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
......@@ -103,7 +97,7 @@ public class TabGridIphItemTest {
// Enter the IPH dialog and exit by clicking ScrimView.
enterIphDialog(cta);
verifyIphDialogShowing(cta);
exitIphDialogByClickingScrim(cta);
TabUiTestHelper.clickScrimToExitDialog(cta);
verifyIphDialogHiding(cta);
// Exiting IPH dialog should not dismiss the IPH.
......@@ -195,29 +189,6 @@ public class TabGridIphItemTest {
.perform(click());
}
private void exitIphDialogByClickingScrim(ChromeTabbedActivity cta) {
onView(instanceOf(ScrimView.class))
.inRoot(withDecorView(not(cta.getWindow().getDecorView())))
.perform(new ViewAction() {
@Override
public Matcher<View> getConstraints() {
return isDisplayed();
}
@Override
public String getDescription() {
return "click on ScrimView";
}
@Override
public void perform(UiController uiController, View view) {
assertTrue(view instanceof ScrimView);
ScrimView scrimView = (ScrimView) view;
scrimView.performClick();
}
});
}
private void enterIphDialog(ChromeTabbedActivity cta) {
assertTrue(cta.getLayoutManager().overviewVisible());
onView(withId(R.id.show_me_button)).perform(click());
......
......@@ -6,10 +6,14 @@ package org.chromium.chrome.browser.tasks.tab_management;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.matcher.RootMatchers.withDecorView;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withParent;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
......@@ -25,11 +29,15 @@ import android.provider.Settings;
import android.support.annotation.Nullable;
import android.support.test.InstrumentationRegistry;
import android.support.test.espresso.NoMatchingViewException;
import android.support.test.espresso.UiController;
import android.support.test.espresso.ViewAction;
import android.support.test.espresso.ViewAssertion;
import android.support.test.espresso.contrib.RecyclerViewActions;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import org.hamcrest.Matcher;
import org.chromium.base.ContextUtils;
import org.chromium.chrome.browser.ChromeTabbedActivity;
import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
......@@ -37,6 +45,7 @@ import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tabmodel.TabModel;
import org.chromium.chrome.browser.tabmodel.TabSelectionType;
import org.chromium.chrome.browser.tasks.tab_groups.TabGroupModelFilter;
import org.chromium.chrome.browser.widget.ScrimView;
import org.chromium.chrome.tab_ui.R;
import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
import org.chromium.chrome.test.util.ChromeTabUtils;
......@@ -324,6 +333,33 @@ public class TabUiTestHelper {
DEFAULT_MAX_TIME_TO_POLL * 10, DEFAULT_POLLING_INTERVAL);
}
/**
* Exit the PopupWindow dialog by clicking the outer ScrimView.
* @param cta The current running activity.
*/
static void clickScrimToExitDialog(ChromeTabbedActivity cta) {
onView(instanceOf(ScrimView.class))
.inRoot(withDecorView(not(cta.getWindow().getDecorView())))
.perform(new ViewAction() {
@Override
public Matcher<View> getConstraints() {
return isDisplayed();
}
@Override
public String getDescription() {
return "click on ScrimView";
}
@Override
public void perform(UiController uiController, View view) {
assertTrue(view instanceof ScrimView);
ScrimView scrimView = (ScrimView) view;
scrimView.performClick();
}
});
}
/**
* Implementation of {@link ViewAssertion} to verify the {@link RecyclerView} has correct number
* of children, and children are showing correctly.
......
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