Commit 7767aa96 authored by Yue Zhang's avatar Yue Zhang Committed by Commit Bot

Make tab strip auto scroll to position of the selected tab

Currently, when a tab in group is selected or a new tab is created
within group, the tab strip doesn't scroll to the position of the
currently selected tab. This could lead to a state where user needs to
scroll by themselves to find their selected tab in strip. This CL fixes
this issue by making following changes:
  * Always scroll the strip to the last position when new tab is added
    in group.
  * When selected a tab in group (through tab grid dialog etc), try to
    scroll to a state where the selected tab is in the middle of the
    strip, if possible,

Bug: 1054079
Change-Id: Ic6921225d744a7b5df1853aa78e14a8f9249f2c8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2068888
Commit-Queue: Yue Zhang <yuezhanggg@chromium.org>
Reviewed-by: default avatarWei-Yin Chen (陳威尹) <wychen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#744892}
parent 2e03b4cf
...@@ -44,8 +44,9 @@ public class TabGroupUiCoordinator implements TabGroupUiMediator.ResetHandler, T ...@@ -44,8 +44,9 @@ public class TabGroupUiCoordinator implements TabGroupUiMediator.ResetHandler, T
private final Context mContext; private final Context mContext;
private final PropertyModel mModel; private final PropertyModel mModel;
private final ThemeColorProvider mThemeColorProvider; private final ThemeColorProvider mThemeColorProvider;
private final PropertyModelChangeProcessor mModelChangeProcessor; private final TabGroupUiToolbarView mToolbarView;
private final ViewGroup mTabListContainerView; private final ViewGroup mTabListContainerView;
private PropertyModelChangeProcessor mModelChangeProcessor;
private TabGridDialogCoordinator mTabGridDialogCoordinator; private TabGridDialogCoordinator mTabGridDialogCoordinator;
private TabListCoordinator mTabStripCoordinator; private TabListCoordinator mTabStripCoordinator;
private TabGroupUiMediator mMediator; private TabGroupUiMediator mMediator;
...@@ -59,13 +60,10 @@ public class TabGroupUiCoordinator implements TabGroupUiMediator.ResetHandler, T ...@@ -59,13 +60,10 @@ public class TabGroupUiCoordinator implements TabGroupUiMediator.ResetHandler, T
mContext = parentView.getContext(); mContext = parentView.getContext();
mThemeColorProvider = themeColorProvider; mThemeColorProvider = themeColorProvider;
mModel = new PropertyModel(TabGroupUiProperties.ALL_KEYS); mModel = new PropertyModel(TabGroupUiProperties.ALL_KEYS);
TabGroupUiToolbarView toolbarView = mToolbarView = (TabGroupUiToolbarView) LayoutInflater.from(mContext).inflate(
(TabGroupUiToolbarView) LayoutInflater.from(mContext).inflate( R.layout.bottom_tab_strip_toolbar, parentView, false);
R.layout.bottom_tab_strip_toolbar, parentView, false); mTabListContainerView = mToolbarView.getViewContainer();
mTabListContainerView = toolbarView.getViewContainer(); parentView.addView(mToolbarView);
parentView.addView(toolbarView);
mModelChangeProcessor = PropertyModelChangeProcessor.create(
mModel, toolbarView, TabGroupUiViewBinder::bind);
} }
/** /**
...@@ -89,6 +87,11 @@ public class TabGroupUiCoordinator implements TabGroupUiMediator.ResetHandler, T ...@@ -89,6 +87,11 @@ public class TabGroupUiCoordinator implements TabGroupUiMediator.ResetHandler, T
TabProperties.UiType.STRIP, null, mTabListContainerView, null, true, TabProperties.UiType.STRIP, null, mTabListContainerView, null, true,
COMPONENT_NAME); COMPONENT_NAME);
mModelChangeProcessor = PropertyModelChangeProcessor.create(mModel,
new TabGroupUiViewBinder.ViewHolder(
mToolbarView, mTabStripCoordinator.getContainerView()),
TabGroupUiViewBinder::bind);
boolean isTabGroupsUiImprovementsEnabled = boolean isTabGroupsUiImprovementsEnabled =
TabUiFeatureUtilities.isTabGroupsAndroidUiImprovementsEnabled(); TabUiFeatureUtilities.isTabGroupsAndroidUiImprovementsEnabled();
// TODO(yuezhanggg): TabGridDialog should be the default mode. // TODO(yuezhanggg): TabGridDialog should be the default mode.
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
package org.chromium.chrome.browser.tasks.tab_management; package org.chromium.chrome.browser.tasks.tab_management;
import android.os.Handler;
import android.view.View; import android.view.View;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
...@@ -136,6 +137,10 @@ public class TabGroupUiMediator { ...@@ -136,6 +137,10 @@ public class TabGroupUiMediator {
@Override @Override
public void didAddTab(Tab tab, int type) { public void didAddTab(Tab tab, int type) {
if (type == TabLaunchType.FROM_CHROME_UI && mIsTabGroupUiVisible) {
mModel.set(TabGroupUiProperties.INITIAL_SCROLL_INDEX,
getRelatedTabsForId(tab.getId()).size() - 1);
}
if (type == TabLaunchType.FROM_CHROME_UI || type == TabLaunchType.FROM_RESTORE if (type == TabLaunchType.FROM_CHROME_UI || type == TabLaunchType.FROM_RESTORE
|| type == TabLaunchType.FROM_STARTUP) { || type == TabLaunchType.FROM_STARTUP) {
return; return;
...@@ -284,6 +289,15 @@ public class TabGroupUiMediator { ...@@ -284,6 +289,15 @@ public class TabGroupUiMediator {
&& BottomToolbarConfiguration.isBottomToolbarEnabled(); && BottomToolbarConfiguration.isBottomToolbarEnabled();
assert (mVisibilityController == null) == isDuetTabStripIntegrationEnabled; assert (mVisibilityController == null) == isDuetTabStripIntegrationEnabled;
if (isDuetTabStripIntegrationEnabled) return; if (isDuetTabStripIntegrationEnabled) return;
if (mIsTabGroupUiVisible) {
// Post to make sure that the recyclerView already knows how many visible items it has.
// This is to make sure that we can scroll to a state where the selected tab is in the
// middle of the strip.
Handler handler = new Handler();
handler.post(()
-> mModel.set(TabGroupUiProperties.INITIAL_SCROLL_INDEX,
listOfTabs.indexOf(mTabModelSelector.getCurrentTab())));
}
mVisibilityController.setBottomControlsVisible(mIsTabGroupUiVisible); mVisibilityController.setBottomControlsVisible(mIsTabGroupUiVisible);
} }
......
...@@ -28,8 +28,14 @@ class TabGroupUiProperties { ...@@ -28,8 +28,14 @@ class TabGroupUiProperties {
new PropertyModel.WritableObjectPropertyKey<>(); new PropertyModel.WritableObjectPropertyKey<>();
public static final PropertyModel.WritableIntPropertyKey LEFT_BUTTON_DRAWABLE_ID = public static final PropertyModel.WritableIntPropertyKey LEFT_BUTTON_DRAWABLE_ID =
new PropertyModel.WritableIntPropertyKey(); new PropertyModel.WritableIntPropertyKey();
/**
* Integer, but not {@link PropertyModel.WritableIntPropertyKey} so that we can force update on
* the same value.
*/
public static final PropertyModel.WritableObjectPropertyKey INITIAL_SCROLL_INDEX =
new PropertyModel.WritableObjectPropertyKey(true);
public static final PropertyKey[] ALL_KEYS = public static final PropertyKey[] ALL_KEYS = new PropertyKey[] {LEFT_BUTTON_ON_CLICK_LISTENER,
new PropertyKey[] {LEFT_BUTTON_ON_CLICK_LISTENER, RIGHT_BUTTON_ON_CLICK_LISTENER, RIGHT_BUTTON_ON_CLICK_LISTENER, IS_MAIN_CONTENT_VISIBLE, PRIMARY_COLOR, TINT,
IS_MAIN_CONTENT_VISIBLE, PRIMARY_COLOR, TINT, LEFT_BUTTON_DRAWABLE_ID}; LEFT_BUTTON_DRAWABLE_ID, INITIAL_SCROLL_INDEX};
} }
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
package org.chromium.chrome.browser.tasks.tab_management; package org.chromium.chrome.browser.tasks.tab_management;
import static org.chromium.chrome.browser.tasks.tab_management.TabGroupUiProperties.INITIAL_SCROLL_INDEX;
import static org.chromium.chrome.browser.tasks.tab_management.TabGroupUiProperties.IS_MAIN_CONTENT_VISIBLE; import static org.chromium.chrome.browser.tasks.tab_management.TabGroupUiProperties.IS_MAIN_CONTENT_VISIBLE;
import static org.chromium.chrome.browser.tasks.tab_management.TabGroupUiProperties.LEFT_BUTTON_DRAWABLE_ID; import static org.chromium.chrome.browser.tasks.tab_management.TabGroupUiProperties.LEFT_BUTTON_DRAWABLE_ID;
import static org.chromium.chrome.browser.tasks.tab_management.TabGroupUiProperties.LEFT_BUTTON_ON_CLICK_LISTENER; import static org.chromium.chrome.browser.tasks.tab_management.TabGroupUiProperties.LEFT_BUTTON_ON_CLICK_LISTENER;
...@@ -11,6 +12,10 @@ import static org.chromium.chrome.browser.tasks.tab_management.TabGroupUiPropert ...@@ -11,6 +12,10 @@ import static org.chromium.chrome.browser.tasks.tab_management.TabGroupUiPropert
import static org.chromium.chrome.browser.tasks.tab_management.TabGroupUiProperties.RIGHT_BUTTON_ON_CLICK_LISTENER; import static org.chromium.chrome.browser.tasks.tab_management.TabGroupUiProperties.RIGHT_BUTTON_ON_CLICK_LISTENER;
import static org.chromium.chrome.browser.tasks.tab_management.TabGroupUiProperties.TINT; import static org.chromium.chrome.browser.tasks.tab_management.TabGroupUiProperties.TINT;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModel;
...@@ -18,27 +23,48 @@ import org.chromium.ui.modelutil.PropertyModel; ...@@ -18,27 +23,48 @@ import org.chromium.ui.modelutil.PropertyModel;
* ViewBinder for TabGroupUi component. * ViewBinder for TabGroupUi component.
*/ */
class TabGroupUiViewBinder { class TabGroupUiViewBinder {
/**
* ViewHolder class to get access to all {@link View}s inside the TabGroupUi.
*/
public static class ViewHolder {
public final TabGroupUiToolbarView toolbarView;
public final RecyclerView contentView;
ViewHolder(TabGroupUiToolbarView toolbarView, RecyclerView contentView) {
this.toolbarView = toolbarView;
this.contentView = contentView;
}
}
/** /**
* Binds the given model to the given view, updating the payload in propertyKey. * Binds the given model to the given view, updating the payload in propertyKey.
* *
* @param model The model to use. * @param model The model to use.
* @param view The view to use. * @param viewHolder The {@link ViewHolder} to use.
* @param propertyKey The key for the property to update for. * @param propertyKey The key for the property to update for.
*/ */
public static void bind( public static void bind(PropertyModel model, ViewHolder viewHolder, PropertyKey propertyKey) {
PropertyModel model, TabGroupUiToolbarView view, PropertyKey propertyKey) {
if (LEFT_BUTTON_ON_CLICK_LISTENER == propertyKey) { if (LEFT_BUTTON_ON_CLICK_LISTENER == propertyKey) {
view.setLeftButtonOnClickListener(model.get(LEFT_BUTTON_ON_CLICK_LISTENER)); viewHolder.toolbarView.setLeftButtonOnClickListener(
model.get(LEFT_BUTTON_ON_CLICK_LISTENER));
} else if (RIGHT_BUTTON_ON_CLICK_LISTENER == propertyKey) { } else if (RIGHT_BUTTON_ON_CLICK_LISTENER == propertyKey) {
view.setRightButtonOnClickListener(model.get(RIGHT_BUTTON_ON_CLICK_LISTENER)); viewHolder.toolbarView.setRightButtonOnClickListener(
model.get(RIGHT_BUTTON_ON_CLICK_LISTENER));
} else if (IS_MAIN_CONTENT_VISIBLE == propertyKey) { } else if (IS_MAIN_CONTENT_VISIBLE == propertyKey) {
view.setMainContentVisibility(model.get(IS_MAIN_CONTENT_VISIBLE)); viewHolder.toolbarView.setMainContentVisibility(model.get(IS_MAIN_CONTENT_VISIBLE));
} else if (PRIMARY_COLOR == propertyKey) { } else if (PRIMARY_COLOR == propertyKey) {
view.setPrimaryColor(model.get(PRIMARY_COLOR)); viewHolder.toolbarView.setPrimaryColor(model.get(PRIMARY_COLOR));
} else if (TINT == propertyKey) { } else if (TINT == propertyKey) {
view.setTint(model.get(TINT)); viewHolder.toolbarView.setTint(model.get(TINT));
} else if (LEFT_BUTTON_DRAWABLE_ID == propertyKey) { } else if (LEFT_BUTTON_DRAWABLE_ID == propertyKey) {
view.setLeftButtonDrawableId(model.get(LEFT_BUTTON_DRAWABLE_ID)); viewHolder.toolbarView.setLeftButtonDrawableId(model.get(LEFT_BUTTON_DRAWABLE_ID));
} else if (INITIAL_SCROLL_INDEX == propertyKey) {
int index = (Integer) model.get(INITIAL_SCROLL_INDEX);
LinearLayoutManager manager =
(LinearLayoutManager) viewHolder.contentView.getLayoutManager();
int showingItemsCount =
manager.findLastVisibleItemPosition() - manager.findFirstVisibleItemPosition();
// Try to scroll to a state where the selected tab is in the middle of the strip.
manager.scrollToPositionWithOffset(index - showingItemsCount / 2, 0);
} }
} }
} }
// Copyright 2020 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 static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
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.junit.Assert.assertTrue;
import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.clickFirstCardFromTabSwitcher;
import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.clickNthTabInDialog;
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.mergeAllNormalTabsToAGroup;
import static org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper.verifyTabSwitcherCardCount;
import android.support.test.filters.MediumTest;
import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup;
import org.junit.After;
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.base.test.util.Feature;
import org.chromium.base.test.util.Restriction;
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.CachedFeatureFlags;
import org.chromium.chrome.features.start_surface.StartSurfaceLayout;
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.ChromeRenderTestRule;
import org.chromium.chrome.test.util.browser.Features;
import org.chromium.content_public.browser.test.util.CriteriaHelper;
import org.chromium.ui.test.util.UiRestriction;
import java.io.IOException;
/** End-to-end tests for TabGroupUi component. */
@RunWith(ChromeJUnit4ClassRunner.class)
// clang-format off
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
@Restriction(UiRestriction.RESTRICTION_TYPE_PHONE)
public class TabGroupUiTest {
// clang-format on
@Rule
public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
@Rule
public TestRule mProcessor = new Features.InstrumentationProcessor();
@Rule
public ChromeRenderTestRule mRenderTestRule = new ChromeRenderTestRule();
@Before
public void setUp() {
CachedFeatureFlags.setGridTabSwitcherEnabledForTesting(true);
CachedFeatureFlags.setTabGroupsAndroidEnabledForTesting(true);
mActivityTestRule.startMainActivityFromLauncher();
Layout layout = mActivityTestRule.getActivity().getLayoutManager().getOverviewLayout();
assertTrue(layout instanceof StartSurfaceLayout);
CriteriaHelper.pollUiThread(mActivityTestRule.getActivity()
.getTabModelSelector()
.getTabModelFilterProvider()
.getCurrentTabModelFilter()::isTabModelRestored);
}
@After
public void tearDown() {
CachedFeatureFlags.setGridTabSwitcherEnabledForTesting(null);
CachedFeatureFlags.setTabGroupsAndroidEnabledForTesting(null);
}
@Test
@MediumTest
@Feature({"RenderTest"})
public void testRenderStrip_Select5thTabIn10Tabs() throws InterruptedException, IOException {
final ChromeTabbedActivity cta = mActivityTestRule.getActivity();
createTabs(cta, false, 10);
enterTabSwitcher(cta);
verifyTabSwitcherCardCount(cta, 10);
mergeAllNormalTabsToAGroup(cta);
verifyTabSwitcherCardCount(cta, 1);
// Select the 5th tab in group.
clickFirstCardFromTabSwitcher(cta);
clickNthTabInDialog(cta, 4);
ViewGroup bottomToolbar = cta.findViewById(R.id.bottom_controls);
RecyclerView stripRecyclerView =
(RecyclerView) bottomToolbar.findViewById(R.id.tab_list_view);
mRenderTestRule.render(stripRecyclerView, "5th_tab_selected");
}
@Test
@MediumTest
@Feature({"RenderTest"})
public void testRenderStrip_Select10thTabIn10Tabs() throws InterruptedException, IOException {
final ChromeTabbedActivity cta = mActivityTestRule.getActivity();
createTabs(cta, false, 10);
enterTabSwitcher(cta);
verifyTabSwitcherCardCount(cta, 10);
mergeAllNormalTabsToAGroup(cta);
verifyTabSwitcherCardCount(cta, 1);
// Select the 10th tab in group.
clickFirstCardFromTabSwitcher(cta);
clickNthTabInDialog(cta, 9);
ViewGroup bottomToolbar = cta.findViewById(R.id.bottom_controls);
RecyclerView stripRecyclerView =
(RecyclerView) bottomToolbar.findViewById(R.id.tab_list_view);
mRenderTestRule.render(stripRecyclerView, "10th_tab_selected");
}
@Test
@MediumTest
@Feature({"RenderTest"})
public void testRenderStrip_AddTab() throws InterruptedException, IOException {
final ChromeTabbedActivity cta = mActivityTestRule.getActivity();
createTabs(cta, false, 10);
enterTabSwitcher(cta);
verifyTabSwitcherCardCount(cta, 10);
mergeAllNormalTabsToAGroup(cta);
verifyTabSwitcherCardCount(cta, 1);
// Select the first tab in group and add one new tab to group.
clickFirstCardFromTabSwitcher(cta);
clickNthTabInDialog(cta, 0);
ViewGroup bottomToolbar = cta.findViewById(R.id.bottom_controls);
RecyclerView stripRecyclerView =
(RecyclerView) bottomToolbar.findViewById(R.id.tab_list_view);
stripRecyclerView.setItemAnimator(null);
onView(allOf(withId(R.id.toolbar_right_button), withParent(withId(R.id.main_content))))
.perform(click());
mRenderTestRule.render(stripRecyclerView, "11th_tab_selected");
}
}
...@@ -16,6 +16,8 @@ import android.graphics.drawable.Drawable; ...@@ -16,6 +16,8 @@ import android.graphics.drawable.Drawable;
import android.os.Build; import android.os.Build;
import android.support.test.annotation.UiThreadTest; import android.support.test.annotation.UiThreadTest;
import android.support.test.filters.SmallTest; import android.support.test.filters.SmallTest;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
...@@ -61,9 +63,16 @@ public class TabGroupUiViewBinderTest extends DummyUiActivityTestCase { ...@@ -61,9 +63,16 @@ public class TabGroupUiViewBinderTest extends DummyUiActivityTestCase {
mRightButton = toolbarView.findViewById(R.id.toolbar_right_button); mRightButton = toolbarView.findViewById(R.id.toolbar_right_button);
mContainerView = toolbarView.findViewById(R.id.toolbar_container_view); mContainerView = toolbarView.findViewById(R.id.toolbar_container_view);
mMainContent = toolbarView.findViewById(R.id.main_content); mMainContent = toolbarView.findViewById(R.id.main_content);
RecyclerView recyclerView =
(TabListRecyclerView) LayoutInflater.from(getActivity())
.inflate(R.layout.tab_list_recycler_view_layout, parentView, false);
recyclerView.setLayoutManager(
new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false));
mModel = new PropertyModel(TabGroupUiProperties.ALL_KEYS); mModel = new PropertyModel(TabGroupUiProperties.ALL_KEYS);
mMCP = PropertyModelChangeProcessor.create(mModel, toolbarView, TabGroupUiViewBinder::bind); mMCP = PropertyModelChangeProcessor.create(mModel,
new TabGroupUiViewBinder.ViewHolder(toolbarView, recyclerView),
TabGroupUiViewBinder::bind);
} }
@Override @Override
......
...@@ -408,6 +408,26 @@ public class TabGroupUiMediatorUnitTest { ...@@ -408,6 +408,26 @@ public class TabGroupUiMediatorUnitTest {
verifyNeverReset(); verifyNeverReset();
} }
@Test
public void tabSelection_ScrollToSelectedIndex() {
initAndAssertProperties(mTab1);
assertThat(mModel.get(TabGroupUiProperties.INITIAL_SCROLL_INDEX), equalTo(null));
// Mock that {tab2, tab3} are in the same tab group.
List<Tab> tabGroup = mTabGroupModelFilter.getRelatedTabList(TAB2_ID);
assertThat(tabGroup.size(), equalTo(2));
// Mock selecting tab 3, and the last selected tab is tab 1 which is a single tab.
doReturn(mTab3).when(mTabModelSelector).getCurrentTab();
mTabModelObserverArgumentCaptor.getValue().didSelectTab(
mTab3, TabSelectionType.FROM_USER, TAB1_ID);
// Strip should be showing since we are selecting a group, and it should scroll to the index
// of currently selected tab.
verifyResetStrip(true, tabGroup);
assertThat(mModel.get(TabGroupUiProperties.INITIAL_SCROLL_INDEX), equalTo(1));
}
@Test @Test
public void tabClosure_NotLastTabInGroup() { public void tabClosure_NotLastTabInGroup() {
initAndAssertProperties(mTab2); initAndAssertProperties(mTab2);
...@@ -500,6 +520,23 @@ public class TabGroupUiMediatorUnitTest { ...@@ -500,6 +520,23 @@ public class TabGroupUiMediatorUnitTest {
verifyResetStrip(true, mTabGroup2); verifyResetStrip(true, mTabGroup2);
} }
@Test
public void tabAddition_TabGroup_ScrollToTheLast() {
initAndAssertProperties(mTab2);
assertThat(mModel.get(TabGroupUiProperties.INITIAL_SCROLL_INDEX), equalTo(0));
TabImpl newTab = prepareTab(TAB4_ID, TAB4_ID);
mTabGroup2.add(newTab);
doReturn(mTabGroup2).when(mTabGroupModelFilter).getRelatedTabList(TAB4_ID);
mTabModelObserverArgumentCaptor.getValue().didAddTab(newTab, TabLaunchType.FROM_CHROME_UI);
// Strip should be not be reset through adding tab from UI.
verifyNeverReset();
assertThat(mTabGroupModelFilter.getRelatedTabList(TAB4_ID).size(), equalTo(3));
assertThat(mModel.get(TabGroupUiProperties.INITIAL_SCROLL_INDEX), equalTo(2));
}
@Test @Test
public void restoreCompleted_TabModelNoTab() { public void restoreCompleted_TabModelNoTab() {
// Simulate no tab in current TabModel. // Simulate no tab in current TabModel.
......
...@@ -40,6 +40,7 @@ tab_management_test_java_sources = [ ...@@ -40,6 +40,7 @@ tab_management_test_java_sources = [
"//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridPanelViewBinderTest.java", "//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridPanelViewBinderTest.java",
"//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiTest.java", "//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiTest.java",
"//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiViewBinderTest.java", "//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupPopupUiViewBinderTest.java",
"//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiTest.java",
"//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiViewBinderTest.java", "//chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiViewBinderTest.java",
"//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/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/TabListViewHolderTest.java",
......
661913928237b92a6e9b775bc6b25e9a9bfd70d8
\ No newline at end of file
df99ffecab9d4e5a9f14aa251a0c4d34d71a8abe
\ No newline at end of file
661913928237b92a6e9b775bc6b25e9a9bfd70d8
\ No newline at end of file
df99ffecab9d4e5a9f14aa251a0c4d34d71a8abe
\ No newline at end of file
edb4497eafe8220b91051e45f71bc8710c0cadcb
\ No newline at end of file
fb7e128ac8cf0a030f4e80fb50cd5500f6cbb3ab
\ No newline at end of file
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