// Copyright 2015 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.compositor.overlays.strip;

import android.content.pm.ActivityInfo;
import android.support.test.InstrumentationRegistry;

import androidx.test.filters.LargeTest;

import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.chromium.base.test.util.CallbackHelper;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.DisabledTest;
import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.Restriction;
import org.chromium.chrome.browser.compositor.layouts.components.CompositorButton;
import org.chromium.chrome.browser.flags.ChromeSwitches;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver;
import org.chromium.chrome.browser.tabmodel.TabModel;
import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver;
import org.chromium.chrome.browser.tabmodel.TabModelUtils;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
import org.chromium.chrome.test.util.ChromeTabUtils;
import org.chromium.chrome.test.util.TabStripUtils;
import org.chromium.content_public.browser.test.util.Criteria;
import org.chromium.content_public.browser.test.util.CriteriaHelper;
import org.chromium.content_public.browser.test.util.DOMUtils;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
import org.chromium.ui.base.LocalizationUtils;
import org.chromium.ui.test.util.UiRestriction;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;

/**
 * Test suite for the TabStrip and making sure it properly represents the TabModel backend.
 */
@RunWith(ChromeJUnit4ClassRunner.class)
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
public class TabStripTest {
    @Rule
    public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();

    @Before
    public void setUp() throws InterruptedException {
        mActivityTestRule.startMainActivityOnBlankPage();
    }

    /**
     * Tests that the initial state of the system is good.  This is so the default TabStrips match
     * the TabModels and we do not have to test this in further tests.
     */
    @Test
    @LargeTest
    @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
    @Feature({"TabStrip"})
    public void testInitialState() throws Exception {
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        compareAllTabStripsWithModel();
    }

    /**
     * Tests that pressing the new tab button creates a new tab, properly updating the selected
     * index.
     */
    @Test
    @LargeTest
    @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
    @Feature({"TabStrip", "Main"})
    public void testNewTabButtonWithOneTab() throws Exception {
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertEquals("Expected original tab to be selected",
                mActivityTestRule.getActivity().getTabModelSelector().getModel(false).index(), 0);

        ChromeTabUtils.clickNewTabButton(
                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());

        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertEquals("Expected two tabs to exist",
                mActivityTestRule.getActivity().getTabModelSelector().getModel(false).getCount(),
                2);
        compareAllTabStripsWithModel();
        Assert.assertEquals("Expected second tab to be selected",
                mActivityTestRule.getActivity().getTabModelSelector().getModel(false).index(), 1);
    }

    /**
     * Tests that pressing the new tab button creates a new tab when many exist, properly updating
     * the selected index.
     */
    @Test
    @LargeTest
    @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
    @Feature({"TabStrip"})
    public void testNewTabButtonWithManyTabs() throws Exception {
        ChromeTabUtils.newTabsFromMenu(
                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity(), 3);
        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
            @Override
            public void run() {
                TabModelUtils.setIndex(
                        mActivityTestRule.getActivity().getTabModelSelector().getModel(false), 0);
            }
        });
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertEquals("Expected original tab to be selected",
                mActivityTestRule.getActivity().getTabModelSelector().getModel(false).index(), 0);
        compareAllTabStripsWithModel();

        ChromeTabUtils.clickNewTabButton(
                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());

        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertEquals("Expected five tabs to exist",
                mActivityTestRule.getActivity().getTabModelSelector().getModel(false).getCount(),
                5);
        Assert.assertEquals("Expected last tab to be selected",
                mActivityTestRule.getActivity().getTabModelSelector().getModel(false).index(), 4);
        compareAllTabStripsWithModel();
    }

    /**
     * Tests that creating a new tab from the menu properly updates the TabStrip.
     */
    @Test
    @LargeTest
    @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
    @Feature({"TabStrip"})
    public void testNewTabFromMenu() throws Exception {
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        compareAllTabStripsWithModel();
        ChromeTabUtils.newTabFromMenu(
                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertEquals("Expected two tabs to exist",
                mActivityTestRule.getActivity().getTabModelSelector().getModel(false).getCount(),
                2);
        compareAllTabStripsWithModel();
    }

    /**
     * Tests that creating a new incognito from the menu properly updates the TabStrips and
     * activates the incognito TabStrip.
     */
    @Test
    @LargeTest
    @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
    @Feature({"TabStrip"})
    public void testNewIncognitoTabFromMenuAtNormalStrip() throws Exception {
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertFalse("Expected normal strip to be selected",
                mActivityTestRule.getActivity().getTabModelSelector().isIncognitoSelected());
        mActivityTestRule.newIncognitoTabFromMenu();
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        compareAllTabStripsWithModel();
        Assert.assertTrue("Expected incognito strip to be selected",
                mActivityTestRule.getActivity().getTabModelSelector().isIncognitoSelected());
        Assert.assertEquals("Expected normal model to have one tab",
                mActivityTestRule.getActivity().getTabModelSelector().getModel(false).getCount(),
                1);
        Assert.assertEquals("Expected incognito model to have one tab",
                mActivityTestRule.getActivity().getTabModelSelector().getModel(false).getCount(),
                1);
    }

    /**
     * Tests that selecting a tab properly selects the new tab.
     */
    @Test
    @LargeTest
    @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
    @Feature({"TabStrip"})
    public void testSelectWithTwoTabs() throws Exception {
        ChromeTabUtils.newTabFromMenu(
                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertEquals("The second tab is not selected",
                mActivityTestRule.getActivity().getCurrentTabModel().index(), 1);
        selectTab(false, mActivityTestRule.getActivity().getCurrentTabModel().getTabAt(0).getId());
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertEquals("The first tab is not selected",
                mActivityTestRule.getActivity().getCurrentTabModel().index(), 0);
        compareAllTabStripsWithModel();
    }

    /**
     * Tests that selecting a tab properly selects the new tab with many present.  This lets us
     * also check that the visible tab ordering is correct.
     */
    @Test
    @LargeTest
    @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
    @Feature({"TabStrip"})
    @DisabledTest(message = "crbug.com/1107395")
    public void testSelectWithManyTabs() throws Exception {
        ChromeTabUtils.newTabsFromMenu(
                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity(), 4);
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertEquals("The last tab is not selected",
                mActivityTestRule.getActivity().getCurrentTabModel().index(), 4);
        compareAllTabStripsWithModel();
        // Note: if the tab is not visible, this will fail. Currently that's not a problem, because
        // the devices we test on are wide enough.
        selectTab(false, mActivityTestRule.getActivity().getCurrentTabModel().getTabAt(0).getId());
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertEquals("The middle tab is not selected",
                mActivityTestRule.getActivity().getCurrentTabModel().index(), 0);
        compareAllTabStripsWithModel();
    }

    /**
     * Tests closing a tab when there are two tabs open.  The remaining tab should still be
     * selected.
     */
    @Test
    @LargeTest
    @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
    @Feature({"TabStrip"})
    public void testCloseTabWithTwoTabs() throws Exception {
        ChromeTabUtils.newTabFromMenu(
                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertEquals("There are not two tabs present",
                mActivityTestRule.getActivity().getCurrentTabModel().getCount(), 2);
        Assert.assertEquals("The second tab is not selected",
                mActivityTestRule.getActivity().getCurrentTabModel().index(), 1);
        int initialSelectedId = mActivityTestRule.getActivity().getActivityTab().getId();
        closeTab(false, mActivityTestRule.getActivity().getCurrentTabModel().getTabAt(0).getId());
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertEquals("There is not one tab present",
                mActivityTestRule.getActivity().getCurrentTabModel().getCount(), 1);
        Assert.assertEquals("The wrong tab index is selected after close",
                mActivityTestRule.getActivity().getCurrentTabModel().index(), 0);
        Assert.assertEquals("Same tab not still selected", initialSelectedId,
                mActivityTestRule.getActivity().getActivityTab().getId());
        compareAllTabStripsWithModel();
    }

    /**
     * Tests closing a tab when there are many tabs open.  The remaining tab should still be
     * selected, even if the index has changed.
     */
    @Test
    @LargeTest
    @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
    @Feature({"TabStrip"})
    public void testCloseTabWithManyTabs() throws Exception {
        ChromeTabUtils.newTabsFromMenu(
                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity(), 4);
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertEquals("There are not five tabs present",
                mActivityTestRule.getActivity().getCurrentTabModel().getCount(), 5);
        Assert.assertEquals("The last tab is not selected",
                mActivityTestRule.getActivity().getCurrentTabModel().index(), 4);
        int initialSelectedId = mActivityTestRule.getActivity().getActivityTab().getId();
        // Note: if the tab is not visible, this will fail. Currently that's not a problem, because
        // the devices we test on are wide enough.
        closeTab(false, mActivityTestRule.getActivity().getCurrentTabModel().getTabAt(0).getId());
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertEquals("There are not four tabs present",
                mActivityTestRule.getActivity().getCurrentTabModel().getCount(), 4);
        Assert.assertEquals("The wrong tab index is selected after close",
                mActivityTestRule.getActivity().getCurrentTabModel().index(), 3);
        Assert.assertEquals("Same tab not still selected", initialSelectedId,
                mActivityTestRule.getActivity().getActivityTab().getId());
        compareAllTabStripsWithModel();
    }

    /**
     * Tests that closing the selected tab properly closes the current tab and updates to a new
     * selected tab.
     */
    @Test
    @LargeTest
    @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
    @Feature({"TabStrip"})
    public void testCloseSelectedTab() throws Exception {
        ChromeTabUtils.newTabFromMenu(
                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertEquals("There are not two tabs present",
                mActivityTestRule.getActivity().getCurrentTabModel().getCount(), 2);
        Assert.assertEquals("The second tab is not selected",
                mActivityTestRule.getActivity().getCurrentTabModel().index(), 1);
        int newSelectionId =
                mActivityTestRule.getActivity().getCurrentTabModel().getTabAt(0).getId();
        closeTab(false, mActivityTestRule.getActivity().getCurrentTabModel().getTabAt(1).getId());
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertEquals("There is not one tab present",
                mActivityTestRule.getActivity().getCurrentTabModel().getCount(), 1);
        Assert.assertEquals("The wrong tab index is selected after close",
                mActivityTestRule.getActivity().getCurrentTabModel().index(), 0);
        Assert.assertEquals("New tab not selected", newSelectionId,
                mActivityTestRule.getActivity().getActivityTab().getId());
        compareAllTabStripsWithModel();
    }

    /**
     * Tests that selecting "Close all tabs" from the tab menu closes all tabs.
     * Also tests that long press on close button selects the tab and displays the menu.
     */
    @Test
    @LargeTest
    @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
    @Feature({"TabStrip"})
    public void testCloseAllTabsFromTabMenuClosesAllTabs() {
        // 1. Create a second tab
        ChromeTabUtils.newTabFromMenu(
                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertEquals("There are not two tabs present", 2,
                mActivityTestRule.getActivity().getCurrentTabModel().getCount());
        Assert.assertEquals("The second tab is not selected", 1,
                mActivityTestRule.getActivity().getCurrentTabModel().index());

        // 2. Display tab menu on first tab
        int tabSelectionId =
                mActivityTestRule.getActivity().getCurrentTabModel().getTabAt(0).getId();
        longPressCloseTab(false, tabSelectionId);
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertEquals("There are not two tabs present", 2,
                mActivityTestRule.getActivity().getCurrentTabModel().getCount());
        Assert.assertEquals("The wrong tab index is selected after long press", 0,
                mActivityTestRule.getActivity().getCurrentTabModel().index());
        Assert.assertEquals("Long pressed tab not selected", tabSelectionId,
                mActivityTestRule.getActivity().getActivityTab().getId());

        // 3. Invoke "close all tabs" menu action; block until action is completed
        TestThreadUtils.runOnUiThreadBlocking(() -> {
            TabStripUtils.getActiveStripLayoutHelper(mActivityTestRule.getActivity())
                    .clickTabMenuItem(StripLayoutHelper.ID_CLOSE_ALL_TABS);
        });

        // 4. Ensure all tabs were closed
        Assert.assertEquals("Expected no tabs to be present", 0,
                mActivityTestRule.getActivity().getCurrentTabModel().getCount());
    }

    /**
     * Tests that the tab menu is dismissed when the orientation changes and no tabs
     * are closed.
     */
    @Test
    @LargeTest
    @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
    @Feature({"TabStrip"})
    public void testTabMenuDismissedOnOrientationChange() {
        // 1. Set orientation to portrait
        mActivityTestRule.getActivity().setRequestedOrientation(
                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();

        // 2. Open tab menu
        int tabSelectionId =
                mActivityTestRule.getActivity().getCurrentTabModel().getTabAt(0).getId();
        longPressCloseTab(false, tabSelectionId);
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();

        // 3. Set orientation to landscape and assert tab menu is not showing
        mActivityTestRule.getActivity().setRequestedOrientation(
                ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertFalse(TabStripUtils.getActiveStripLayoutHelper(mActivityTestRule.getActivity())
                                   .isTabMenuShowing());
        Assert.assertEquals("Expected 1 tab to be present", 1,
                mActivityTestRule.getActivity().getCurrentTabModel().getCount());

        // 4. Reset orientation
        mActivityTestRule.getActivity().setRequestedOrientation(
                ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
    }

    /**
     * Tests that pressing the incognito toggle button properly switches between the incognito
     * and normal TabStrips.
     */

    @Test
    @LargeTest
    @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
    @Feature({"TabStrip"})
    public void testToggleIncognitoMode() throws Exception {
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertFalse("Expected normal strip to be selected",
                mActivityTestRule.getActivity().getTabModelSelector().isIncognitoSelected());
        mActivityTestRule.newIncognitoTabFromMenu();
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertTrue("Expected incognito strip to be selected",
                mActivityTestRule.getActivity().getTabModelSelector().isIncognitoSelected());
        compareAllTabStripsWithModel();
        clickIncognitoToggleButton();
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertFalse("Expected normal strip to be selected",
                mActivityTestRule.getActivity().getTabModelSelector().isIncognitoSelected());
        compareAllTabStripsWithModel();
        clickIncognitoToggleButton();
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertTrue("Expected incognito strip to be selected",
                mActivityTestRule.getActivity().getTabModelSelector().isIncognitoSelected());
    }

    /**
     * Tests that closing the last incognito tab properly closes the incognito TabStrip and
     * switches to the normal TabStrip.
     */
    @Test
    @LargeTest
    @Feature({"TabStrip"})
    @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
    public void testCloseLastIncognitoTab() {
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertFalse("Expected normal strip to be selected",
                mActivityTestRule.getActivity().getTabModelSelector().isIncognitoSelected());
        mActivityTestRule.newIncognitoTabFromMenu();
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertTrue("Expected incognito strip to be selected",
                mActivityTestRule.getActivity().getTabModelSelector().isIncognitoSelected());
        closeTab(true,
                TabModelUtils
                        .getCurrentTab(
                                mActivityTestRule.getActivity().getTabModelSelector().getModel(
                                        true))
                        .getId());
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertFalse("Expected normal strip to be selected",
                mActivityTestRule.getActivity().getTabModelSelector().isIncognitoSelected());
        Assert.assertEquals("Expected incognito strip to have no tabs",
                mActivityTestRule.getActivity().getTabModelSelector().getModel(true).getCount(), 0);
    }

    /**
     * Tests that closing all incognito tab properly closes the incognito TabStrip and
     * switches to the normal TabStrip.
     */
    @Test
    @LargeTest
    @Feature({"TabStrip"})
    @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
    public void testCloseAllIncognitoTabsFromTabMenu() {
        //1. Create two incognito tabs
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertFalse("Expected normal strip to be selected",
                mActivityTestRule.getActivity().getTabModelSelector().isIncognitoSelected());
        mActivityTestRule.newIncognitoTabFromMenu();
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        mActivityTestRule.newIncognitoTabFromMenu();
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertTrue("Expected incognito strip to be selected",
                mActivityTestRule.getActivity().getTabModelSelector().isIncognitoSelected());
        Assert.assertEquals("Expected incognito strip to have 2 tabs", 2,
                mActivityTestRule.getActivity().getTabModelSelector().getModel(true).getCount());

        // 2. Open tab menu
        int tabSelectionId =
                TabModelUtils
                        .getCurrentTab(
                                mActivityTestRule.getActivity().getTabModelSelector().getModel(
                                        true))
                        .getId();
        longPressCloseTab(true, tabSelectionId);
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();

        // 3. Invoke menu action; block until action is completed
        TestThreadUtils.runOnUiThreadBlocking(() -> {
            TabStripUtils.getActiveStripLayoutHelper(mActivityTestRule.getActivity())
                    .clickTabMenuItem(StripLayoutHelper.ID_CLOSE_ALL_TABS);
        });

        // 4. Ensure all incognito tabs were closed and TabStrip is switched to normal
        Assert.assertFalse("Expected normal strip to be selected",
                mActivityTestRule.getActivity().getTabModelSelector().isIncognitoSelected());
        Assert.assertEquals("Expected normal strip to have 1 tab", 1,
                mActivityTestRule.getActivity().getTabModelSelector().getModel(false).getCount());
        Assert.assertEquals("Expected incognito strip to have no tabs", 0,
                mActivityTestRule.getActivity().getTabModelSelector().getModel(true).getCount());
    }

    /**
     * Test that switching a tab and quickly changing the model stays on the correct new tab/model
     * when the tab finishes loading (when the GL overlay goes away).
     */
    @Test
    @LargeTest
    @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
    @Feature({"TabStrip"})
    public void testTabSelectionViewDoesNotBreakModelSwitch() {
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertFalse("Expected normal strip to be selected",
                mActivityTestRule.getActivity().getTabModelSelector().isIncognitoSelected());
        mActivityTestRule.newIncognitoTabFromMenu();
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertTrue("Expected incognito strip to be selected",
                mActivityTestRule.getActivity().getTabModelSelector().isIncognitoSelected());
        mActivityTestRule.newIncognitoTabFromMenu();
        ChromeTabUtils.switchTabInCurrentTabModel(mActivityTestRule.getActivity(), 0);

        clickIncognitoToggleButton();

        Assert.assertFalse("Expected normal strip to be selected",
                mActivityTestRule.getActivity().getTabModelSelector().isIncognitoSelected());
    }

    /**
     * Compares tab strips with models after switching between the ScrollingStripStacker and
     * CascadingStripStacker when an incognito tab is present. Tests tapping the incognito
     * button while the strip is using the ScrollingStripStacker (other tests cover tapping
     * the button while using the CascadingStripStacker), and checks that switching between
     * tab models scrolls to make the selected tab visible.
     */
    @Test
    @LargeTest
    @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
    @Feature({"TabStrip"})
    public void testSwitchStripStackersWithIncognito() throws Exception {
        // Open an incognito tab to switch to the incognito model.
        mActivityTestRule.newIncognitoTabFromMenu();

        // Open enough regular tabs to cause the tabs to cascade or the strip to scroll depending
        // on which stacker is being used.
        ChromeTabUtils.newTabsFromMenu(
                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity(), 10);

        // Switch to the ScrollingStripStacker.
        setShouldCascadeTabsAndCheckTabStrips(false);

        // Scroll so the selected tab is not visible.
        assertSetTabStripScrollOffset(0);
        TabModel model = mActivityTestRule.getActivity().getTabModelSelector().getModel(false);
        StripLayoutTab tab = TabStripUtils.findStripLayoutTab(
                mActivityTestRule.getActivity(), false, model.getTabAt(10).getId());
        assertTabVisibility(false, tab);

        // Create visibility callback helper.
        final CallbackHelper helper = new CallbackHelper();
        tab.addObserver(new StripLayoutTab.Observer() {
            @Override
            public void onVisibilityChanged(boolean visible) {
                // Notify the callback when tab becomes visible.
                if (visible) helper.notifyCalled();
            }
        });

        // Open another incognito tab to switch to the incognito model.
        mActivityTestRule.newIncognitoTabFromMenu();

        // Switch tab models to switch back to the regular tab strip.
        clickIncognitoToggleButton();

        // Wait for selected tab to be visible.
        helper.waitForCallback(0);

        // 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.
     */
    @Test
    @LargeTest
    @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
    @Feature({"TabStrip"})
    public void testSwitchStripStackersWithLastTabSelected() throws Exception {
        // Open enough regular tabs to cause the tabs to cascade or the strip to scroll depending
        // on which stacker is being used.
        ChromeTabUtils.newTabsFromMenu(
                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.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.
     */
    @Test
    @LargeTest
    @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
    @Feature({"TabStrip"})
    public void testSwitchStripStackersWithFirstTabSelected() throws Exception {
        // Open enough regular tabs to cause the tabs to cascade or the strip to scroll depending
        // on which stacker is being used.
        ChromeTabUtils.newTabsFromMenu(
                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.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(mActivityTestRule.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(mActivityTestRule.getActivity())
                        .getMinimumScrollOffset());
        StripLayoutTab selectedLayoutTab =
                TabStripUtils.findStripLayoutTab(mActivityTestRule.getActivity(), false,
                        mActivityTestRule.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.
     */
    @Test
    @LargeTest
    @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
    @Feature({"TabStrip"})
    public void testSwitchStripStackersWithMiddleTabSelected() throws Exception {
        // Open enough regular tabs to cause the tabs to cascade or the strip to scroll depending
        // on which stacker is being used.
        ChromeTabUtils.newTabsFromMenu(
                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.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(mActivityTestRule.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.
     */
    @Test
    @LargeTest
    @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
    @Feature({"TabStrip"})
    public void testScrollingStripStackerFadeOpacity() throws Exception {
        // Switch to the ScrollingStripStacker.
        setShouldCascadeTabsAndCheckTabStrips(false);

        // Open enough regular tabs to cause the strip to scroll.
        ChromeTabUtils.newTabsFromMenu(
                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.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(mActivityTestRule.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.
     */
    @Test
    @LargeTest
    @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
    @Feature({"TabStrip"})
    public void testScrollingStripStackerScrollsToSelectedTab() throws Exception {
        // Switch to the ScrollingStripStacker.
        setShouldCascadeTabsAndCheckTabStrips(false);

        // Open enough regular tabs to cause the strip to scroll.
        ChromeTabUtils.newTabsFromMenu(
                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity(), 10);

        // Get tab at index 0 and assert it is not visible.
        TabModel model = mActivityTestRule.getActivity().getTabModelSelector().getModel(false);
        final StripLayoutTab tab = TabStripUtils.findStripLayoutTab(
                mActivityTestRule.getActivity(), false, model.getTabAt(0).getId());
        assertTabVisibility(false, tab);

        // Create visibility callback helper.
        final CallbackHelper helper = new CallbackHelper();
        tab.addObserver(new StripLayoutTab.Observer() {
            @Override
            public void onVisibilityChanged(boolean visible) {
                // Notify the helper when tab becomes visible.
                if (visible) helper.notifyCalled();
            }
        });

        // Select tab 0.
        ChromeTabUtils.switchTabInCurrentTabModel(mActivityTestRule.getActivity(), 0);

        // Tab should now be visible.
        helper.waitForCallback(0);
    }

    /**
     * Test that the draw positions for tabs match expectations at various scroll positions
     * when using the ScrollingStripStacker.
     */
    @Test
    @LargeTest
    @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
    @Feature({"TabStrip"})
    public void testScrollingStripStackerTabOffsets() throws Exception {
        // Switch to the ScrollingStripStacker.
        setShouldCascadeTabsAndCheckTabStrips(false);

        // Open enough regular tabs to cause the strip to scroll and select the first tab.
        ChromeTabUtils.newTabsFromMenu(
                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity(), 10);

        // Set up some variables.
        StripLayoutHelper strip =
                TabStripUtils.getActiveStripLayoutHelper(mActivityTestRule.getActivity());
        StripLayoutTab[] tabs = strip.getStripLayoutTabs();
        float tabDrawWidth = tabs[0].getWidth() - strip.getTabOverlapWidth();

        // Disable animations. The animation that normally runs when scrolling the tab strip makes
        // this test flaky.
        strip.disableAnimationsForTesting();

        // Create callback helper to be notified when first tab becomes visible.
        final CallbackHelper visibleHelper = new CallbackHelper();
        tabs[0].addObserver(new StripLayoutTab.Observer() {
            @Override
            public void onVisibilityChanged(boolean visible) {
                if (visible) visibleHelper.notifyCalled();
            }
        });

        // Switch to the first tab and wait until it's visible.
        ChromeTabUtils.switchTabInCurrentTabModel(mActivityTestRule.getActivity(), 0);
        visibleHelper.waitForCallback(0);

        // Check initial model validity.
        compareAllTabStripsWithModel();

        // Assert getStripLayoutTabs() returns the expected number of tabs.
        Assert.assertEquals("Unexpected number of StripLayoutTabs.", 11, tabs.length);

        // Create callback helper to be notified when first tab is no longer visible.
        final CallbackHelper notVisibleHelper = new CallbackHelper();
        tabs[0].addObserver(new StripLayoutTab.Observer() {
            @Override
            public void onVisibilityChanged(boolean visible) {
                if (!visible) notVisibleHelper.notifyCalled();
            }
        });

        // Scroll tab strip to 0 and check tab positions.
        assertSetTabStripScrollOffset(0);
        for (int i = 0; i < tabs.length; i++) {
            assertTabDrawX(i * tabDrawWidth, tabs[i], 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], 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], i);
        }

        // Wait for the first tab in the strip to no longer be visible.
        notVisibleHelper.waitForCallback(0);
    }

    /**
     * Tests that switching tabs hides keyboard.
     */
    @Test
    @LargeTest
    @Restriction(UiRestriction.RESTRICTION_TYPE_TABLET)
    @Feature({"TabStrip", "IME"})
    public void testSwitchingTabsHidesKeyboard() throws Throwable {
        mActivityTestRule.loadUrl("data:text/html;charset=utf-8,<html><head></head><body><form>"
                + "<input type='text' id='input0'></form></body></html>");
        DOMUtils.clickNode(
                mActivityTestRule.getActivity().getActivityTab().getWebContents(), "input0");
        assertWaitForKeyboardStatus(true);

        InstrumentationRegistry.getInstrumentation().waitForIdleSync();

        ChromeTabUtils.clickNewTabButton(
                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());

        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        Assert.assertEquals("Expected two tabs to exist",
                mActivityTestRule.getActivity().getTabModelSelector().getModel(false).getCount(),
                2);

        assertWaitForKeyboardStatus(false);
    }

    /**
     * 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.
     * @param modelPos The position in the model we want to map.
     * @return The position in the view hierarchy that represents the tab at modelPos.
     */
    private int mapModelToViewIndex(int tabCount, int selectedIndex, int modelPos) {
        if (modelPos < selectedIndex) {
            return modelPos;
        } else if (modelPos == selectedIndex) {
            return tabCount - 1;
        } else {
            return tabCount - 1 - modelPos + selectedIndex;
        }
    }

    /**
     * Simulates a click to the incognito toggle button.
     */
    protected void clickIncognitoToggleButton() {
        final CallbackHelper tabModelSelectedCallback = new CallbackHelper();
        TabModelSelectorObserver observer = new EmptyTabModelSelectorObserver() {
            @Override
            public void onTabModelSelected(TabModel newModel, TabModel oldModel) {
                tabModelSelectedCallback.notifyCalled();
            }
        };
        mActivityTestRule.getActivity().getTabModelSelector().addObserver(observer);
        StripLayoutHelperManager manager =
                TabStripUtils.getStripLayoutHelperManager(mActivityTestRule.getActivity());
        TabStripUtils.clickCompositorButton(manager.getModelSelectorButton(),
                InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity());
        try {
            tabModelSelectedCallback.waitForCallback(0);
        } catch (TimeoutException e) {
            Assert.fail("Tab model selected event never occurred.");
        }
        mActivityTestRule.getActivity().getTabModelSelector().removeObserver(observer);
    }

    /**
     * Simulates a click on a tab, selecting it.
     * @param incognito Whether or not this tab is in the incognito or normal stack.
     * @param id The id of the tab to click.
     */
    protected void selectTab(final boolean incognito, final int id) {
        ChromeTabUtils.selectTabWithAction(InstrumentationRegistry.getInstrumentation(),
                mActivityTestRule.getActivity(), new Runnable() {
                    @Override
                    public void run() {
                        TabStripUtils.clickTab(
                                TabStripUtils.findStripLayoutTab(
                                        mActivityTestRule.getActivity(), incognito, id),
                                InstrumentationRegistry.getInstrumentation(),
                                mActivityTestRule.getActivity());
                    }
                });
    }

    /**
     * Simulates a click on the close button of a tab.
     * @param incognito Whether or not this tab is in the incognito or normal stack.
     * @param id The id of the tab to click.
     */
    protected void closeTab(final boolean incognito, final int id) {
        ChromeTabUtils.closeTabWithAction(InstrumentationRegistry.getInstrumentation(),
                mActivityTestRule.getActivity(), new Runnable() {
                    @Override
                    public void run() {
                        StripLayoutTab tab = TabStripUtils.findStripLayoutTab(
                                mActivityTestRule.getActivity(), incognito, id);
                        TabStripUtils.clickCompositorButton(tab.getCloseButton(),
                                InstrumentationRegistry.getInstrumentation(),
                                mActivityTestRule.getActivity());
                    }
                });
    }

    /**
     * Simulates a long press on the close button of a tab. Asserts that the tab
     * is selected and the tab menu is showing.
     * @param incognito Whether or not this tab is in the incognito or normal stack.
     * @param id The id of the tab to click.
     */
    protected void longPressCloseTab(final boolean incognito, final int id) {
        ChromeTabUtils.selectTabWithAction(InstrumentationRegistry.getInstrumentation(),
                mActivityTestRule.getActivity(), new Runnable() {
                    @Override
                    public void run() {
                        StripLayoutTab tab = TabStripUtils.findStripLayoutTab(
                                mActivityTestRule.getActivity(), incognito, id);
                        TabStripUtils.longPressCompositorButton(tab.getCloseButton(),
                                InstrumentationRegistry.getInstrumentation(),
                                mActivityTestRule.getActivity());
                    }
                });
        Assert.assertTrue(TabStripUtils.getActiveStripLayoutHelper(mActivityTestRule.getActivity())
                                  .isTabMenuShowing());
    }

    /**
     * Compares a TabView with the corresponding model Tab.  This tries to compare as many
     * features as possible making sure the TabView properly mirrors the Tab it represents.
     * @param incognito Whether or not this tab is incognito or not.
     * @param id The id of the tab to compare.
     */
    protected void compareTabViewWithModel(boolean incognito, int id) throws ExecutionException {
        TabModel model = mActivityTestRule.getActivity().getTabModelSelector().getModel(incognito);
        Tab tab = TabModelUtils.getTabById(model, id);
        StripLayoutHelper tabStrip =
                TabStripUtils.getStripLayoutHelper(mActivityTestRule.getActivity(), incognito);
        StripLayoutTab tabView =
                TabStripUtils.findStripLayoutTab(mActivityTestRule.getActivity(), incognito, id);

        Assert.assertTrue("One of Tab and TabView does not exist",
                (tabView == null && tab == null) || (tabView != null && tab != null));

        if (tabView == null || tab == null) return;

        Assert.assertEquals("The IDs are not identical", tabView.getId(), tab.getId());

        int assumedTabViewIndex = mapModelToViewIndex(model.getCount(), model.index(),
                model.indexOf(tab));

        Assert.assertEquals("The tab is not in the proper position ", assumedTabViewIndex,
                tabStrip.visualIndexOfTab(tabView));

        if (TabModelUtils.getCurrentTab(model) == tab
                && mActivityTestRule.getActivity().getTabModelSelector().isIncognitoSelected()
                        == incognito) {
            Assert.assertTrue("ChromeTab is not in the proper selection state",
                    tabStrip.isForegroundTab(tabView));
            if (tabStrip.shouldCascadeTabs()) {
                Assert.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, 0);
            }
        }

        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
     * 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.
     * @param incognito Whether or not to check the incognito or normal TabStrip.
     */
    protected void compareTabStripWithModel(boolean incognito) throws ExecutionException {
        TabModel model = mActivityTestRule.getActivity().getTabModelSelector().getModel(incognito);
        StripLayoutHelper strip =
                TabStripUtils.getStripLayoutHelper(mActivityTestRule.getActivity(), incognito);
        StripLayoutHelper activeStrip =
                TabStripUtils.getActiveStripLayoutHelper(mActivityTestRule.getActivity());
        TabModel activeModel = mActivityTestRule.getActivity().getCurrentTabModel();

        if (activeModel.isIncognito() == incognito) {
            Assert.assertEquals("TabStrip is not in the right visible state", strip, activeStrip);
            Assert.assertEquals("TabStrip does not have the same number of views as the model",
                    strip.getTabCount(), model.getCount());
        } else {
            Assert.assertTrue("TabStrip is not in the right visible state", model != activeModel);
        }

        CompositorButton incognitoIndicator =
                TabStripUtils.getStripLayoutHelperManager(mActivityTestRule.getActivity())
                        .getModelSelectorButton();
        if (activeModel.isIncognito()) {
            Assert.assertNotNull("Incognito indicator null in incognito mode", incognitoIndicator);
            Assert.assertTrue("Incognito indicator not visible in incognito mode",
                    incognitoIndicator.isVisible());
        } else if (mActivityTestRule.getActivity().getTabModelSelector().getModel(true).getCount()
                == 0) {
            Assert.assertFalse("Incognito indicator visible in non incognito mode",
                    incognitoIndicator.isVisible());
        }

        for (int i = 0; i < model.getCount(); ++i) {
            compareTabViewWithModel(incognito, model.getTabAt(i).getId());
        }
    }

    /**
     * Compares all TabStrips with the corresponding TabModels.  This also checks if the incognito
     * toggle is visible if necessary.
     */
    protected void compareAllTabStripsWithModel() throws ExecutionException {
        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)
            throws ExecutionException {
        TabModel model = mActivityTestRule.getActivity().getCurrentTabModel();
        int selectedTabIndex = model.index();

        TestThreadUtils.runOnUiThreadBlocking(() -> {
            TabStripUtils.getStripLayoutHelper(mActivityTestRule.getActivity(), true)
                    .setShouldCascadeTabs(shouldCascadeTabs);
            TabStripUtils.getStripLayoutHelper(mActivityTestRule.getActivity(), false)
                    .setShouldCascadeTabs(shouldCascadeTabs);
        });

        // Assert that the correct StripStacker is being used.
        Assert.assertEquals(shouldCascadeTabs
                        ? "Expected CascadingStripStacker but was ScrollingStripStacker."
                        : "Expected ScrollingStripStacker but was CascadingStripStacker.",
                shouldCascadeTabs,
                TabStripUtils.getActiveStripLayoutHelper(mActivityTestRule.getActivity())
                        .shouldCascadeTabs());

        // Assert that the same tab is still selected.
        Assert.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(mActivityTestRule.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) throws ExecutionException {
        final StripLayoutHelper strip =
                TabStripUtils.getActiveStripLayoutHelper(mActivityTestRule.getActivity());
        TestThreadUtils.runOnUiThreadBlocking(
                () -> { strip.setScrollOffsetForTesting(scrollOffset); });

        Assert.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(mActivityTestRule.getActivity());
        if (isLeft) {
            Assert.assertEquals("Left tab strip fade visibility is incorrect.", 0.f,
                    strip.getLeftFadeOpacity(), 0);
        } else {
            Assert.assertEquals("Right tab strip fade visibility is incorrect.", 0.f,
                    strip.getRightFadeOpacity(), 0);
        }
    }

    /**
     * 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(mActivityTestRule.getActivity());
        if (isLeft) {
            Assert.assertEquals("Left tab strip fade visibility is incorrect.", 1.f,
                    strip.getLeftFadeOpacity(), 0);
        } else {
            Assert.assertEquals("Right tab strip fade visibility is incorrect.", 1.f,
                    strip.getRightFadeOpacity(), 0);
        }
    }

    /**
     * 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(mActivityTestRule.getActivity());
        if (isLeft) {
            boolean isPartiallyVisible = strip.getLeftFadeOpacity() > 0.f
                    && strip.getLeftFadeOpacity() < 1.f;
            Assert.assertEquals("Left tab strip fade expected to be partially visible.", true,
                    isPartiallyVisible);
        } else {
            boolean isPartiallyVisible = strip.getRightFadeOpacity() > 0.f
                    && strip.getRightFadeOpacity() < 1.f;
            Assert.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(final StripLayoutHelper tabStrip,
            final StripLayoutTab tabView) throws ExecutionException {
        // The visible percent for all tabs is 1.0 in the ScrollingStripStacker.
        Assert.assertEquals("ChromeTab is not completely visible. All tabs should be visible when "
                        + "the ScrollingStripStacker is in use.",
                tabView.getVisiblePercentage(), 1.0f, 0);

        // Only tabs that can currently be seen on the screen should be visible.
        Boolean shouldBeVisible = TestThreadUtils.runOnUiThreadBlocking(new Callable<Boolean>() {
            @Override
            public Boolean call() {
                return (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(final Boolean shouldBeVisible, final StripLayoutTab tabView)
            throws ExecutionException {
        Boolean isVisible = TestThreadUtils.runOnUiThreadBlocking(new Callable<Boolean>() {
            @Override
            public Boolean call() {
                return tabView.isVisible();
            }
        });

        Assert.assertEquals(
                "ChromeTab " + (shouldBeVisible ? "should" : "should not") + " be visible.",
                shouldBeVisible, 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.
     * @param index The index for the tab.
     */
    private void assertTabDrawX(float expectedDrawX, final StripLayoutTab tabView, int index)
            throws ExecutionException {
        Float tabDrawX = TestThreadUtils.runOnUiThreadBlocking(new Callable<Float>() {
            @Override
            public Float call() {
                return tabView.getDrawX();
            }
        });

        Assert.assertEquals(
                "Incorrect draw position for tab at " + index, expectedDrawX, tabDrawX, 0);
    }

    /**
     * Asserts that we get the keyboard status to be shown or hidden.
     * @param expectsShown Whether shown status is expected.
     */
    private void assertWaitForKeyboardStatus(final boolean expectsShown) {
        CriteriaHelper.pollInstrumentationThread(() -> {
            Criteria.checkThat(mActivityTestRule.getKeyboardDelegate().isKeyboardShowing(
                                       mActivityTestRule.getActivity(),
                                       mActivityTestRule.getActivity().getActivityTab().getView()),
                    Matchers.is(expectsShown));
        });
    }
}
