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 { ...@@ -449,6 +449,22 @@ class TabListMediator {
} }
sTabClosedFromMapTabClosedFromMap.remove(tab.getId()); 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 @Override
......
...@@ -9,6 +9,7 @@ import static android.support.test.espresso.action.ViewActions.click; ...@@ -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.doesNotExist;
import static android.support.test.espresso.assertion.ViewAssertions.matches; 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.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.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId; import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withParent; import static android.support.test.espresso.matcher.ViewMatchers.withParent;
...@@ -30,13 +31,17 @@ import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.v ...@@ -30,13 +31,17 @@ import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.v
import android.graphics.Rect; import android.graphics.Rect;
import android.support.test.espresso.Espresso; import android.support.test.espresso.Espresso;
import android.support.test.espresso.NoMatchingRootException; 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.espresso.contrib.RecyclerViewActions;
import android.support.test.filters.MediumTest; import android.support.test.filters.MediumTest;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView;
import org.hamcrest.Matcher;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
...@@ -218,6 +223,38 @@ public class TabGridDialogTest { ...@@ -218,6 +223,38 @@ public class TabGridDialogTest {
CriteriaHelper.pollInstrumentationThread(() -> isDialogShowing(cta)); 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) { private void mergeAllTabsToAGroup(ChromeTabbedActivity cta) {
List<Tab> tabGroup = new ArrayList<>(); List<Tab> tabGroup = new ArrayList<>();
TabModel tabModel = cta.getTabModelSelector().getModel(false); TabModel tabModel = cta.getTabModelSelector().getModel(false);
...@@ -312,4 +349,42 @@ public class TabGridDialogTest { ...@@ -312,4 +349,42 @@ public class TabGridDialogTest {
assertEquals(isEnabled, v.isFocused()); 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; ...@@ -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.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId; import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
...@@ -24,15 +23,11 @@ import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.r ...@@ -24,15 +23,11 @@ import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.r
import android.content.res.Configuration; import android.content.res.Configuration;
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.UiController;
import android.support.test.espresso.ViewAction;
import android.support.test.filters.MediumTest; import android.support.test.filters.MediumTest;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import org.hamcrest.Matcher;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
...@@ -48,7 +43,6 @@ import org.chromium.chrome.browser.ChromeSwitches; ...@@ -48,7 +43,6 @@ import org.chromium.chrome.browser.ChromeSwitches;
import org.chromium.chrome.browser.ChromeTabbedActivity; 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.FeatureUtilities; 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.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;
...@@ -103,7 +97,7 @@ public class TabGridIphItemTest { ...@@ -103,7 +97,7 @@ public class TabGridIphItemTest {
// Enter the IPH dialog and exit by clicking ScrimView. // Enter the IPH dialog and exit by clicking ScrimView.
enterIphDialog(cta); enterIphDialog(cta);
verifyIphDialogShowing(cta); verifyIphDialogShowing(cta);
exitIphDialogByClickingScrim(cta); TabUiTestHelper.clickScrimToExitDialog(cta);
verifyIphDialogHiding(cta); verifyIphDialogHiding(cta);
// Exiting IPH dialog should not dismiss the IPH. // Exiting IPH dialog should not dismiss the IPH.
...@@ -195,29 +189,6 @@ public class TabGridIphItemTest { ...@@ -195,29 +189,6 @@ public class TabGridIphItemTest {
.perform(click()); .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) { private void enterIphDialog(ChromeTabbedActivity cta) {
assertTrue(cta.getLayoutManager().overviewVisible()); assertTrue(cta.getLayoutManager().overviewVisible());
onView(withId(R.id.show_me_button)).perform(click()); onView(withId(R.id.show_me_button)).perform(click());
......
...@@ -6,10 +6,14 @@ package org.chromium.chrome.browser.tasks.tab_management; ...@@ -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.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click; 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.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withParent; import static android.support.test.espresso.matcher.ViewMatchers.withParent;
import static org.hamcrest.Matchers.allOf; 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.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
...@@ -25,11 +29,15 @@ import android.provider.Settings; ...@@ -25,11 +29,15 @@ import android.provider.Settings;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.test.InstrumentationRegistry; import android.support.test.InstrumentationRegistry;
import android.support.test.espresso.NoMatchingViewException; 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.ViewAssertion;
import android.support.test.espresso.contrib.RecyclerViewActions; 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.Matcher;
import org.chromium.base.ContextUtils; import org.chromium.base.ContextUtils;
import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.ChromeTabbedActivity;
import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
...@@ -37,6 +45,7 @@ import org.chromium.chrome.browser.tab.Tab; ...@@ -37,6 +45,7 @@ import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.tabmodel.TabModel;
import org.chromium.chrome.browser.tabmodel.TabSelectionType; import org.chromium.chrome.browser.tabmodel.TabSelectionType;
import org.chromium.chrome.browser.tasks.tab_groups.TabGroupModelFilter; 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.tab_ui.R;
import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
import org.chromium.chrome.test.util.ChromeTabUtils; import org.chromium.chrome.test.util.ChromeTabUtils;
...@@ -324,6 +333,33 @@ public class TabUiTestHelper { ...@@ -324,6 +333,33 @@ public class TabUiTestHelper {
DEFAULT_MAX_TIME_TO_POLL * 10, DEFAULT_POLLING_INTERVAL); 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 * Implementation of {@link ViewAssertion} to verify the {@link RecyclerView} has correct number
* of children, and children are showing correctly. * 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