Commit 59700399 authored by Rohit Agarwal's avatar Rohit Agarwal Committed by Commit Bot

Add browser tests for cookies leak check across all activity types.

We currently don't have extensive tests on java side which checks
any leakage of data across activities.

This CL adds browser tests to check cookies leaks involving both
Tabbed and CCT activities for both regular and incognito mode.

Bug: 1035770
Change-Id: Iba3481d51923c0a30ec38646b25614db36549bdb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2054109
Commit-Queue: Rohit Agarwal <roagarwal@chromium.org>
Reviewed-by: default avatarRamin Halavati <rhalavati@chromium.org>
Reviewed-by: default avatarPeter Conn <peconn@chromium.org>
Cr-Commit-Position: refs/heads/master@{#748143}
parent 8d5a1973
...@@ -202,6 +202,8 @@ chrome_test_java_sources = [ ...@@ -202,6 +202,8 @@ chrome_test_java_sources = [
"javatests/src/org/chromium/chrome/browser/identity/SettingsSecureBasedIdentificationGeneratorTest.java", "javatests/src/org/chromium/chrome/browser/identity/SettingsSecureBasedIdentificationGeneratorTest.java",
"javatests/src/org/chromium/chrome/browser/identity/UniqueIdentificationGeneratorFactoryTest.java", "javatests/src/org/chromium/chrome/browser/identity/UniqueIdentificationGeneratorFactoryTest.java",
"javatests/src/org/chromium/chrome/browser/identity/UuidBasedUniqueIdentificationGeneratorTest.java", "javatests/src/org/chromium/chrome/browser/identity/UuidBasedUniqueIdentificationGeneratorTest.java",
"javatests/src/org/chromium/chrome/browser/incognito/IncognitoCookieLeakageTest.java",
"javatests/src/org/chromium/chrome/browser/incognito/IncognitoDataTestUtils.java",
"javatests/src/org/chromium/chrome/browser/incognito/IncognitoNotificationServiceTest.java", "javatests/src/org/chromium/chrome/browser/incognito/IncognitoNotificationServiceTest.java",
"javatests/src/org/chromium/chrome/browser/incognito/IncognitoTabLauncherTest.java", "javatests/src/org/chromium/chrome/browser/incognito/IncognitoTabLauncherTest.java",
"javatests/src/org/chromium/chrome/browser/infobar/InfoBarAppearanceTest.java", "javatests/src/org/chromium/chrome/browser/infobar/InfoBarAppearanceTest.java",
......
...@@ -29,19 +29,40 @@ import java.util.concurrent.TimeoutException; ...@@ -29,19 +29,40 @@ import java.util.concurrent.TimeoutException;
public class CustomTabActivityTestRule extends ChromeActivityTestRule<CustomTabActivity> { public class CustomTabActivityTestRule extends ChromeActivityTestRule<CustomTabActivity> {
protected static final long STARTUP_TIMEOUT_MS = 5L * 1000; protected static final long STARTUP_TIMEOUT_MS = 5L * 1000;
protected static final long LONG_TIMEOUT_MS = 10L * 1000; protected static final long LONG_TIMEOUT_MS = 10L * 1000;
private static int sCustomTabId;
public CustomTabActivityTestRule() { public CustomTabActivityTestRule() {
super(CustomTabActivity.class); super(CustomTabActivity.class);
} }
public static void putCustomTabIdInIntent(Intent intent) {
boolean hasCustomTabId = intent.hasExtra(CustomTabsTestUtils.EXTRA_CUSTOM_TAB_ID);
// Intent already has a custom tab id assigned to it and we should reuse the same activity.
// Test relying on sending the same intent relies on using the same activity.
if (hasCustomTabId) return;
intent.putExtra(CustomTabsTestUtils.EXTRA_CUSTOM_TAB_ID, sCustomTabId++);
}
public static int getCustomTabIdFromIntent(Intent intent) {
return intent.getIntExtra(CustomTabsTestUtils.EXTRA_CUSTOM_TAB_ID, -1);
}
@Override @Override
public void startActivityCompletely(Intent intent) { public void startActivityCompletely(Intent intent) {
putCustomTabIdInIntent(intent);
int currentIntentId = getCustomTabIdFromIntent(intent);
Activity activity = InstrumentationRegistry.getInstrumentation().startActivitySync(intent); Activity activity = InstrumentationRegistry.getInstrumentation().startActivitySync(intent);
Assert.assertNotNull("Main activity did not start", activity); Assert.assertNotNull("Main activity did not start", activity);
CriteriaHelper.pollUiThread(() -> { CriteriaHelper.pollUiThread(() -> {
for (Activity runningActivity : ApplicationStatus.getRunningActivities()) { for (Activity runningActivity : ApplicationStatus.getRunningActivities()) {
if (runningActivity instanceof CustomTabActivity) { if (runningActivity instanceof CustomTabActivity) {
setActivity((CustomTabActivity) runningActivity); CustomTabActivity customTabActivity = (CustomTabActivity) runningActivity;
final int customTabIdInActivity =
getCustomTabIdFromIntent(customTabActivity.getIntent());
if (currentIntentId != customTabIdInActivity) continue;
setActivity(customTabActivity);
return true; return true;
} }
} }
......
...@@ -35,6 +35,9 @@ import androidx.browser.customtabs.CustomTabsSession; ...@@ -35,6 +35,9 @@ import androidx.browser.customtabs.CustomTabsSession;
* Utility class that contains convenience calls related with custom tabs testing. * Utility class that contains convenience calls related with custom tabs testing.
*/ */
public class CustomTabsTestUtils { public class CustomTabsTestUtils {
/** Intent extra to specify an id to a custom tab.*/
public static final String EXTRA_CUSTOM_TAB_ID =
"android.support.customtabs.extra.tests.CUSTOM_TAB_ID";
/** A plain old data class that holds the return value from {@link #bindWithCallback}. */ /** A plain old data class that holds the return value from {@link #bindWithCallback}. */
public static class ClientAndSession { public static class ClientAndSession {
......
// 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.browser.incognito;
import static org.junit.Assert.assertEquals;
import android.os.Build;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.LargeTest;
import org.junit.After;
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.library_loader.LibraryLoader;
import org.chromium.base.test.params.ParameterAnnotations.ClassParameter;
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.DisableIf;
import org.chromium.base.test.util.RetryOnFailure;
import org.chromium.chrome.browser.ChromeTabbedActivity;
import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
import org.chromium.chrome.browser.firstrun.FirstRunStatus;
import org.chromium.chrome.browser.flags.ChromeFeatureList;
import org.chromium.chrome.browser.incognito.IncognitoDataTestUtils.ActivityType;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.test.ChromeActivityTestRule;
import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
import org.chromium.chrome.test.util.browser.Features;
import org.chromium.content_public.browser.test.util.JavaScriptUtils;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
import org.chromium.net.test.EmbeddedTestServer;
import java.util.List;
import java.util.concurrent.TimeoutException;
/**
* This test class checks cookie leakage between all different
* pairs of Activity types with a constraint that one of the
* interacting activity must be either Incognito Tab or Incognito CCT.
*/
@RunWith(ParameterizedRunner.class)
@UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class)
@Features.EnableFeatures({ChromeFeatureList.CCT_INCOGNITO})
public class IncognitoCookieLeakageTest {
private String mCookiesTestPage;
private EmbeddedTestServer mTestServer;
private ActivityType mActivity1;
private ActivityType mActivity2;
private static final String COOKIES_SETTING_PATH = "/chrome/test/data/android/cookie.html";
@ClassParameter
private static List<ParameterSet> sClassParams =
new IncognitoDataTestUtils.TestParams().getParameters();
@Rule
public ChromeActivityTestRule<ChromeTabbedActivity> mChromeActivityTestRule =
new ChromeActivityTestRule<>(ChromeTabbedActivity.class);
@Rule
public CustomTabActivityTestRule mCustomTabActivityTestRule = new CustomTabActivityTestRule();
@Rule
public TestRule mProcessor = new Features.InstrumentationProcessor();
public IncognitoCookieLeakageTest(String activityType1, String activityType2) {
mActivity1 = IncognitoDataTestUtils.ActivityType.valueOf(activityType1);
mActivity2 = IncognitoDataTestUtils.ActivityType.valueOf(activityType2);
}
@Before
public void setUp() throws Exception {
TestThreadUtils.runOnUiThreadBlocking(
() -> { FirstRunStatus.setFirstRunFlowComplete(true); });
mTestServer = EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext());
mCookiesTestPage = mTestServer.getURL(COOKIES_SETTING_PATH);
mChromeActivityTestRule.startMainActivityOnBlankPage();
LibraryLoader.getInstance().ensureInitialized();
}
@After
public void tearDown() {
TestThreadUtils.runOnUiThreadBlocking(
() -> { IncognitoDataTestUtils.closeTabs(mChromeActivityTestRule); });
IncognitoDataTestUtils.finishActivities();
TestThreadUtils.runOnUiThreadBlocking(
() -> { FirstRunStatus.setFirstRunFlowComplete(false); });
mTestServer.stopAndDestroyServer();
}
// TODO(crbug.com/1023759) : We currently don't have proper incognito CCT profile isolation,
// when we do we need to update this.
private String getExpectedString() {
if (mActivity1.incognito == mActivity2.incognito) return "\"Foo=Bar\"";
return "\"\"";
}
private void setCookies(Tab tab) throws TimeoutException {
JavaScriptUtils.executeJavaScriptAndWaitForResult(tab.getWebContents(), "setCookie()");
assertCookies(tab, "\"Foo=Bar\"");
}
private void assertCookies(Tab tab, String expected) throws TimeoutException {
String actual = JavaScriptUtils.executeJavaScriptAndWaitForResult(
tab.getWebContents(), "getCookie()");
if (actual.equalsIgnoreCase("null")) actual = "\"\"";
assertEquals(expected, actual);
}
@Test
@LargeTest
@RetryOnFailure
@DisableIf.Build(sdk_is_less_than = Build.VERSION_CODES.LOLLIPOP,
message = "TODO(crbug.com/1023759): The test is disabled in Android Kitkat because of "
+ "incognito cct flakiness.")
public void
testCookiesLeak() throws TimeoutException {
Tab setter_tab = mActivity1.launchUrl(
mChromeActivityTestRule, mCustomTabActivityTestRule, mCookiesTestPage);
setCookies(setter_tab);
Tab getter_tab = mActivity2.launchUrl(
mChromeActivityTestRule, mCustomTabActivityTestRule, mCookiesTestPage);
assertCookies(getter_tab, getExpectedString());
}
}
// 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.browser.incognito;
import static org.junit.Assert.assertEquals;
import android.app.Activity;
import android.content.Intent;
import android.support.test.InstrumentationRegistry;
import org.chromium.base.ApplicationStatus;
import org.chromium.base.test.params.ParameterProvider;
import org.chromium.base.test.params.ParameterSet;
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.IntentHandler;
import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.test.ChromeActivityTestRule;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeoutException;
/**
* This class provides helper methods for launching any Urls in CCT or Tabs.
* This also provides parameters for tests. Parameters include pair of activity types.
*
*/
public class IncognitoDataTestUtils {
public static enum ActivityType {
INCOGNITO_TAB(true, false),
INCOGNITO_CCT(true, true),
REGULAR_TAB(false, false),
REGULAR_CCT(false, true);
public final boolean incognito;
public final boolean cct;
public Tab launchUrl(ChromeActivityTestRule chromeActivityRule,
CustomTabActivityTestRule customTabActivityTestRule, String url)
throws TimeoutException {
if (cct) {
return launchUrlInCCT(customTabActivityTestRule, url, incognito);
} else {
return launchUrlInTab(chromeActivityRule, url, incognito);
}
}
ActivityType(boolean incognito, boolean cct) {
this.incognito = incognito;
this.cct = cct;
}
}
/**
* {@link ParameterProvider} used for parameterized test that provides a list of two activity
* types between whom we run incognito leakage tests.
*/
public static class TestParams implements ParameterProvider {
@Override
public List<ParameterSet> getParameters() {
List<ParameterSet> tests = new ArrayList<>();
for (ActivityType activity1 : ActivityType.values()) {
for (ActivityType activity2 : ActivityType.values()) {
// We remove the test with two incognito tabs because they are known to share
// state via same session.
if ((activity1.incognito && !activity1.cct)
&& (activity2.incognito && !activity2.cct)) {
continue;
}
// We remove the tests with two regular type activities (cct and tabbed) because
// again they are known to share state.
if (!activity1.incognito && !activity2.incognito) {
continue;
}
tests.add(new ParameterSet()
.value(activity1.toString(), activity2.toString())
.name(activity1.toString() + "_" + activity2.toString()));
}
}
return tests;
}
}
private static Tab launchUrlInTab(
ChromeActivityTestRule testRule, String url, boolean incognito) {
// This helps to bring back the "existing" chrome tabbed activity to foreground
// in case the custom tab activity was launched before.
testRule.startMainActivityOnBlankPage();
Tab tab = testRule.loadUrlInNewTab(url, incognito);
assertEquals(incognito, tab.getWebContents().isIncognito());
return tab;
}
private static Tab launchUrlInCCT(
CustomTabActivityTestRule testRule, String url, boolean incognito) {
Intent intent = CustomTabsTestUtils.createMinimalCustomTabIntent(
InstrumentationRegistry.getContext(), url);
if (incognito) {
intent.putExtra(IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, true);
}
testRule.startCustomTabActivityWithIntent(intent);
Tab tab = testRule.getActivity().getActivityTab();
assertEquals(incognito, tab.getWebContents().isIncognito());
return tab;
}
public static void closeTabs(ChromeActivityTestRule testRule) {
ChromeActivity activity = testRule.getActivity();
if (activity == null) return;
activity.getTabModelSelector().getModel(false).closeAllTabs();
activity.getTabModelSelector().getModel(true).closeAllTabs();
}
public static void finishActivities() {
TestThreadUtils.runOnUiThreadBlocking(() -> {
for (Activity runningActivities : ApplicationStatus.getRunningActivities()) {
if (runningActivities instanceof ChromeActivity) {
runningActivities.finish();
}
}
});
}
}
\ No newline at end of file
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