chromium/chrome/test/android/javatests/src/org/chromium/chrome/test/transit/hub/NewTabGroupDialogFacility.java

// Copyright 2024 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.test.transit.hub;

import static androidx.test.espresso.action.ViewActions.replaceText;
import static androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom;
import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;

import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.startsWith;

import static org.chromium.base.test.transit.ViewSpec.viewSpec;

import android.content.Context;
import android.view.View;
import android.widget.EditText;

import androidx.annotation.Nullable;

import org.hamcrest.Matcher;

import org.chromium.base.test.transit.Elements;
import org.chromium.base.test.transit.Facility;
import org.chromium.base.test.transit.ViewElement;
import org.chromium.base.test.transit.ViewSpec;
import org.chromium.chrome.browser.tasks.tab_management.ColorPickerUtils;
import org.chromium.chrome.test.R;
import org.chromium.chrome.test.transit.tabmodel.TabGroupUtil;
import org.chromium.components.tab_groups.TabGroupColorId;
import org.chromium.ui.test.transit.SoftKeyboardElement;

import java.util.List;

/** Dialog that appears when a new tab group is created to name the group and pick a color. */
public class NewTabGroupDialogFacility extends Facility<TabSwitcherStation> {

    public static final ViewSpec DIALOG = viewSpec(withId(R.id.visual_data_dialog_layout));
    public static final ViewSpec DIALOG_TITLE =
            viewSpec(allOf(withId(R.id.visual_data_dialog_title), withText("New tab group")));

    public static final Matcher<View> TITLE_INPUT_MATCHER =
            allOf(withId(R.id.title_input_text), isAssignableFrom(EditText.class));
    public static final ViewSpec COLOR_PICKER_CONTAINER =
            viewSpec(withId(R.id.color_picker_container));

    public static final ViewSpec DONE_BUTTON = viewSpec(withId(R.id.positive_button));

    private final List<Integer> mTabIdsToGroup;
    private final String mTitle;
    private final @Nullable @TabGroupColorId Integer mSelectedColor;
    private ViewSpec mTitleInputSpec;

    /** Constructor. Expects no particular title or selected color. */
    public NewTabGroupDialogFacility(List<Integer> tabIdsToGroup) {
        this(
                tabIdsToGroup,
                TabGroupUtil.getNumberOfTabsString(tabIdsToGroup.size()),
                /* selectedColor= */ null);
    }

    /** Constructor. Expects a specific title and selected color. */
    public NewTabGroupDialogFacility(
            List<Integer> tabIdsToGroup,
            String title,
            @Nullable @TabGroupColorId Integer selectedColor) {
        mTabIdsToGroup = tabIdsToGroup;
        mTitle = title;
        mSelectedColor = selectedColor;
    }

    @Override
    public void declareElements(Elements.Builder elements) {
        elements.declareView(DIALOG);
        elements.declareView(DIALOG_TITLE);

        String inputElementId = "Tab group title input showing " + mTitle;
        mTitleInputSpec = viewSpec(allOf(TITLE_INPUT_MATCHER, withText(mTitle)));
        elements.declareView(mTitleInputSpec, ViewElement.elementIdOption(inputElementId));

        // TODO(crbug.com/345489175): Partially cut off in android_30_google_apis_x86.textpb
        elements.declareView(COLOR_PICKER_CONTAINER, ViewElement.displayingAtLeastOption(50));
        @TabGroupColorId List<Integer> colors = ColorPickerUtils.getTabGroupColorIdList();
        for (@TabGroupColorId Integer color : colors) {
            if (mSelectedColor != null) {
                elements.declareView(
                        colorPickerIconSpec(color, color.equals(mSelectedColor)),
                        ViewElement.unscopedOption());
            } else {
                elements.declareView(
                        colorPickerIconSpec(color, /* selected= */ null),
                        ViewElement.unscopedOption());
            }
        }

        elements.declareView(DONE_BUTTON);

        elements.declareElement(new SoftKeyboardElement(mHostStation.getActivitySupplier()));
    }

    private ViewSpec colorPickerIconSpec(
            @TabGroupColorId Integer color, @Nullable Boolean selected) {
        Context context = mHostStation.getActivity();
        String colorName =
                context.getString(
                        ColorPickerUtils.getTabGroupColorPickerItemColorAccessibilityString(color));
        Matcher<View> contentDescriptionMatcher;
        if (selected != null) {
            contentDescriptionMatcher =
                    withContentDescription(
                            colorName + " " + (selected ? "Selected" : "Not selected"));
        } else {
            contentDescriptionMatcher = withContentDescription(startsWith(colorName));
        }
        return viewSpec(allOf(withId(R.id.color_picker_icon), contentDescriptionMatcher));
    }

    /** Input a new tab group name. */
    public NewTabGroupDialogFacility inputName(String newTabGroupName) {
        return mHostStation.swapFacilitySync(
                this,
                new NewTabGroupDialogFacility(mTabIdsToGroup, newTabGroupName, mSelectedColor),
                () -> mTitleInputSpec.perform(replaceText(newTabGroupName)));
    }

    /** Select a color. */
    public NewTabGroupDialogFacility pickColor(@TabGroupColorId int newColor) {
        return mHostStation.swapFacilitySync(
                this,
                new NewTabGroupDialogFacility(mTabIdsToGroup, mTitle, newColor),
                colorPickerIconSpec(newColor, /* selected= */ false)::click);
    }

    /** Press "Done" to confirm the tab group name and color. */
    public TabSwitcherGroupCardFacility pressDone() {
        return mHostStation.swapFacilitySync(
                this, new TabSwitcherGroupCardFacility(mTabIdsToGroup, mTitle), DONE_BUTTON::click);
    }
}