blob: 10cc489258c669b662f35ad2ad57d117368ca37f [file] [log] [blame]
// Copyright 2019 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.features.start_surface;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.Espresso.pressBack;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.action.ViewActions.pressKey;
import static android.support.test.espresso.action.ViewActions.replaceText;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.Visibility.GONE;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withParent;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.chromium.chrome.browser.tasks.ReturnToChromeExperimentsUtil.TAB_SWITCHER_ON_RETURN_MS;
import static org.chromium.chrome.test.util.ViewUtils.VIEW_GONE;
import static org.chromium.chrome.test.util.ViewUtils.onViewWaiting;
import static org.chromium.chrome.test.util.ViewUtils.waitForView;
import android.content.Intent;
import android.support.test.InstrumentationRegistry;
import android.support.test.espresso.contrib.RecyclerViewActions;
import android.support.test.filters.MediumTest;
import android.view.KeyEvent;
import android.view.ViewGroup;
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.params.ParameterAnnotations;
import org.chromium.base.test.params.ParameterAnnotations.UseRunnerDelegate;
import org.chromium.base.test.params.ParameterSet;
import org.chromium.base.test.params.ParameterizedRunner;
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.ChromeTabbedActivity;
import org.chromium.chrome.browser.compositor.layouts.phone.StackLayout;
import org.chromium.chrome.browser.flags.CachedFeatureFlags;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.flags.ChromeSwitches;
import org.chromium.chrome.browser.tasks.ReturnToChromeExperimentsUtil;
import org.chromium.chrome.browser.tasks.tab_management.TabUiTestHelper;
import org.chromium.chrome.start_surface.R;
import org.chromium.chrome.test.ChromeActivityTestRule;
import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
import org.chromium.chrome.test.util.OverviewModeBehaviorWatcher;
import org.chromium.chrome.test.util.browser.Features;
import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
import org.chromium.content_public.browser.test.util.CriteriaHelper;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
import org.chromium.content_public.browser.test.util.TouchCommon;
import org.chromium.net.test.EmbeddedTestServer;
import org.chromium.ui.test.util.UiRestriction;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
/** Integration tests of the {@link StartSurface}. */
@RunWith(ParameterizedRunner.class)
@UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class)
@Restriction(UiRestriction.RESTRICTION_TYPE_PHONE)
@EnableFeatures({ChromeFeatureList.START_SURFACE_ANDROID + "<Study"})
@CommandLineFlags.
Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, "force-fieldtrials=Study/Group"})
public class StartSurfaceTest {
@ParameterAnnotations.ClassParameter
private static List<ParameterSet> sClassParams =
Arrays.asList(new ParameterSet().value(false, false).name("NoInstant_NoReturn"),
new ParameterSet().value(true, false).name("Instant_NoReturn"),
new ParameterSet().value(false, true).name("NoInstant_Return"),
new ParameterSet().value(true, true).name("Instant_Return"));
private static final String BASE_PARAMS =
"force-fieldtrial-params=Study.Group:start_surface_variation";
@Rule
public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
@Rule
public TestRule mProcessor = new Features.InstrumentationProcessor();
private final boolean mImmediateReturn;
private String mUrl;
public StartSurfaceTest(boolean useInstantStart, boolean immediateReturn) {
CachedFeatureFlags.setForTesting(ChromeFeatureList.INSTANT_START, useInstantStart);
mImmediateReturn = immediateReturn;
}
/**
* Only launch Chrome without waiting for a current tab.
* This test could not use {@link ChromeActivityTestRule#startMainActivityFromLauncher()}
* because of its {@link org.chromium.chrome.browser.tab.Tab} dependency.
*/
private void startMainActivityFromLauncher() {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
mActivityTestRule.prepareUrlIntent(intent, null);
mActivityTestRule.startActivityCompletely(intent);
}
private boolean isInstantReturn() {
return CachedFeatureFlags.isEnabled(ChromeFeatureList.INSTANT_START) && mImmediateReturn;
}
@Before
public void setUp() throws IOException {
EmbeddedTestServer testServer =
EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext());
mUrl = testServer.getURL("/chrome/test/data/android/navigate/simple.html");
if (mImmediateReturn) {
TAB_SWITCHER_ON_RETURN_MS.setForTesting(0);
assertEquals(0, ReturnToChromeExperimentsUtil.TAB_SWITCHER_ON_RETURN_MS.getValue());
assertTrue(ReturnToChromeExperimentsUtil.shouldShowTabSwitcher(-1));
// Need to start main activity from launcher for immediate return to be effective.
// However, need at least one tab for carousel to show, which starting main activity
// from launcher doesn't provide.
// Creating tabs and restart the activity would do the trick, but we cannot do that for
// Instant start because we cannot unload native library.
// Create fake TabState files to emulate having one tab in previous session.
InstantStartTest.createTabStateFile(new int[] {0});
startMainActivityFromLauncher();
} else {
// Cannot use startMainActivityFromLauncher().
// Otherwise tab switcher could be shown immediately if single-pane is enabled.
mActivityTestRule.startMainActivityOnBlankPage();
onViewWaiting(allOf(withId(R.id.home_button), isDisplayed()));
}
}
@Test
@MediumTest
@Feature({"StartSurface"})
@CommandLineFlags.Add({BASE_PARAMS + "/tasksonly"})
public void testShow_TasksOnly() {
if (!mImmediateReturn) {
TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity());
}
onViewWaiting(allOf(withId(R.id.primary_tasks_surface_view), isDisplayed()));
onView(withId(org.chromium.chrome.tab_ui.R.id.mv_tiles_container))
.check(matches(isDisplayed()));
onView(withId(org.chromium.chrome.tab_ui.R.id.tasks_surface_body))
.check(matches(isDisplayed()));
TestThreadUtils.runOnUiThreadBlocking(
() -> mActivityTestRule.getActivity().getLayoutManager().hideOverview(false));
assertFalse(mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
}
@Test
@MediumTest
@Feature({"StartSurface"})
// clang-format off
@CommandLineFlags.Add({BASE_PARAMS + "/omniboxonly" +
"/hide_switch_when_no_incognito_tabs/true"})
public void testShow_OmniboxOnly() {
// clang-format on
final ChromeTabbedActivity cta = mActivityTestRule.getActivity();
if (!mImmediateReturn) {
TabUiTestHelper.enterTabSwitcher(cta);
}
onViewWaiting(allOf(withId(R.id.primary_tasks_surface_view), isDisplayed()));
onView(withId(org.chromium.chrome.tab_ui.R.id.mv_tiles_container))
.check(matches(withEffectiveVisibility(GONE)));
onView(withId(org.chromium.chrome.tab_ui.R.id.tasks_surface_body))
.check(matches(isDisplayed()));
if (!isInstantReturn()) {
// TODO(crbug/1076274): fix toolbar to make incognito switch part of the view.
onView(withId(org.chromium.chrome.tab_ui.R.id.incognito_switch))
.check(matches(withEffectiveVisibility(GONE)));
}
mActivityTestRule.waitForActivityNativeInitializationComplete();
TabUiTestHelper.createTabs(cta, true, 1);
TabUiTestHelper.verifyTabModelTabCount(cta, 1, 1);
if (isInstantReturn()) {
// TODO(crbug/1076274): fix toolbar to avoid wrongly focusing on the toolbar omnibox.
return;
}
TabUiTestHelper.enterTabSwitcher(cta);
if (!isInstantReturn()) {
// TODO(crbug/1076274): fix toolbar to make incognito switch part of the view.
onView(withId(org.chromium.chrome.tab_ui.R.id.incognito_switch))
.check(matches(isDisplayed()));
}
TestThreadUtils.runOnUiThreadBlocking(
() -> cta.getTabModelSelector().getModel(true).closeAllTabs());
TabUiTestHelper.verifyTabModelTabCount(cta, 1, 0);
assertTrue(mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
if (!isInstantReturn()) {
// TODO(crbug/1076274): fix toolbar to make incognito switch part of the view.
onView(withId(org.chromium.chrome.tab_ui.R.id.incognito_switch))
.check(matches(withEffectiveVisibility(GONE)));
}
TestThreadUtils.runOnUiThreadBlocking(
() -> mActivityTestRule.getActivity().getLayoutManager().hideOverview(false));
assertFalse(mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
}
@Test
@MediumTest
@Feature({"StartSurface"})
@CommandLineFlags.Add({BASE_PARAMS + "/twopanes"})
public void testShow_TwoPanes() {
final ChromeTabbedActivity cta = mActivityTestRule.getActivity();
if (!mImmediateReturn) {
TabUiTestHelper.enterTabSwitcher(cta);
}
onViewWaiting(allOf(withId(R.id.primary_tasks_surface_view), isDisplayed()));
onView(withId(R.id.ss_bottom_bar)).check(matches(isDisplayed()));
onView(withId(org.chromium.chrome.tab_ui.R.id.mv_tiles_container))
.check(matches(isDisplayed()));
onView(withId(org.chromium.chrome.tab_ui.R.id.tasks_surface_body))
.check(matches(isDisplayed()));
onView(withId(R.id.ss_explore_tab)).perform(click());
onViewWaiting(withId(R.id.start_surface_explore_view));
pressBack();
onViewWaiting(withId(R.id.primary_tasks_surface_view));
TestThreadUtils.runOnUiThreadBlocking(
() -> mActivityTestRule.getActivity().getLayoutManager().hideOverview(false));
assertFalse(mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
}
@Test
@MediumTest
@Feature({"StartSurface"})
@CommandLineFlags.Add({BASE_PARAMS + "/single"})
public void testShow_SingleAsHomepage() {
if (!mImmediateReturn) {
onView(withId(org.chromium.chrome.tab_ui.R.id.home_button)).perform(click());
}
CriteriaHelper.pollUiThread(
()
-> mActivityTestRule.getActivity().getLayoutManager() != null
&& mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
onView(withId(R.id.primary_tasks_surface_view)).check(matches(isDisplayed()));
onView(withId(R.id.search_box_text)).check(matches(isDisplayed()));
onView(withId(org.chromium.chrome.tab_ui.R.id.mv_tiles_container))
.check(matches(isDisplayed()));
if (!isInstantReturn()) {
// TODO(crbug/1065314): show tab switcher section.
onView(withId(org.chromium.chrome.tab_ui.R.id.tab_switcher_title))
.check(matches(isDisplayed()));
onView(withId(org.chromium.chrome.tab_ui.R.id.carousel_tab_switcher_container))
.check(matches(isDisplayed()));
}
onView(withId(org.chromium.chrome.tab_ui.R.id.tasks_surface_body))
.check(matches(isDisplayed()));
// Note that onView(R.id.more_tabs).perform(click()) can not be used since it requires 90
// percent of the view's area is displayed to the users. However, this view has negative
// margin which makes the percentage is less than 90.
// TODO(crbug.com/1025296): Investigate whether this would be a problem for real users.
try {
TestThreadUtils.runOnUiThreadBlocking(
()
-> mActivityTestRule.getActivity()
.findViewById(org.chromium.chrome.tab_ui.R.id.more_tabs)
.performClick());
} catch (ExecutionException e) {
fail("Failed to tap 'more tabs' " + e.toString());
}
onViewWaiting(withId(R.id.secondary_tasks_surface_view));
if (isInstantReturn()) {
// TODO(crbug/1076274): fix toolbar to avoid wrongly focusing on the toolbar omnibox.
return;
}
pressBack();
onViewWaiting(withId(R.id.primary_tasks_surface_view));
OverviewModeBehaviorWatcher hideWatcher =
TabUiTestHelper.createOverviewHideWatcher(mActivityTestRule.getActivity());
onView(allOf(withParent(withId(
org.chromium.chrome.tab_ui.R.id.carousel_tab_switcher_container)),
withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)))
.perform(RecyclerViewActions.actionOnItemAtPosition(0, click()));
hideWatcher.waitForBehavior();
}
@Test
@MediumTest
@Feature({"StartSurface"})
// clang-format off
@CommandLineFlags.Add({BASE_PARAMS + "/single" +
"/exclude_mv_tiles/true/hide_switch_when_no_incognito_tabs/true"})
public void testShow_SingleAsHomepage_NoMVTiles() {
// clang-format on
if (!mImmediateReturn) {
onView(withId(org.chromium.chrome.tab_ui.R.id.home_button)).perform(click());
}
CriteriaHelper.pollUiThread(
()
-> mActivityTestRule.getActivity().getLayoutManager() != null
&& mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
onView(withId(R.id.primary_tasks_surface_view)).check(matches(isDisplayed()));
onView(withId(R.id.search_box_text)).check(matches(isDisplayed()));
onView(withId(org.chromium.chrome.tab_ui.R.id.mv_tiles_container))
.check(matches(withEffectiveVisibility(GONE)));
if (!isInstantReturn()) {
// TODO(crbug/1065314): show tab switcher section.
onView(withId(org.chromium.chrome.tab_ui.R.id.tab_switcher_title))
.check(matches(isDisplayed()));
onView(withId(org.chromium.chrome.tab_ui.R.id.carousel_tab_switcher_container))
.check(matches(isDisplayed()));
}
onView(withId(org.chromium.chrome.tab_ui.R.id.tasks_surface_body))
.check(matches(isDisplayed()));
if (!isInstantReturn()) {
// TODO(crbug/1076274): fix toolbar to make incognito switch part of the view.
onView(withId(org.chromium.chrome.tab_ui.R.id.incognito_switch))
.check(matches(withEffectiveVisibility(GONE)));
}
// Note that onView(R.id.more_tabs).perform(click()) can not be used since it requires 90
// percent of the view's area is displayed to the users. However, this view has negative
// margin which makes the percentage is less than 90.
// TODO(crbug.com/1025296): Investigate whether this would be a problem for real users.
try {
TestThreadUtils.runOnUiThreadBlocking(
()
-> mActivityTestRule.getActivity()
.findViewById(org.chromium.chrome.tab_ui.R.id.more_tabs)
.performClick());
} catch (ExecutionException e) {
fail("Failed to tap 'more tabs' " + e.toString());
}
onViewWaiting(withId(R.id.secondary_tasks_surface_view));
if (isInstantReturn()) {
// TODO(crbug/1076274): fix toolbar to avoid wrongly focusing on the toolbar omnibox.
return;
}
pressBack();
onViewWaiting(withId(R.id.primary_tasks_surface_view));
OverviewModeBehaviorWatcher hideWatcher =
TabUiTestHelper.createOverviewHideWatcher(mActivityTestRule.getActivity());
onView(allOf(withParent(withId(
org.chromium.chrome.tab_ui.R.id.carousel_tab_switcher_container)),
withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)))
.perform(RecyclerViewActions.actionOnItemAtPosition(0, click()));
hideWatcher.waitForBehavior();
}
@Test
@MediumTest
@Feature({"StartSurface"})
// clang-format off
@CommandLineFlags.Add({BASE_PARAMS + "/single/exclude_mv_tiles/true" +
"/hide_switch_when_no_incognito_tabs/true/show_last_active_tab_only/true"})
public void testShow_SingleAsHomepage_SingleTabNoMVTiles() {
// clang-format on
if (!mImmediateReturn) {
onView(withId(org.chromium.chrome.tab_ui.R.id.home_button)).perform(click());
}
CriteriaHelper.pollUiThread(
()
-> mActivityTestRule.getActivity().getLayoutManager() != null
&& mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
onView(withId(R.id.primary_tasks_surface_view)).check(matches(isDisplayed()));
onView(withId(R.id.search_box_text)).check(matches(isDisplayed()));
onView(withId(org.chromium.chrome.tab_ui.R.id.mv_tiles_container))
.check(matches(withEffectiveVisibility(GONE)));
if (!isInstantReturn()) {
// TODO(crbug/1065314): show tab switcher section.
onView(withId(org.chromium.chrome.tab_ui.R.id.tab_switcher_title))
.check(matches(isDisplayed()));
onView(withId(org.chromium.chrome.tab_ui.R.id.carousel_tab_switcher_container))
.check(matches(isDisplayed()));
onView(withId(org.chromium.chrome.tab_ui.R.id.single_tab_view))
.check(matches(isDisplayed()));
}
onView(withId(org.chromium.chrome.tab_ui.R.id.tasks_surface_body))
.check(matches(isDisplayed()));
if (!isInstantReturn()) {
// TODO(crbug/1076274): fix toolbar to make incognito switch part of the view.
onView(withId(org.chromium.chrome.tab_ui.R.id.incognito_switch))
.check(matches(withEffectiveVisibility(GONE)));
}
// Note that onView(R.id.more_tabs).perform(click()) can not be used since it requires 90
// percent of the view's area is displayed to the users. However, this view has negative
// margin which makes the percentage is less than 90.
// TODO(crbug.com/1025296): Investigate whether this would be a problem for real users.
try {
TestThreadUtils.runOnUiThreadBlocking(
()
-> mActivityTestRule.getActivity()
.findViewById(org.chromium.chrome.tab_ui.R.id.more_tabs)
.performClick());
} catch (ExecutionException e) {
fail("Failed to tap 'more tabs' " + e.toString());
}
onViewWaiting(withId(R.id.secondary_tasks_surface_view));
if (isInstantReturn()) {
// TODO(crbug/1076274): fix toolbar to avoid wrongly focusing on the toolbar omnibox.
return;
}
pressBack();
onViewWaiting(withId(R.id.primary_tasks_surface_view));
OverviewModeBehaviorWatcher hideWatcher =
TabUiTestHelper.createOverviewHideWatcher(mActivityTestRule.getActivity());
onView(withId(org.chromium.chrome.tab_ui.R.id.single_tab_view)).perform(click());
hideWatcher.waitForBehavior();
}
@Test
@MediumTest
@Feature({"StartSurface"})
// clang-format off
@CommandLineFlags.Add({BASE_PARAMS + "/single/exclude_mv_tiles/true" +
"/show_last_active_tab_only/true/show_stack_tab_switcher/true"})
public void testShow_SingleAsHomepage_V2() {
// clang-format on
if (!mImmediateReturn) {
onView(withId(org.chromium.chrome.tab_ui.R.id.home_button)).perform(click());
}
CriteriaHelper.pollUiThread(
()
-> mActivityTestRule.getActivity().getLayoutManager() != null
&& mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
onView(withId(R.id.primary_tasks_surface_view)).check(matches(isDisplayed()));
onView(withId(R.id.search_box_text)).check(matches(isDisplayed()));
onView(withId(org.chromium.chrome.tab_ui.R.id.mv_tiles_container))
.check(matches(withEffectiveVisibility(GONE)));
onView(withId(org.chromium.chrome.tab_ui.R.id.tab_switcher_title))
.check(matches(isDisplayed()));
onView(withId(org.chromium.chrome.tab_ui.R.id.carousel_tab_switcher_container))
.check(matches(isDisplayed()));
onView(withId(org.chromium.chrome.tab_ui.R.id.single_tab_view))
.check(matches(isDisplayed()));
onView(withId(org.chromium.chrome.tab_ui.R.id.tasks_surface_body))
.check(matches(isDisplayed()));
onView(withId(org.chromium.chrome.tab_ui.R.id.incognito_switch))
.check(matches(withEffectiveVisibility(GONE)));
// Note that onView(R.id.more_tabs).perform(click()) can not be used since it requires 90
// percent of the view's area is displayed to the users. However, this view has negative
// margin which makes the percentage is less than 90.
// TODO(crbug.com/1025296): Investigate whether this would be a problem for real users.
try {
TestThreadUtils.runOnUiThreadBlocking(
()
-> mActivityTestRule.getActivity()
.findViewById(org.chromium.chrome.tab_ui.R.id.more_tabs)
.performClick());
} catch (ExecutionException e) {
fail("Failed to tap 'more tabs' " + e.toString());
}
waitForView(withId(R.id.primary_tasks_surface_view), VIEW_GONE);
assertThat(mActivityTestRule.getActivity().getLayoutManager().getOverviewLayout(),
instanceOf(StackLayout.class));
pressBack();
onViewWaiting(withId(R.id.primary_tasks_surface_view));
OverviewModeBehaviorWatcher hideWatcher =
TabUiTestHelper.createOverviewHideWatcher(mActivityTestRule.getActivity());
onView(withId(org.chromium.chrome.tab_ui.R.id.single_tab_view)).perform(click());
hideWatcher.waitForBehavior();
}
@Test
@MediumTest
@Feature({"StartSurface"})
@CommandLineFlags.Add({BASE_PARAMS + "/single"})
public void testShow_SingleAsTabSwitcher() {
if (mImmediateReturn) {
CriteriaHelper.pollUiThread(
()
-> mActivityTestRule.getActivity().getLayoutManager() != null
&& mActivityTestRule.getActivity()
.getLayoutManager()
.overviewVisible());
waitForTabModel();
// Single surface is shown as homepage. Exit in order to get into tab switcher later.
pressBack();
}
if (isInstantReturn()) {
// TODO(crbug/1076274): fix toolbar to avoid wrongly focusing on the toolbar omnibox.
return;
}
TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity());
onViewWaiting(allOf(withId(R.id.secondary_tasks_surface_view), isDisplayed()));
OverviewModeBehaviorWatcher hideWatcher =
TabUiTestHelper.createOverviewHideWatcher(mActivityTestRule.getActivity());
onView(allOf(withParent(withId(org.chromium.chrome.tab_ui.R.id.tasks_surface_body)),
withId(org.chromium.chrome.tab_ui.R.id.tab_list_view)))
.perform(RecyclerViewActions.actionOnItemAtPosition(0, click()));
hideWatcher.waitForBehavior();
}
@Test
@MediumTest
@Feature({"StartSurface"})
// clang-format off
@CommandLineFlags.Add({BASE_PARAMS + "/single/exclude_mv_tiles/true" +
"/show_last_active_tab_only/true/show_stack_tab_switcher/true"})
public void testShow_SingleAsTabSwitcher_V2() {
// clang-format on
if (mImmediateReturn) {
CriteriaHelper.pollUiThread(
()
-> mActivityTestRule.getActivity().getLayoutManager() != null
&& mActivityTestRule.getActivity()
.getLayoutManager()
.overviewVisible());
// Single surface is shown as homepage. Exit in order to get into tab switcher later.
pressBack();
}
TabUiTestHelper.enterTabSwitcher(mActivityTestRule.getActivity());
waitForView(withId(R.id.primary_tasks_surface_view), VIEW_GONE);
assertThat(mActivityTestRule.getActivity().getLayoutManager().getOverviewLayout(),
instanceOf(StackLayout.class));
OverviewModeBehaviorWatcher hideWatcher =
TabUiTestHelper.createOverviewHideWatcher(mActivityTestRule.getActivity());
// Simulate click roughly at the center of the screen so as to select the only tab.
TouchCommon.singleClickView(
mActivityTestRule.getActivity().getCompositorViewHolder().getCompositorView());
hideWatcher.waitForBehavior();
}
@Test
@MediumTest
@Feature({"StartSurface"})
@CommandLineFlags.Add({BASE_PARAMS + "/single"})
public void testSearchInSingleSurface() {
if (!mImmediateReturn) {
onView(withId(org.chromium.chrome.tab_ui.R.id.home_button)).perform(click());
}
CriteriaHelper.pollUiThread(
()
-> mActivityTestRule.getActivity().getLayoutManager() != null
&& mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
waitForTabModel();
assertThat(
mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel().getCount(),
equalTo(1));
OverviewModeBehaviorWatcher hideWatcher =
TabUiTestHelper.createOverviewHideWatcher(mActivityTestRule.getActivity());
onView(withId(R.id.search_box_text)).perform(replaceText(mUrl));
onView(withId(R.id.url_bar)).perform(pressKey(KeyEvent.KEYCODE_ENTER));
hideWatcher.waitForBehavior();
assertThat(
mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel().getCount(),
equalTo(2));
}
@Test
@MediumTest
@Feature({"StartSurface"})
@CommandLineFlags.Add({BASE_PARAMS + "/single"})
public void testSearchInIncognitoSingleSurface() {
if (!mImmediateReturn) {
onView(withId(org.chromium.chrome.tab_ui.R.id.home_button)).perform(click());
}
CriteriaHelper.pollUiThread(
()
-> mActivityTestRule.getActivity().getLayoutManager() != null
&& mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
waitForTabModel();
if (isInstantReturn()) {
// TODO(crbug/1076274): hide toolbar to make incognito switch visible.
TestThreadUtils.runOnUiThreadBlocking(() -> {
mActivityTestRule.getActivity().getTabModelSelector().selectModel(true);
});
} else {
onView(withId(R.id.incognito_switch)).perform(click());
}
assertTrue(mActivityTestRule.getActivity().getTabModelSelector().isIncognitoSelected());
OverviewModeBehaviorWatcher hideWatcher =
TabUiTestHelper.createOverviewHideWatcher(mActivityTestRule.getActivity());
onView(allOf(withId(R.id.search_box_text), isDisplayed())).perform(replaceText(mUrl));
onView(withId(R.id.url_bar)).perform(pressKey(KeyEvent.KEYCODE_ENTER));
hideWatcher.waitForBehavior();
assertThat(
mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel().getCount(),
equalTo(1));
}
@Test
@MediumTest
@Feature({"StartSurface"})
@CommandLineFlags.Add({BASE_PARAMS + "/single"})
public void testTapMVTilesInSingleSurface() {
if (!mImmediateReturn) {
onView(withId(org.chromium.chrome.tab_ui.R.id.home_button)).perform(click());
}
CriteriaHelper.pollUiThread(
()
-> mActivityTestRule.getActivity().getLayoutManager() != null
&& mActivityTestRule.getActivity().getLayoutManager().overviewVisible());
waitForTabModel();
assertThat(
mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel().getCount(),
equalTo(1));
ViewGroup mvTilesContainer = mActivityTestRule.getActivity().findViewById(
org.chromium.chrome.tab_ui.R.id.mv_tiles_layout);
assertTrue(mvTilesContainer.getChildCount() > 0);
OverviewModeBehaviorWatcher hideWatcher =
TabUiTestHelper.createOverviewHideWatcher(mActivityTestRule.getActivity());
try {
// TODO (crbug.com/1025296): Find a way to perform click on a child at index 0 in
// LinearLayout with Espresso. Note that we do not have 'withParentIndex' so far.
TestThreadUtils.runOnUiThreadBlocking(
() -> mvTilesContainer.getChildAt(0).performClick());
} catch (ExecutionException e) {
fail("Failed to click the first child " + e.toString());
}
hideWatcher.waitForBehavior();
assertThat(
mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel().getCount(),
equalTo(2));
if (isInstantReturn()) {
// TODO(crbug/1076274): fix toolbar to avoid wrongly focusing on the toolbar omnibox.
return;
}
// Press back button should close the tab opened from the Start surface.
OverviewModeBehaviorWatcher showWatcher =
TabUiTestHelper.createOverviewShowWatcher(mActivityTestRule.getActivity());
pressBack();
showWatcher.waitForBehavior();
assertThat(
mActivityTestRule.getActivity().getTabModelSelector().getCurrentModel().getCount(),
equalTo(1));
}
private void waitForTabModel() {
CriteriaHelper.pollUiThread(()
-> mActivityTestRule.getActivity()
.getTabModelSelector()
.getTabModelFilterProvider()
.getCurrentTabModelFilter()
!= null
&& mActivityTestRule.getActivity()
.getTabModelSelector()
.getTabModelFilterProvider()
.getCurrentTabModelFilter()
.isTabModelRestored());
}
}
// TODO(crbug.com/1033909): Add more integration tests.