chromium/content/public/android/javatests/src/org/chromium/content/browser/input/SelectPopupTest.java

// Copyright 2012 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.content.browser.input;

import androidx.test.InstrumentationRegistry;
import androidx.test.filters.LargeTest;

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

import org.chromium.base.test.BaseJUnit4ClassRunner;
import org.chromium.base.test.util.Criteria;
import org.chromium.base.test.util.CriteriaHelper;
import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.UrlUtils;
import org.chromium.content_public.browser.WebContents;
import org.chromium.content_public.browser.test.util.DOMUtils;
import org.chromium.content_public.browser.test.util.TestCallbackHelperContainer;
import org.chromium.content_public.browser.test.util.TestCallbackHelperContainer.OnPageFinishedHelper;
import org.chromium.content_shell_apk.ContentShellActivityTestRule;
import org.chromium.content_shell_apk.ContentShellActivityTestRule.RerunWithUpdatedContainerView;

import java.util.concurrent.TimeUnit;

/** Integration Tests for SelectPopup. */
@RunWith(BaseJUnit4ClassRunner.class)
public class SelectPopupTest {
    @Rule
    public ContentShellActivityTestRule mActivityTestRule = new ContentShellActivityTestRule();

    private static final long WAIT_TIMEOUT_SECONDS = 2L;
    private static final String SELECT_URL =
            UrlUtils.encodeHtmlDataUri(
                    "<html><head><meta name=\"viewport\"content=\"width=device-width,"
                            + " initial-scale=1.0, maximum-scale=1.0\" /></head><body>Which animal is"
                            + " the strongest:<br/><select id=\"select\"><option>Black"
                            + " bear</option><option>Polar bear</option><option>Grizzly</option>"
                            + "<option>Tiger</option><option>Lion</option><option>Gorilla</option>"
                            + "<option>Chipmunk</option></select></body></html>");

    private void verifyPopupShownState(boolean shown) {
        CriteriaHelper.pollUiThread(
                () -> {
                    Criteria.checkThat(
                            mActivityTestRule.getSelectPopup().isVisibleForTesting(),
                            Matchers.is(shown));
                });
    }

    @Before
    public void setUp() {
        mActivityTestRule.launchContentShellWithUrl(SELECT_URL);
        mActivityTestRule.waitForActiveShellToBeDoneLoading();
    }

    /**
     * Tests that showing a select popup and having the page reload while the popup is showing does
     * not assert.
     */
    @Test
    @LargeTest
    @Feature({"Browser"})
    @RerunWithUpdatedContainerView
    public void testReloadWhilePopupShowing() throws Exception, Throwable {
        // The popup should be hidden before the click.
        verifyPopupShownState(false);

        final WebContents webContents = mActivityTestRule.getWebContents();
        final TestCallbackHelperContainer viewClient = new TestCallbackHelperContainer(webContents);
        final OnPageFinishedHelper onPageFinishedHelper = viewClient.getOnPageFinishedHelper();

        // Once clicked, the popup should show up.
        DOMUtils.clickNode(webContents, "select");
        verifyPopupShownState(true);

        // Reload the test page.
        int currentCallCount = onPageFinishedHelper.getCallCount();

        InstrumentationRegistry.getInstrumentation()
                .runOnMainSync(
                        () -> {
                            // Now reload the page while the popup is showing, it gets hidden.
                            mActivityTestRule
                                    .getWebContents()
                                    .getNavigationController()
                                    .reload(true);
                        });
        onPageFinishedHelper.waitForCallback(
                currentCallCount, 1, WAIT_TIMEOUT_SECONDS, TimeUnit.SECONDS);

        // The popup should be hidden after the page reload.
        verifyPopupShownState(false);

        // Click the select and wait for the popup to show.
        DOMUtils.clickNode(webContents, "select");
        verifyPopupShownState(true);
    }
}