blob: 7168469943acc281055e49508076703fed010759 [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// 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.recent_tabs;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static org.chromium.chrome.browser.recent_tabs.RestoreTabsProperties.CURRENT_SCREEN;
import static org.chromium.chrome.browser.recent_tabs.RestoreTabsProperties.DEVICE_MODEL_LIST;
import static org.chromium.chrome.browser.recent_tabs.RestoreTabsProperties.SELECTED_DEVICE;
import static org.chromium.chrome.browser.recent_tabs.RestoreTabsProperties.ScreenType.HOME_SCREEN;
import android.app.Activity;
import android.view.View;
import android.widget.FrameLayout;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.test.filters.MediumTest;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.chromium.base.test.BaseActivityTestRule;
import org.chromium.base.test.params.ParameterAnnotations;
import org.chromium.base.test.params.ParameterSet;
import org.chromium.base.test.params.ParameterizedRunner;
import org.chromium.base.test.util.DoNotBatch;
import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.JniMocker;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.recent_tabs.ForeignSessionHelper.ForeignSession;
import org.chromium.chrome.browser.recent_tabs.ForeignSessionHelper.ForeignSessionTab;
import org.chromium.chrome.browser.recent_tabs.RestoreTabsProperties.DetailItemType;
import org.chromium.chrome.browser.recent_tabs.ui.ForeignSessionItemProperties;
import org.chromium.chrome.browser.recent_tabs.ui.TabItemProperties;
import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
import org.chromium.chrome.test.util.ChromeRenderTestRule;
import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
import org.chromium.components.sync_device_info.FormFactor;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
import org.chromium.ui.modelutil.MVCListAdapter.ListItem;
import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
import org.chromium.ui.modelutil.PropertyModel;
import org.chromium.ui.test.util.BlankUiTestActivity;
import org.chromium.ui.test.util.DisableAnimationsTestRule;
import org.chromium.ui.test.util.NightModeTestUtils;
import org.chromium.ui.test.util.RenderTestRule;
import org.chromium.ui.test.util.ViewUtils;
import org.chromium.url.JUnitTestGURLs;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/** Render tests for Restore Tabs UI elements */
@RunWith(ParameterizedRunner.class)
@ParameterAnnotations.UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class)
@DoNotBatch(reason = "RestoreTabs tests different startup behaviours and shouldn't be batched.")
public class RestoreTabsUiRenderTest {
@ParameterAnnotations.ClassParameter
public static List<ParameterSet> sClassParams =
new NightModeTestUtils.NightModeParams().getParameters();
@Rule
public final ChromeRenderTestRule mRenderTestRule =
ChromeRenderTestRule.Builder.withPublicCorpus()
.setBugComponent(RenderTestRule.Component.UI_BROWSER_MOBILE_RECENT_TABS)
.setRevision(1)
.build();
@Rule
public BaseActivityTestRule<BlankUiTestActivity> mActivityTestRule =
new BaseActivityTestRule<>(BlankUiTestActivity.class);
@Rule
public JniMocker jniMocker = new JniMocker();
@Rule
public final DisableAnimationsTestRule mDisableAnimationsRule = new DisableAnimationsTestRule();
@Mock
ForeignSessionHelper.Natives mForeignSessionHelperJniMock;
@Mock
private Profile mProfile;
@Mock
private RestoreTabsControllerFactory.ControllerListener mListener;
@Mock
private TabCreatorManager mTabCreatorManager;
@Mock
private BottomSheetController mBottomSheetController;
private RestoreTabsCoordinator mCoordinator;
private View mView;
private PropertyModel mModel;
private FrameLayout mRootView;
public RestoreTabsUiRenderTest(boolean nightModeEnabled) {
NightModeTestUtils.setUpNightModeForBlankUiTestActivity(nightModeEnabled);
mRenderTestRule.setNightModeEnabled(nightModeEnabled);
}
@Before
public void setUp() throws InterruptedException {
MockitoAnnotations.initMocks(this);
Profile.setLastUsedProfileForTesting(mProfile);
jniMocker.mock(ForeignSessionHelperJni.TEST_HOOKS, mForeignSessionHelperJniMock);
mActivityTestRule.launchActivity(null);
TestThreadUtils.runOnUiThreadBlocking(() -> {
Activity activity = mActivityTestRule.getActivity();
mCoordinator = new RestoreTabsCoordinator(mActivityTestRule.getActivity(), mProfile,
mListener, mTabCreatorManager, mBottomSheetController);
mView = mCoordinator.getContentViewForTesting();
mView.setBackground(
AppCompatResources.getDrawable(activity, R.drawable.menu_bg_tinted));
mModel = mCoordinator.getPropertyModelForTesting();
mRootView = new FrameLayout(activity);
activity.setContentView(mRootView);
mRootView.addView(mView);
});
}
@After
public void tearDownTest() throws Exception {
TestThreadUtils.runOnUiThreadBlocking(
() -> NightModeTestUtils.tearDownNightModeForBlankUiTestActivity());
}
@Test
@MediumTest
@Feature("RenderTest")
public void testPromoScreenSheet() throws IOException, InterruptedException {
TestThreadUtils.runOnUiThreadBlocking(() -> {
// 0 devices in DEVICE_MODEL_LIST and 1 selected tab in REVIEW_TABS_MODEL_LIST.
// Restore tabs button enabled and chevron/onClickListener for device view.
ForeignSessionTab tab = new ForeignSessionTab(
JUnitTestGURLs.getGURL(JUnitTestGURLs.URL_1), "title", 32L, 0);
ForeignSession session = new ForeignSession(
"tag", "John's iPhone 6", 32L, new ArrayList<>(), FormFactor.PHONE);
ModelList tabItems = mModel.get(RestoreTabsProperties.REVIEW_TABS_MODEL_LIST);
tabItems.clear();
PropertyModel model = TabItemProperties.create(/*tab=*/tab, /*isSelected=*/true);
model.set(TabItemProperties.ON_CLICK_LISTENER, () -> {});
tabItems.add(new ListItem(DetailItemType.TAB, model));
mModel.set(SELECTED_DEVICE, session);
mModel.set(CURRENT_SCREEN, HOME_SCREEN);
});
ViewUtils.waitForView(mRootView, withId(R.id.restore_tabs_promo_screen_sheet));
Thread.sleep(2000);
mRenderTestRule.render(mRootView, "restore_tabs_promo_screen_all_enabled");
}
@Test
@MediumTest
@Feature("RenderTest")
public void testPromoScreenSheet_disabledDeviceViewAndRestoreButtonWithTabletIcon()
throws IOException, InterruptedException {
TestThreadUtils.runOnUiThreadBlocking(() -> {
// 1 device in DEVICE_MODEL_LIST and 0 selected tabs in REVIEW_TABS_MODEL_LIST.
// Restore tabs button disabled, tablet icon and no chevron/onClickListener for device
// view.
ForeignSession session = new ForeignSession(
"tag", "John's iPhone 6", 32L, new ArrayList<>(), FormFactor.TABLET);
ModelList sessionItems = mModel.get(DEVICE_MODEL_LIST);
sessionItems.clear();
PropertyModel model = ForeignSessionItemProperties.create(
/*session=*/session, /*isSelected=*/false, /*onClickListener=*/() -> {});
sessionItems.add(new ListItem(DetailItemType.DEVICE, model));
mModel.set(SELECTED_DEVICE, session);
mModel.set(CURRENT_SCREEN, HOME_SCREEN);
});
ViewUtils.waitForView(mRootView, withId(R.id.restore_tabs_promo_screen_sheet));
Thread.sleep(2000);
mRenderTestRule.render(mRootView, "restore_tabs_promo_screen_disabled_elements");
}
@Test
@MediumTest
@Feature("RenderTest")
public void testDeviceScreenSheet_twoItemDecorationAndSelection()
throws IOException, InterruptedException {
TestThreadUtils.runOnUiThreadBlocking(() -> {
ForeignSession session1 = new ForeignSession(
"tag1", "John's iPhone 6", 32L, new ArrayList<>(), FormFactor.PHONE);
ForeignSession session2 = new ForeignSession(
"tag2", "John's iPhone 7", 33L, new ArrayList<>(), FormFactor.PHONE);
List<ForeignSession> sessions = new ArrayList<>();
sessions.add(session1);
sessions.add(session2);
ModelList sessionItems = mModel.get(DEVICE_MODEL_LIST);
sessionItems.clear();
for (ForeignSession session : sessions) {
PropertyModel model = ForeignSessionItemProperties.create(
/*session=*/session, /*isSelected=*/true, /*onClickListener=*/() -> {});
sessionItems.add(new ListItem(DetailItemType.DEVICE, model));
}
mModel.set(CURRENT_SCREEN, HOME_SCREEN);
mView.findViewById(R.id.restore_tabs_selected_device_view).performClick();
});
ViewUtils.waitForView(mRootView, withId(R.id.restore_tabs_detail_screen_sheet));
Thread.sleep(2000);
mRenderTestRule.render(mRootView, "restore_tabs_detail_screen_two_item_decoration");
}
@Test
@MediumTest
@Feature("RenderTest")
public void testDeviceScreenSheet_threeItemDecorationAndTablet()
throws IOException, InterruptedException {
TestThreadUtils.runOnUiThreadBlocking(() -> {
ForeignSession session1 = new ForeignSession(
"tag1", "John's iPhone 6", 32L, new ArrayList<>(), FormFactor.PHONE);
ForeignSession session2 = new ForeignSession(
"tag2", "John's iPhone 7", 33L, new ArrayList<>(), FormFactor.PHONE);
ForeignSession session3 = new ForeignSession(
"tag3", "John's iPad Air", 34L, new ArrayList<>(), FormFactor.TABLET);
List<ForeignSession> sessions = new ArrayList<>();
sessions.add(session1);
sessions.add(session2);
sessions.add(session3);
ModelList sessionItems = mModel.get(DEVICE_MODEL_LIST);
sessionItems.clear();
for (ForeignSession session : sessions) {
PropertyModel model = ForeignSessionItemProperties.create(
/*session=*/session, /*isSelected=*/false, /*onClickListener=*/() -> {});
sessionItems.add(new ListItem(DetailItemType.DEVICE, model));
}
mModel.set(CURRENT_SCREEN, HOME_SCREEN);
mView.findViewById(R.id.restore_tabs_selected_device_view).performClick();
});
ViewUtils.waitForView(mRootView, withId(R.id.restore_tabs_detail_screen_sheet));
Thread.sleep(2000);
mRenderTestRule.render(mRootView, "restore_tabs_detail_screen_three_item_decoration");
}
}