Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2834)

Unified Diff: chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java

Issue 1836453003: Use a scrollable tab strip on tablets at small widths (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Tiny bit of clean up Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java
index 3d060ec9ed3758f5c5f5e927c8153151314dbfa2..eb60b9bba08d397d5845471df871d3c9c2d1803b 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/overlays/strip/TabStripTest.java
@@ -22,6 +22,7 @@ import org.chromium.chrome.test.util.ChromeRestriction;
import org.chromium.chrome.test.util.ChromeTabUtils;
import org.chromium.chrome.test.util.TabStripUtils;
import org.chromium.content.browser.test.util.CallbackHelper;
+import org.chromium.ui.base.LocalizationUtils;
import java.util.concurrent.TimeoutException;
@@ -466,6 +467,224 @@ public class TabStripTest extends ChromeTabbedActivityTestBase {
}
/**
+ * Compares tab strips with models after switching between the ScrollingStripStacker and
+ * CascadingStripStacker when an incognito tab is present. Also tests tapping the incognito
+ * button while the strip is using the ScrollingStripStacker (other tests cover tapping
+ * the button while using the CascadingStripStacker).
+ */
+ @LargeTest
+ @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET)
+ @Feature({"TabStrip"})
+ public void testSwitchStripStackersWithIncognito() throws InterruptedException {
+ // Open an incognito tab.
+ newIncognitoTabFromMenu();
+
+ // Switch to the ScrollingStripStacker.
+ setShouldCascadeTabsAndCheckTabStrips(false);
+
+ // Switch tab models.
+ clickIncognitoToggleButton();
+
+ // Switch to the CascadingStripStacker.
+ setShouldCascadeTabsAndCheckTabStrips(true);
+ }
+
+ /**
+ * Compares tab strip with model after switching between the ScrollingStripStacker and
+ * CascadingStripStacker when the last tab is selected. This also verifies that the strip
+ * scrolls correctly and the correct index is selected after switching.
+ */
+ @LargeTest
+ @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET)
+ @Feature({"TabStrip"})
+ public void testSwitchStripStackersWithLastTabSelected() throws InterruptedException {
+ // Open enough regular tabs to cause the tabs to cascade or the strip to scroll depending
+ // on which stacker is being used.
+ ChromeTabUtils.newTabsFromMenu(getInstrumentation(), getActivity(), 10);
+
+ // Switch to the ScrollingStripStacker.
+ setShouldCascadeTabsAndCheckTabStrips(false);
+
+ // Switch to the CascadingStripStacker.
+ setShouldCascadeTabsAndCheckTabStrips(true);
+ }
+
+ /**
+ * Compares tab strip with model after switching between the ScrollingStripStacker and
+ * CascadingStripStacker when the first tab is selected. This also verifies that the strip
+ * scrolls correctly and the correct index is selected after switching.
+ */
+ @LargeTest
+ @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET)
+ @Feature({"TabStrip"})
+ public void testSwitchStripStackersWithFirstTabSelected() throws InterruptedException {
+ // Open enough regular tabs to cause the tabs to cascade or the strip to scroll depending
+ // on which stacker is being used.
+ ChromeTabUtils.newTabsFromMenu(getInstrumentation(), getActivity(), 10);
+
+ // Select the first tab by setting the index directly. It may not be visible, so don't
+ // try to tap on it.
+ ChromeTabUtils.switchTabInCurrentTabModel(getActivity(), 0);
+
+ // Switch to the ScrollingStripStacker.
+ setShouldCascadeTabsAndCheckTabStrips(false);
+
+ // Scroll so the first tab is off screen to verify that switching to the
+ // CascadingStripStacker makes it visible again. The selected tab should always be visible
+ // when using the CascadingStripStacker but may not be visible when using the
+ // ScrollingStripStacker.
+ assertSetTabStripScrollOffset((int) TabStripUtils.getActiveStripLayoutHelper(
+ getActivity()).getMinimumScrollOffset());
+ StripLayoutTab selectedLayoutTab = TabStripUtils.findStripLayoutTab(
+ getActivity(), false, getActivity().getCurrentTabModel().getTabAt(0).getId());
+ assertTabVisibility(false, selectedLayoutTab);
+
+ // Switch to the CascadingStripStacker.
+ setShouldCascadeTabsAndCheckTabStrips(true);
+ }
+
+ /**
+ * Compares tab strip with model after switching between the ScrollingStripStacker and
+ * CascadingStripStacker when a middle tab is selected. This also verifies that the strip
+ * scrolls correctly and the correct index is selected after switching.
+ */
+ @LargeTest
+ @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET)
+ @Feature({"TabStrip"})
+ public void testSwitchStripStackersWithMiddleTabSelected() throws InterruptedException {
+ // Open enough regular tabs to cause the tabs to cascade or the strip to scroll depending
+ // on which stacker is being used.
+ ChromeTabUtils.newTabsFromMenu(getInstrumentation(), getActivity(), 10);
+
+ // Select the sixth tab by setting the index directly. It may not be visible, so don't
+ // try to tap on it.
+ ChromeTabUtils.switchTabInCurrentTabModel(getActivity(), 5);
+
+ // Switch to the ScrollingStripStacker.
+ setShouldCascadeTabsAndCheckTabStrips(false);
+
+ // Switch to the CascadingStripStacker.
+ setShouldCascadeTabsAndCheckTabStrips(true);
+ }
+
+ /**
+ * Test that the right and left tab strip fades are fully visible, partially visible or
+ * hidden at various scroll positions.
+ * TODO(twellington): Also test these expectations in RTL.
+ */
+ @LargeTest
+ @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET)
+ @Feature({"TabStrip"})
+ public void testScrollingStripStackerFadeOpacity() throws InterruptedException {
+ // Switch to the ScrollingStripStacker.
+ setShouldCascadeTabsAndCheckTabStrips(false);
+
+ // Open enough regular tabs to cause the strip to scroll.
+ ChromeTabUtils.newTabsFromMenu(getInstrumentation(), getActivity(), 10);
+
+ // In RTL the expectation for left/right fade opacities is swapped.
+ boolean isLeft = !LocalizationUtils.isLayoutRtl();
+
+ // Initially the right fade (in LTR) should be hidden and the left fade should be visible.
+ assertTabStripFadeFullyHidden(!isLeft);
+ assertTabStripFadeFullyVisible(isLeft);
+
+ // Scroll a little below the minimum scroll offset causing the right fade (in LTR) to be
+ // at partial opacity.
+ assertSetTabStripScrollOffset((int) (TabStripUtils.getActiveStripLayoutHelper(
+ getActivity()).getMinimumScrollOffset()
+ + StripLayoutHelper.FADE_FULL_OPACITY_THRESHOLD_DP / 2));
+ assertTabStripFadePartiallyVisible(!isLeft);
+ assertTabStripFadeFullyVisible(isLeft);
+
+ // Scroll a little above 0 causing the left fade (in LTR) to be at partial opacity.
+ assertSetTabStripScrollOffset(
+ (int) (0 - StripLayoutHelper.FADE_FULL_OPACITY_THRESHOLD_DP / 2));
+ assertTabStripFadeFullyVisible(!isLeft);
+ assertTabStripFadePartiallyVisible(isLeft);
+
+ // Scroll to 0 causing the left fade (in LTR) to be hidden.
+ assertSetTabStripScrollOffset(0);
+ assertTabStripFadeFullyHidden(isLeft);
+ assertTabStripFadeFullyVisible(!isLeft);
+ }
+
+ /**
+ * Test that selecting a tab that isn't currently visible causes the ScrollingStripStacker
+ * to scroll to make it visible.
+ */
+ @LargeTest
+ @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET)
+ @Feature({"TabStrip"})
+ public void testScrollingStripStackerScrollsToSelectedTab() throws InterruptedException {
+ // Switch to the ScrollingStripStacker.
+ setShouldCascadeTabsAndCheckTabStrips(false);
+
+ // Open enough regular tabs to cause the strip to scroll.
+ ChromeTabUtils.newTabsFromMenu(getInstrumentation(), getActivity(), 10);
+
+ // Get tab at index 0 and assert it is not visible.
+ TabModel model = getActivity().getTabModelSelector().getModel(false);
+ StripLayoutTab tab = TabStripUtils.findStripLayoutTab(getActivity(), false,
+ model.getTabAt(0).getId());
+ assertTabVisibility(false, tab);
+
+ // Select tab 0.
+ ChromeTabUtils.switchTabInCurrentTabModel(getActivity(), 0);
+ getInstrumentation().waitForIdleSync();
+
+ // Tab should now be visible.
+ assertTabVisibility(true, tab);
+ }
+
+ /**
+ * Test that the draw positions for tabs match expectations at various scroll positions
+ * when using the ScrollingStripStacker.
+ */
+ @LargeTest
+ @Restriction(ChromeRestriction.RESTRICTION_TYPE_TABLET)
+ @Feature({"TabStrip"})
+ public void testScrollingStripStackerTabOffsets() throws InterruptedException {
+ // Switch to the ScrollingStripStacker.
+ setShouldCascadeTabsAndCheckTabStrips(false);
+
+ // Open enough regular tabs to cause the strip to scroll and select the first tab.
+ ChromeTabUtils.newTabsFromMenu(getInstrumentation(), getActivity(), 10);
+ ChromeTabUtils.switchTabInCurrentTabModel(getActivity(), 0);
+ getInstrumentation().waitForIdleSync();
+
+ // Check initial model validity.
+ compareAllTabStripsWithModel();
+
+ // Set up some variables.
+ StripLayoutHelper strip = TabStripUtils.getActiveStripLayoutHelper(getActivity());
+ StripLayoutTab[] tabs = strip.getStripLayoutTabs();
+ float tabDrawWidth = tabs[0].getWidth() - strip.getTabOverlapWidth();
+
+ // Assert getStripLayoutTabs() returns the expected number of tabs.
+ assertEquals("Unexpected number of StripLayoutTabs.", 11, tabs.length);
+
+ // Scroll tab strip to 0 and check tab positions.
+ assertSetTabStripScrollOffset(0);
+ for (int i = 0; i < tabs.length; i++) {
+ assertTabDrawX(i * tabDrawWidth, tabs[i]);
+ }
+
+ // Scroll tab strip a little and check tab draw positions.
+ assertSetTabStripScrollOffset(-25);
+ for (int i = 0; i < tabs.length; i++) {
+ assertTabDrawX(i * tabDrawWidth - 25.f, tabs[i]);
+ }
+
+ // Scroll tab strip a lot and check tab draw positions.
+ assertSetTabStripScrollOffset(-500);
+ for (int i = 0; i < tabs.length; i++) {
+ assertTabDrawX(i * tabDrawWidth - 500.f, tabs[i]);
+ }
+ assertTabVisibility(false, tabs[0]);
+ }
+
+ /**
* Take a model index and figure out which index it will be in the TabStrip's view hierarchy.
* @param tabCount The number of tabs.
* @param selectedIndex The index of the selected tab.
@@ -584,15 +803,22 @@ public class TabStripTest extends ChromeTabbedActivityTestBase {
&& getActivity().getTabModelSelector().isIncognitoSelected() == incognito) {
assertTrue("ChromeTab is not in the proper selection state",
tabStrip.isForegroundTab(tabView));
- assertEquals("ChromeTab is not completely visible, but is selected",
- tabView.getVisiblePercentage(), 1.0f);
+ if (tabStrip.shouldCascadeTabs()) {
+ assertEquals("ChromeTab is not completely visible, but is selected. The selected "
+ + "tab should be visible when the CascadingStripStacker is in use.",
+ tabView.getVisiblePercentage(), 1.0f);
+ }
+ }
+
+ if (!tabStrip.shouldCascadeTabs()) {
+ assertTabVisibilityForScrollingStripStacker(tabStrip, tabView);
}
// TODO(dtrainor): Compare favicon bitmaps? Only compare a few pixels.
}
/**
- * Compares an entire TabStrip with the corresponding TabModel. This tries to compare
+ * Compares an entire TabStrip with the corresponding TabModel. This tries to compare
* as many features as possible, including checking all of the tabs through
* compareTabViewWithModel. It also checks that the incognito indicator is visible if the
* incognito tab is showing.
@@ -636,4 +862,150 @@ public class TabStripTest extends ChromeTabbedActivityTestBase {
compareTabStripWithModel(true);
compareTabStripWithModel(false);
}
+
+ /**
+ * Sets whether the strip should cascade tabs and checks for validity.
+ *
+ * @param shouldCascadeTabs Whether the {@link CascadingStripStacker} should be used. If false,
+ * the {@link ScrollingStripStacker} will be used instead.
+ */
+ private void setShouldCascadeTabsAndCheckTabStrips(final boolean shouldCascadeTabs) {
+ TabModel model = getActivity().getCurrentTabModel();
+ int selectedTabIndex = model.index();
+
+ ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+ @Override
+ public void run() {
+ TabStripUtils.getStripLayoutHelper(getActivity(), true).setShouldCascadeTabs(
+ shouldCascadeTabs);
+ TabStripUtils.getStripLayoutHelper(getActivity(), false).setShouldCascadeTabs(
+ shouldCascadeTabs);
+ }
+ });
+
+ // Assert that the correct StripStacker is being used.
+ assertEquals(shouldCascadeTabs
+ ? "Expected CascadingStripStacker but was ScrollingStripStacker."
+ : "Expected ScrollingStripStacker but was CascadingStripStacker.",
+ shouldCascadeTabs,
+ TabStripUtils.getActiveStripLayoutHelper(getActivity()).shouldCascadeTabs());
+
+ // Assert that the same tab is still selected.
+ assertEquals("The correct tab is not selected.", selectedTabIndex, model.index());
+
+ // Compare all TabStrips with corresponding TabModels.
+ compareAllTabStripsWithModel();
+
+ // The selected tab should always be visible in the CascadingStripStacker and switching to
+ // the ScrollingStripStacker should auto-scroll to make the selected tab visible.
+ StripLayoutTab selectedLayoutTab = TabStripUtils.findStripLayoutTab(
+ getActivity(), model.isIncognito(), model.getTabAt(selectedTabIndex).getId());
+ assertTabVisibility(true, selectedLayoutTab);
+ }
+
+ /**
+ * Scrolls the tab strip to the desired position and checks for validity.
+ *
+ * @param scrollOffset The end scroll position for the tab strip.
+ */
+ private void assertSetTabStripScrollOffset(final int scrollOffset) {
+ final StripLayoutHelper strip = TabStripUtils.getActiveStripLayoutHelper(getActivity());
+ ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+ @Override
+ public void run() {
+ strip.setScrollOffsetForTesting(scrollOffset);
+ }
+ });
+
+ assertEquals("Tab strip scroll incorrect.", scrollOffset, strip.getScrollOffset());
+ compareAllTabStripsWithModel();
+ }
+
+ /**
+ * Asserts that the left or right fade is fully hidden.
+ * @param isLeft Whether the left fade should be checked.
+ */
+ private void assertTabStripFadeFullyHidden(boolean isLeft) {
+ StripLayoutHelper strip = TabStripUtils.getActiveStripLayoutHelper(getActivity());
+ if (isLeft) {
+ assertEquals("Left tab strip fade visibility is incorrect.", 0.f,
+ strip.getLeftFadeOpacity());
+ } else {
+ assertEquals("Right tab strip fade visibility is incorrect.", 0.f,
+ strip.getRightFadeOpacity());
+ }
+ }
+
+ /**
+ * Asserts that the left or right fade is fully visible.
+ * @param isLeft Whether the left fade should be checked.
+ */
+ private void assertTabStripFadeFullyVisible(boolean isLeft) {
+ StripLayoutHelper strip = TabStripUtils.getActiveStripLayoutHelper(getActivity());
+ if (isLeft) {
+ assertEquals("Left tab strip fade visibility is incorrect.", 1.f,
+ strip.getLeftFadeOpacity());
+ } else {
+ assertEquals("Right tab strip fade visibility is incorrect.", 1.f,
+ strip.getRightFadeOpacity());
+ }
+ }
+
+ /**
+ * Asserts that the left or right fade is partially visible.
+ * @param isLeft Whether the left fade should be checked.
+ */
+ private void assertTabStripFadePartiallyVisible(boolean isLeft) {
+ StripLayoutHelper strip = TabStripUtils.getActiveStripLayoutHelper(getActivity());
+ if (isLeft) {
+ boolean isPartiallyVisible = strip.getLeftFadeOpacity() > 0.f
+ && strip.getLeftFadeOpacity() < 1.f;
+ assertEquals("Left tab strip fade expected to be partially visible.", true,
+ isPartiallyVisible);
+ } else {
+ boolean isPartiallyVisible = strip.getRightFadeOpacity() > 0.f
+ && strip.getRightFadeOpacity() < 1.f;
+ assertEquals("Right tab strip fade expected to be partially visible.", true,
+ isPartiallyVisible);
+ }
+ }
+
+ /**
+ * Checks visible percentage and visibility for the given tab. Should only be called when the
+ * ScrollingStripStacker is in use.
+ *
+ * @param tabStrip The StripLayoutHelper that owns the tab.
+ * @param tabView The StripLayoutTab associated with the tab to check.
+ */
+ private void assertTabVisibilityForScrollingStripStacker(StripLayoutHelper tabStrip,
+ StripLayoutTab tabView) {
+ // The visible percent for all tabs is 1.0 in the ScrollingStripStacker.
+ assertEquals("ChromeTab is not completely visible. All tabs should be visible when "
+ + "the ScrollingStripStacker is in use.",
+ tabView.getVisiblePercentage(), 1.0f);
+
+ // Only tabs that can currently be seen on the screen should be visible.
+ boolean shouldBeVisible = (tabView.getDrawX() + tabView.getWidth()) >= 0
+ && tabView.getDrawX() <= tabStrip.getWidth();
+ assertTabVisibility(shouldBeVisible, tabView);
+ }
+
+ /**
+ * Asserts whether a tab should be visible.
+ * @param shouldBeVisible Whether the tab should be visible.
+ * @param tabView The StripLayoutTab associated with the tab to check.
+ */
+ private void assertTabVisibility(boolean shouldBeVisible, StripLayoutTab tabView) {
+ assertEquals("ChromeTab " + (shouldBeVisible ? "should" : "should not") + " be visible.",
+ shouldBeVisible, tabView.isVisible());
+ }
+
+ /**
+ * Asserts that the tab has the expected draw X position.
+ * @param expectedDrawX The expected draw X position.
+ * @param tabView The StripLayoutTab associated with the tab to check.
+ */
+ private void assertTabDrawX(float expectedDrawX, StripLayoutTab tabView) {
+ assertEquals("Incorrect draw position for tab.", expectedDrawX, tabView.getDrawX());
+ }
}
« no previous file with comments | « chrome/android/java_sources.gni ('k') | chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698