Commit 885cf1f6 authored by Michael Thiessen's avatar Michael Thiessen Committed by Commit Bot

Batch device_dialog tests together

Introduces BlankCTATabInitialState.java, which manages initial state
across test suites. No post-batch cleanup is required as the only state
carried across test suites is the Activity, which is finished by the
test runner.

Also batches all device_dialog instrumentation tests together,
dramatically speeding them up.

Bug: 989569
Change-Id: I66fa56da157491defe1dca9b4ce9464a3d308961
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2307650Reviewed-by: default avatarYaron Friedman <yfriedman@chromium.org>
Commit-Queue: Michael Thiessen <mthiesse@chromium.org>
Cr-Commit-Position: refs/heads/master@{#792242}
parent 21e6c4e1
......@@ -9,15 +9,17 @@ import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import androidx.test.filters.LargeTest;
import androidx.test.filters.SmallTest;
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.chromium.base.test.util.Batch;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.JniMocker;
import org.chromium.chrome.R;
......@@ -25,6 +27,7 @@ import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.flags.ChromeSwitches;
import org.chromium.chrome.test.ChromeActivityTestRule;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.batch.BlankCTATabInitialStateRule;
import org.chromium.components.security_state.ConnectionSecurityLevel;
import org.chromium.content_public.browser.bluetooth_scanning.Event;
import org.chromium.content_public.browser.test.util.Criteria;
......@@ -37,11 +40,16 @@ import org.chromium.ui.base.ActivityWindowAndroid;
*/
@RunWith(ChromeJUnit4ClassRunner.class)
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
@Batch(BluetoothChooserDialogTest.DEVICE_DIALOG_BATCH_NAME)
public class BluetoothScanningPermissionDialogTest {
@Rule
public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
@ClassRule
public static final ChromeActivityTestRule<ChromeActivity> sActivityTestRule =
new ChromeActivityTestRule<>(ChromeActivity.class);
@Rule
public final BlankCTATabInitialStateRule mInitialStateRule =
new BlankCTATabInitialStateRule(sActivityTestRule, false);
@Rule
public JniMocker mocker = new JniMocker();
......@@ -62,13 +70,12 @@ public class BluetoothScanningPermissionDialogTest {
public void setUp() throws Exception {
mocker.mock(BluetoothScanningPermissionDialogJni.TEST_HOOKS,
new TestBluetoothScanningPermissionDialogJni());
mActivityTestRule.startMainActivityOnBlankPage();
mPermissionDialog = createDialog();
}
private BluetoothScanningPermissionDialog createDialog() {
return TestThreadUtils.runOnUiThreadBlockingNoException(() -> {
mWindowAndroid = mActivityTestRule.getActivity().getWindowAndroid();
mWindowAndroid = sActivityTestRule.getActivity().getWindowAndroid();
BluetoothScanningPermissionDialog dialog = new BluetoothScanningPermissionDialog(
mWindowAndroid, "https://origin.example.com/", ConnectionSecurityLevel.SECURE,
/*nativeBluetoothScanningPermissionDialogPtr=*/42);
......@@ -77,7 +84,7 @@ public class BluetoothScanningPermissionDialogTest {
}
@Test
@LargeTest
@SmallTest
public void testAddDevice() {
Dialog dialog = mPermissionDialog.getDialogForTesting();
......@@ -117,7 +124,7 @@ public class BluetoothScanningPermissionDialogTest {
}
@Test
@LargeTest
@SmallTest
public void testCancelPermissionDialogWithoutClickingAnyButton() {
Dialog dialog = mPermissionDialog.getDialogForTesting();
......
......@@ -9,15 +9,17 @@ import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import androidx.test.filters.LargeTest;
import androidx.test.filters.SmallTest;
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.chromium.base.test.util.Batch;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.JniMocker;
import org.chromium.chrome.R;
......@@ -25,6 +27,7 @@ import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.flags.ChromeSwitches;
import org.chromium.chrome.test.ChromeActivityTestRule;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.batch.BlankCTATabInitialStateRule;
import org.chromium.components.security_state.ConnectionSecurityLevel;
import org.chromium.content_public.browser.test.util.Criteria;
import org.chromium.content_public.browser.test.util.CriteriaHelper;
......@@ -37,11 +40,16 @@ import org.chromium.ui.widget.TextViewWithClickableSpans;
*/
@RunWith(ChromeJUnit4ClassRunner.class)
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
@Batch(BluetoothChooserDialogTest.DEVICE_DIALOG_BATCH_NAME)
public class UsbChooserDialogTest {
@Rule
public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
@ClassRule
public static final ChromeActivityTestRule<ChromeActivity> sActivityTestRule =
new ChromeActivityTestRule<>(ChromeActivity.class);
@Rule
public final BlankCTATabInitialStateRule mInitialStateRule =
new BlankCTATabInitialStateRule(sActivityTestRule, false);
@Rule
public JniMocker mocker = new JniMocker();
......@@ -65,14 +73,13 @@ public class UsbChooserDialogTest {
@Before
public void setUp() throws Exception {
mocker.mock(UsbChooserDialogJni.TEST_HOOKS, new TestUsbChooserDialogJni());
mActivityTestRule.startMainActivityOnBlankPage();
mChooserDialog = createDialog();
}
private UsbChooserDialog createDialog() {
return TestThreadUtils.runOnUiThreadBlockingNoException(() -> {
UsbChooserDialog dialog = new UsbChooserDialog(/*nativeUsbChooserDialogPtr=*/42);
dialog.show(mActivityTestRule.getActivity(), "https://origin.example.com/",
dialog.show(sActivityTestRule.getActivity(), "https://origin.example.com/",
ConnectionSecurityLevel.SECURE);
return dialog;
});
......@@ -110,7 +117,7 @@ public class UsbChooserDialogTest {
}
@Test
@LargeTest
@SmallTest
public void testCancel() {
Dialog dialog = mChooserDialog.mItemChooserDialog.getDialogForTesting();
Assert.assertTrue(dialog.isShowing());
......@@ -129,7 +136,7 @@ public class UsbChooserDialogTest {
}
@Test
@LargeTest
@SmallTest
public void testSelectItem() {
Dialog dialog = mChooserDialog.mItemChooserDialog.getDialogForTesting();
......@@ -151,7 +158,7 @@ public class UsbChooserDialogTest {
// After adding items to the dialog, the help message should be showing,
// the 'Connect' button should still be disabled (since nothing's selected),
// and the list view should show.
Assert.assertEquals(removeLinkTags(mActivityTestRule.getActivity().getString(
Assert.assertEquals(removeLinkTags(sActivityTestRule.getActivity().getString(
R.string.usb_chooser_dialog_footnote_text)),
statusView.getText().toString());
Assert.assertFalse(button.isEnabled());
......
......@@ -193,6 +193,7 @@ android_library("chrome_java_test_support") {
"javatests/src/org/chromium/chrome/test/MultiActivityTestRule.java",
"javatests/src/org/chromium/chrome/test/ReducedModeNativeTestRule.java",
"javatests/src/org/chromium/chrome/test/TestContentProvider.java",
"javatests/src/org/chromium/chrome/test/batch/BlankCTATabInitialStateRule.java",
"javatests/src/org/chromium/chrome/test/gcore/MockChromeGoogleApiClient.java",
"javatests/src/org/chromium/chrome/test/invalidation/IntentSavingContext.java",
"javatests/src/org/chromium/chrome/test/omaha/AttributeFinder.java",
......
// Copyright 2020 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.test.batch;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.chromium.base.test.util.Batch;
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.firstrun.FirstRunStatus;
import org.chromium.chrome.browser.tab.TabLaunchType;
import org.chromium.chrome.browser.tabmodel.TabModelUtils;
import org.chromium.chrome.test.ChromeActivityTestRule;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
/**
* To be used by batched tests that would like to reset to a single blank tab open in
* ChromeTabbedActivity between each test, without restarting the Activity.
*
* State is stored statically, and so the Activity may be reused across multiple test suites within
* the same {@link Batch}.
*/
public class BlankCTATabInitialStateRule implements TestRule {
private static ChromeActivity sActivity;
private final ChromeActivityTestRule<ChromeActivity> mActivityTestRule;
private final boolean mClearAllTabState;
/**
* @param activityTestRule The ActivityTestRule to be reset to initial state between each test.
* @param clearAllTabState More thoroughly clears all tab state, at the cost of restarting the
* renderer process between each test.
*/
public BlankCTATabInitialStateRule(
ChromeActivityTestRule<ChromeActivity> activityTestRule, boolean clearAllTabState) {
super();
mActivityTestRule = activityTestRule;
mClearAllTabState = clearAllTabState;
}
@Override
public Statement apply(Statement base, Description description) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
if (sActivity == null) {
TestThreadUtils.runOnUiThreadBlocking(
() -> { FirstRunStatus.setFirstRunFlowComplete(true); });
mActivityTestRule.startMainActivityOnBlankPage();
sActivity = mActivityTestRule.getActivity();
} else {
mActivityTestRule.setActivity(sActivity);
if (mClearAllTabState) {
resetTabStateThorough();
} else {
resetTabStateFast();
}
}
base.evaluate();
}
};
}
// Avoids closing the primary tab (and killing the renderer) in order to reset tab state
// quickly, at the cost of thoroughness. This should be adequate for most tests.
private void resetTabStateFast() {
TestThreadUtils.runOnUiThreadBlocking(() -> {
// Close all but the first tab as these tests expect to start with a single
// tab.
while (TabModelUtils.closeTabByIndex(sActivity.getCurrentTabModel(), 1)) {
}
});
mActivityTestRule.loadUrl("about:blank");
TestThreadUtils.runOnUiThreadBlocking(() -> {
sActivity.getCurrentWebContents().getNavigationController().clearHistory();
});
}
// Thoroughly resets tab state by closing all tabs before restoring the primary tab to
// about:blank state.
private void resetTabStateThorough() {
TestThreadUtils.runOnUiThreadBlocking(() -> {
sActivity.getTabModelSelector().closeAllTabs();
sActivity.getTabCreator(false).launchUrl("about:blank", TabLaunchType.FROM_CHROME_UI);
});
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment