chromium/chrome/test/data/webui/settings/clear_browsing_data_test.ts

// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// clang-format off
import {webUIListenerCallback} from 'chrome://resources/js/cr.js';
import {PromiseResolver} from 'chrome://resources/js/promise_resolver.js';
import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import type {ClearBrowsingDataResult, SettingsCheckboxElement, SettingsClearBrowsingDataDialogElement, SettingsHistoryDeletionDialogElement, SettingsPasswordsDeletionDialogElement} from 'chrome://settings/lazy_load.js';
import {ClearBrowsingDataBrowserProxyImpl, TimePeriodExperiment, TimePeriod} from 'chrome://settings/lazy_load.js';
import type {CrButtonElement, SettingsDropdownMenuElement} from 'chrome://settings/settings.js';
import {loadTimeData, resetRouterForTesting, SignedInState, StatusAction, SyncBrowserProxyImpl} from 'chrome://settings/settings.js';
import {assertArrayEquals, assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
import {isChildVisible, isVisible, eventToPromise, microtasksFinished} from 'chrome://webui-test/test_util.js';

import {TestClearBrowsingDataBrowserProxy} from './test_clear_browsing_data_browser_proxy.js';
import {TestSyncBrowserProxy} from './test_sync_browser_proxy.js';

// <if expr="not is_chromeos">
import {Router, routes} from 'chrome://settings/settings.js';
// </if>

// clang-format on

function getClearBrowsingDataPrefs() {
  return {
    browser: {
      clear_data: {
        browsing_history: {
          key: 'browser.clear_data.browsing_history',
          type: chrome.settingsPrivate.PrefType.BOOLEAN,
          value: false,
        },
        browsing_history_basic: {
          key: 'browser.clear_data.browsing_history_basic',
          type: chrome.settingsPrivate.PrefType.BOOLEAN,
          value: false,
        },
        cache: {
          key: 'browser.clear_data.cache',
          type: chrome.settingsPrivate.PrefType.BOOLEAN,
          value: false,
        },
        cache_basic: {
          key: 'browser.clear_data.cache_basic',
          type: chrome.settingsPrivate.PrefType.BOOLEAN,
          value: false,
        },
        cookies: {
          key: 'browser.clear_data.cookies',
          type: chrome.settingsPrivate.PrefType.BOOLEAN,
          value: false,
        },
        cookies_basic: {
          key: 'browser.clear_data.cookies_basic',
          type: chrome.settingsPrivate.PrefType.BOOLEAN,
          value: false,
        },
        download_history: {
          key: 'browser.clear_data.download_history',
          type: chrome.settingsPrivate.PrefType.BOOLEAN,
          value: false,
        },
        hosted_apps_data: {
          key: 'browser.clear_data.hosted_apps_data',
          type: chrome.settingsPrivate.PrefType.BOOLEAN,
          value: false,
        },
        form_data: {
          key: 'browser.clear_data.form_data',
          type: chrome.settingsPrivate.PrefType.BOOLEAN,
          value: false,
        },
        passwords: {
          key: 'browser.clear_data.passwords',
          type: chrome.settingsPrivate.PrefType.BOOLEAN,
          value: false,
        },
        site_settings: {
          key: 'browser.clear_data.site_settings',
          type: chrome.settingsPrivate.PrefType.BOOLEAN,
          value: false,
        },
        time_period: {
          key: 'browser.clear_data.time_period',
          type: chrome.settingsPrivate.PrefType.NUMBER,
          value: 0,
        },
        time_period_basic: {
          key: 'browser.clear_data.time_period_basic',
          type: chrome.settingsPrivate.PrefType.NUMBER,
          value: 0,
        },
        time_period_v2: {
          key: 'browser.clear_data.time_period_v2',
          type: chrome.settingsPrivate.PrefType.NUMBER,
          value: TimePeriodExperiment.NOT_SELECTED,
        },
        time_period_v2_basic: {
          key: 'browser.clear_data.time_period_v2_basic',
          type: chrome.settingsPrivate.PrefType.NUMBER,
          value: TimePeriodExperiment.NOT_SELECTED,
        },
      },
      last_clear_browsing_data_tab: {
        key: 'browser.last_clear_browsing_data_tab',
        type: chrome.settingsPrivate.PrefType.NUMBER,
        value: 0,
      },
    },
  };
}

// TODO(crbug.com/40283307): Used by the CbdExperiment test suites below. Remove
// once crbug.com/40283307 completed.
async function testCbdExperimentDualWritesPref(
    element: SettingsClearBrowsingDataDialogElement, tabIndex: number,
    prefName: string, inialPrefValue: number, userSelectedTimeFrame: number,
    expectedDualWrittenPrefValue: number) {
  // Ensure the test starts with a known pref state.
  element.setPrefValue(prefName, inialPrefValue);

  // The user selects the tab of interest.
  element.$.tabs.selected = tabIndex;
  await microtasksFinished();

  // Select a datatype for deletion to enable the clear button.
  const page = element.$.pages.selectedItem as HTMLElement;
  const cookiesCheckbox =
      page.querySelector<SettingsCheckboxElement>('.cookies-checkbox');
  assertTrue(!!cookiesCheckbox);
  cookiesCheckbox.$.checkbox.click();
  await microtasksFinished();
  assertFalse(element.$.clearButton.disabled);

  // The user selects a time range value.
  const dropdownMenu =
      page.querySelector<SettingsDropdownMenuElement>('.time-range-select');
  assertTrue(!!dropdownMenu);
  const selectElement = dropdownMenu.shadowRoot!.querySelector('select');
  assertTrue(!!selectElement);
  selectElement.value = userSelectedTimeFrame.toString();
  selectElement.dispatchEvent(new CustomEvent('change'));
  await microtasksFinished();

  // The correct time range value is dual written to the other pref.
  element.$.clearButton.click();
  await microtasksFinished();
  assertEquals(expectedDualWrittenPrefValue, element.getPref(prefName).value);
}

suite('ClearBrowsingDataDesktop', function() {
  let testBrowserProxy: TestClearBrowsingDataBrowserProxy;
  let testSyncBrowserProxy: TestSyncBrowserProxy;
  let element: SettingsClearBrowsingDataDialogElement;

  setup(async function() {
    testBrowserProxy = new TestClearBrowsingDataBrowserProxy();
    ClearBrowsingDataBrowserProxyImpl.setInstance(testBrowserProxy);
    testSyncBrowserProxy = new TestSyncBrowserProxy();
    SyncBrowserProxyImpl.setInstance(testSyncBrowserProxy);
    document.body.innerHTML = window.trustedTypes!.emptyHTML;
    // TODO(b/314968275): Add tests for when UNO Desktop is enabled.
    loadTimeData.overrideValues({
      enableCbdTimeframeRequired: false,
      unoDesktopEnabled: false,
    });
    resetRouterForTesting();

    element = document.createElement('settings-clear-browsing-data-dialog');
    element.set('prefs', getClearBrowsingDataPrefs());
    document.body.appendChild(element);
    await testBrowserProxy.whenCalled('initialize');
    assertTrue(element.$.clearBrowsingDataDialog.open);
  });

  teardown(function() {
    element.remove();
  });

  test('ClearBrowsingDataSyncAccountInfoDesktop', function() {
    // Not syncing: the footer is hidden.
    webUIListenerCallback('sync-status-changed', {
      signedInState: SignedInState.SIGNED_IN,
      hasError: false,
    });
    flush();
    assertFalse(!!element.shadowRoot!.querySelector(
        '#clearBrowsingDataDialog [slot=footer]'));

    // The footer is never shown on Lacros.
    // <if expr="not is_chromeos">
    // Syncing: the footer is shown, with the normal sync info.
    webUIListenerCallback('sync-status-changed', {
      signedInState: SignedInState.SYNCING,
      hasError: false,
    });
    flush();
    assertTrue(!!element.shadowRoot!.querySelector(
        '#clearBrowsingDataDialog [slot=footer]'));
    assertTrue(isChildVisible(element, '#sync-info'));
    assertFalse(isChildVisible(element, '#sync-paused-info'));
    assertFalse(isChildVisible(element, '#sync-passphrase-error-info'));
    assertFalse(isChildVisible(element, '#sync-other-error-info'));

    // Sync is paused.
    webUIListenerCallback('sync-status-changed', {
      signedInState: SignedInState.SYNCING,
      hasError: true,
      statusAction: StatusAction.REAUTHENTICATE,
    });
    flush();
    assertFalse(isChildVisible(element, '#sync-info'));
    assertTrue(isChildVisible(element, '#sync-paused-info'));
    assertFalse(isChildVisible(element, '#sync-passphrase-error-info'));
    assertFalse(isChildVisible(element, '#sync-other-error-info'));

    // Sync passphrase error.
    webUIListenerCallback('sync-status-changed', {
      signedInState: SignedInState.SYNCING,
      hasError: true,
      statusAction: StatusAction.ENTER_PASSPHRASE,
    });
    flush();
    assertFalse(isChildVisible(element, '#sync-info'));
    assertFalse(isChildVisible(element, '#sync-paused-info'));
    assertTrue(isChildVisible(element, '#sync-passphrase-error-info'));
    assertFalse(isChildVisible(element, '#sync-other-error-info'));

    // Other sync error.
    webUIListenerCallback('sync-status-changed', {
      signedInState: SignedInState.SYNCING,
      hasError: true,
      statusAction: StatusAction.NO_ACTION,
    });
    flush();
    assertFalse(isChildVisible(element, '#sync-info'));
    assertFalse(isChildVisible(element, '#sync-paused-info'));
    assertFalse(isChildVisible(element, '#sync-passphrase-error-info'));
    assertTrue(isChildVisible(element, '#sync-other-error-info'));
    // </if>
  });

  // The footer is never shown on Lacros.
  // <if expr="not is_chromeos">
  test('ClearBrowsingDataPauseSyncDesktop', function() {
    webUIListenerCallback('sync-status-changed', {
      signedInState: SignedInState.SYNCING,
      hasError: false,
    });
    flush();
    assertTrue(!!element.shadowRoot!.querySelector(
        '#clearBrowsingDataDialog [slot=footer]'));
    const syncInfo = element.shadowRoot!.querySelector('#sync-info');
    assertTrue(!!syncInfo);
    assertTrue(isVisible(syncInfo));
    const signoutLink = syncInfo.querySelector<HTMLElement>('a[href]');
    assertTrue(!!signoutLink);
    assertEquals(0, testSyncBrowserProxy.getCallCount('pauseSync'));
    signoutLink.click();
    assertEquals(1, testSyncBrowserProxy.getCallCount('pauseSync'));
  });

  test('ClearBrowsingDataStartSignInDesktop', function() {
    webUIListenerCallback('sync-status-changed', {
      signedInState: SignedInState.SYNCING,
      hasError: true,
      statusAction: StatusAction.REAUTHENTICATE,
    });
    flush();
    assertTrue(!!element.shadowRoot!.querySelector(
        '#clearBrowsingDataDialog [slot=footer]'));
    const syncInfo = element.shadowRoot!.querySelector('#sync-paused-info');
    assertTrue(!!syncInfo);
    assertTrue(isVisible(syncInfo));
    const signinLink = syncInfo.querySelector<HTMLElement>('a[href]');
    assertTrue(!!signinLink);
    assertEquals(0, testSyncBrowserProxy.getCallCount('startSignIn'));
    signinLink.click();
    assertEquals(1, testSyncBrowserProxy.getCallCount('startSignIn'));
  });

  test('ClearBrowsingDataHandlePassphraseErrorDesktop', function() {
    webUIListenerCallback('sync-status-changed', {
      signedInState: SignedInState.SYNCING,
      hasError: true,
      statusAction: StatusAction.ENTER_PASSPHRASE,
    });
    flush();
    assertTrue(!!element.shadowRoot!.querySelector(
        '#clearBrowsingDataDialog [slot=footer]'));
    const syncInfo =
        element.shadowRoot!.querySelector('#sync-passphrase-error-info');
    assertTrue(!!syncInfo);
    assertTrue(isVisible(syncInfo));
    const passphraseLink = syncInfo.querySelector<HTMLElement>('a[href]');
    assertTrue(!!passphraseLink);
    passphraseLink.click();
    assertEquals(routes.SYNC, Router.getInstance().getCurrentRoute());
  });
  // </if>

  test('ClearBrowsingDataSearchLabelVisibility', function() {
    for (const signedIn of [false, true]) {
      for (const isNonGoogleDse of [false, true]) {
        webUIListenerCallback('update-sync-state', {
          signedIn: signedIn,
          isNonGoogleDse: isNonGoogleDse,
          nonGoogleSearchHistoryString: 'Some test string',
        });
        flush();
        // Test Google search history label visibility and string.
        assertEquals(
            signedIn,
            isVisible(
                element.shadowRoot!.querySelector('#googleSearchHistoryLabel')),
            'googleSearchHistoryLabel visibility');
        if (signedIn) {
          assertEquals(
              isNonGoogleDse ?
                  element.i18nAdvanced('clearGoogleSearchHistoryNonGoogleDse')
                      .toString() :
                  element.i18nAdvanced('clearGoogleSearchHistoryGoogleDse')
                      .toString(),
              element.shadowRoot!
                  .querySelector<HTMLElement>(
                      '#googleSearchHistoryLabel')!.innerHTML,
              'googleSearchHistoryLabel text');
        }
        // Test non-Google search history label visibility and string.
        assertEquals(
            isNonGoogleDse,
            isVisible(element.shadowRoot!.querySelector(
                '#nonGoogleSearchHistoryLabel')),
            'nonGoogleSearchHistoryLabel visibility');
        if (isNonGoogleDse) {
          assertEquals(
              'Some test string',
              element.shadowRoot!
                  .querySelector<HTMLElement>(
                      '#nonGoogleSearchHistoryLabel')!.innerText,
              'nonGoogleSearchHistoryLabel text');
        }
      }
    }
  });

  test('ClearBrowsingData_MenuOptions', async function() {
    // The user selects the tab of interest.
    element.$.tabs.selected = 0;
    await microtasksFinished();

    const page = element.$.pages.selectedItem as HTMLElement;
    const dropdownMenu =
        page.querySelector<SettingsDropdownMenuElement>('.time-range-select');
    assertTrue(!!dropdownMenu);
    assertTrue(!!dropdownMenu.menuOptions);
    assertTrue(dropdownMenu.menuOptions.length === 5);

    // TODO(crbug.com/40283307): Remove once CbdTimeframeRequired finished.
    assertFalse(dropdownMenu.menuOptions.some(
        option =>
            option.name === loadTimeData.getString('clearPeriod15Minutes')));
  });

  async function testUnsupportedTimePeriod(tabIndex: number, prefName: string) {
    // The user selects the tab of interest.
    element.$.tabs.selected = tabIndex;
    await microtasksFinished();

    const page = element.$.pages.selectedItem as HTMLElement;
    const dropdownMenu =
        page.querySelector<SettingsDropdownMenuElement>('.time-range-select');
    assertTrue(!!dropdownMenu);
    const selectElement = dropdownMenu.shadowRoot!.querySelector('select');
    assertTrue(!!selectElement);

    const unsupported_pref_value = 100;

    element.setPrefValue(prefName, unsupported_pref_value);

    await microtasksFinished();

    // The unsupported value is replaced by the Default value.
    assertEquals(TimePeriod.LAST_HOUR, element.getPref(prefName).value);
    assertEquals(TimePeriod.LAST_HOUR.toString(), selectElement.value);
  }

  test('ClearBrowsingData_UnsupportedTimePeriod_Basic', function() {
    return testUnsupportedTimePeriod(0, 'browser.clear_data.time_period_basic');
  });

  test('ClearBrowsingData_UnsupportedTimePeriod_Advanced', function() {
    return testUnsupportedTimePeriod(1, 'browser.clear_data.time_period');
  });
});

// TODO(crbug.com/40283307): Remove once CbdTimeframeRequired finished.
// This test suite should only test code that exist only during the
// crbug.com/40283307 experiment for the in-experiment group.
suite('CbdTimeRangeExperiment_ExperimentOn', function() {
  let testBrowserProxy: TestClearBrowsingDataBrowserProxy;
  let element: SettingsClearBrowsingDataDialogElement;

  setup(async function() {
    testBrowserProxy = new TestClearBrowsingDataBrowserProxy();
    ClearBrowsingDataBrowserProxyImpl.setInstance(testBrowserProxy);
    document.body.innerHTML = window.trustedTypes!.emptyHTML;
    loadTimeData.overrideValues({enableCbdTimeframeRequired: true});
    resetRouterForTesting();

    element = document.createElement('settings-clear-browsing-data-dialog');
    element.set('prefs', getClearBrowsingDataPrefs());
    document.body.appendChild(element);
    await testBrowserProxy.whenCalled('initialize');
    assertTrue(element.$.clearBrowsingDataDialog.open);
  });

  async function testTimeRangeDropdownRequiresSelection(tabIndex: number) {
    // The user selects the tab of interest.
    element.$.tabs.selected = tabIndex;
    await microtasksFinished();

    // The dropdown menu contains the "not selected" and "15 min" options on
    // top.
    const page = element.$.pages.selectedItem as HTMLElement;
    const dropdownMenu =
        page.querySelector<SettingsDropdownMenuElement>('.time-range-select');
    assertTrue(!!dropdownMenu);
    assertTrue(!!dropdownMenu.menuOptions);
    assertEquals(7, dropdownMenu.menuOptions.length);
    assertEquals(
        loadTimeData.getString('clearPeriodNotSelected'),
        dropdownMenu.menuOptions[0]!.name);
    assertEquals(
        loadTimeData.getString('clearPeriod15Minutes'),
        dropdownMenu.menuOptions[1]!.name);
    assertEquals(
        loadTimeData.getString('clearPeriodNotSelected'),
        dropdownMenu.$.dropdownMenu
            .options[dropdownMenu.$.dropdownMenu.selectedIndex]!.text);
    for (const option of dropdownMenu.$.dropdownMenu.options) {
      assertEquals(
          option.text === loadTimeData.getString('clearPeriodNotSelected'),
          option.hidden);
    }

    // Select a datatype for deletion to enable the clear button.
    const cookiesCheckbox =
        page.querySelector<SettingsCheckboxElement>('.cookies-checkbox');
    assertTrue(!!cookiesCheckbox);
    cookiesCheckbox.$.checkbox.click();
    await microtasksFinished();
    assertFalse(element.$.clearButton.disabled);

    // Before trying data clearing without a time range selection, the dropdown
    // is not in the dropdown-error state.
    assertFalse(dropdownMenu.classList.contains('dropdown-error'));

    // Once the user tries to clear data without having made a time range
    // selection the dropdown goes into the dropdown-error state.
    element.$.clearButton.click();
    await microtasksFinished();
    assertTrue(dropdownMenu.classList.contains('dropdown-error'));

    // Once a time range is selected, the dropdown is no longer in the
    // dropdown-error state.
    dropdownMenu.$.dropdownMenu.value = TimePeriod.LAST_DAY.toString();
    dropdownMenu.$.dropdownMenu.dispatchEvent(new CustomEvent('change'));
    await microtasksFinished();
    assertFalse(dropdownMenu.classList.contains('dropdown-error'));
  }

  test('ClearBrowsingData_CbdTimeframeRequired_Basic', function() {
    return testTimeRangeDropdownRequiresSelection(/*tabIndex*/ 0);
  });

  test('ClearBrowsingData_CbdTimeframeRequired_Advanced', function() {
    return testTimeRangeDropdownRequiresSelection(/*tabIndex*/ 1);
  });

  async function assertSelectionRecordedToMetric(
      element: SettingsClearBrowsingDataDialogElement,
      testBrowserProxy: TestClearBrowsingDataBrowserProxy, tabIndex: number,
      prefName: string, inialPrefValue: number,
      expectedProxyCallFunctionName: string) {
    // Ensure the test starts with a known pref state.
    element.setPrefValue(prefName, inialPrefValue);

    // The user selects the tab of interest.
    element.$.tabs.selected = tabIndex;
    await microtasksFinished();

    // Select a datatype for deletion to enable the clear button.
    const page = element.$.pages.selectedItem as HTMLElement;
    const cookiesCheckbox =
        page.querySelector<SettingsCheckboxElement>('.cookies-checkbox');
    assertTrue(!!cookiesCheckbox);
    cookiesCheckbox.$.checkbox.click();
    await microtasksFinished();
    assertFalse(element.$.clearButton.disabled);

    // The user selects a time range value.
    const dropdownMenu =
        page.querySelector<SettingsDropdownMenuElement>('.time-range-select');
    assertTrue(!!dropdownMenu);
    const selectElement = dropdownMenu.shadowRoot!.querySelector('select');
    assertTrue(!!selectElement);
    selectElement.value = TimePeriodExperiment.LAST_WEEK.toString();
    selectElement.dispatchEvent(new CustomEvent('change'));
    await microtasksFinished();

    // The user confirms the deletion.
    element.$.clearButton.click();
    await microtasksFinished();

    // The selection is recorded only if clearing is done the first time, which
    // is indicated by the original pref value being NOT_SELECTED.
    if (inialPrefValue === TimePeriodExperiment.NOT_SELECTED) {
      const metricValue =
          await testBrowserProxy.whenCalled(expectedProxyCallFunctionName);
      assertEquals(
          1, testBrowserProxy.getCallCount(expectedProxyCallFunctionName),
          'metrics should be recored');
      assertEquals(TimePeriodExperiment.LAST_WEEK, metricValue);
    } else {
      assertEquals(
          0, testBrowserProxy.getCallCount(expectedProxyCallFunctionName),
          'no metrics should be recorded');
    }
  }

  test('SelectionRecordedToMetrics_Basic', function() {
    return assertSelectionRecordedToMetric(
        /*element*/ element,
        /*testBrowserProxy*/ testBrowserProxy,
        /*tabIndex*/ 0,
        /*prefName*/ 'browser.clear_data.time_period_v2_basic',
        /*inialPrefValue*/ TimePeriodExperiment.NOT_SELECTED,
        /*expectedProxyCallFunctionName*/
        'recordSettingsClearBrowsingDataBasicTimePeriodHistogram');
  });

  test('SelectionRecordedToMetrics_Advanced', function() {
    return assertSelectionRecordedToMetric(
        /*element*/ element,
        /*testBrowserProxy*/ testBrowserProxy,
        /*tabIndex*/ 1,
        /*prefName*/ 'browser.clear_data.time_period_v2',
        /*inialPrefValue*/ TimePeriodExperiment.NOT_SELECTED,
        /*expectedProxyCallFunctionName*/
        'recordSettingsClearBrowsingDataAdvancedTimePeriodHistogram');
  });

  test('SelectionNotRecordedToMetrics_Basic', function() {
    return assertSelectionRecordedToMetric(
        /*element*/ element,
        /*testBrowserProxy*/ testBrowserProxy,
        /*tabIndex*/ 0,
        /*prefName*/ 'browser.clear_data.time_period_v2_basic',
        /*inialPrefValue*/ TimePeriodExperiment.LAST_DAY,
        /*expectedProxyCallFunctionName*/
        'recordSettingsClearBrowsingDataBasicTimePeriodHistogram');
  });

  test('SelectionNotRecordedToMetrics_Advanced', function() {
    return assertSelectionRecordedToMetric(
        /*element*/ element,
        /*testBrowserProxy*/ testBrowserProxy,
        /*tabIndex*/ 1,
        /*prefName*/ 'browser.clear_data.time_period_v2',
        /*inialPrefValue*/ TimePeriodExperiment.LAST_DAY,
        /*expectedProxyCallFunctionName*/
        'recordSettingsClearBrowsingDataAdvancedTimePeriodHistogram');
  });

  test('DualWritePrefs_BasicDualWriteSelection', function() {
    return testCbdExperimentDualWritesPref(
        /*element*/ element,
        /*tabIndex*/ 0,
        /*prefName*/ 'browser.clear_data.time_period_basic',
        /*inialPrefValue*/ TimePeriod.LAST_WEEK,
        /*userSelectedTimeFrame*/ TimePeriodExperiment.LAST_DAY,
        /*expectedDualWrittenPrefValue*/ TimePeriodExperiment.LAST_DAY);
  });

  test('DualWritePrefs_BasicDualWrite1h', function() {
    return testCbdExperimentDualWritesPref(
        /*element*/ element,
        /*tabIndex*/ 0,
        /*prefName*/ 'browser.clear_data.time_period_basic',
        /*inialPrefValue*/ TimePeriod.LAST_WEEK,
        /*userSelectedTimeFrame*/ TimePeriodExperiment.LAST_15_MINUTES,
        /*expectedDualWrittenPrefValue*/ TimePeriodExperiment.LAST_HOUR);
  });

  test('DualWritePrefs_AdvancedDualWriteSelection', function() {
    return testCbdExperimentDualWritesPref(
        /*element*/ element,
        /*tabIndex*/ 1,
        /*prefName*/ 'browser.clear_data.time_period',
        /*inialPrefValue*/ TimePeriod.LAST_WEEK,
        /*userSelectedTimeFrame*/ TimePeriodExperiment.LAST_DAY,
        /*expectedDualWrittenPrefValue*/ TimePeriodExperiment.LAST_DAY);
  });

  test('DualWritePrefs_AdvancedDualWrite1h', function() {
    return testCbdExperimentDualWritesPref(
        /*element*/ element,
        /*tabIndex*/ 1,
        /*prefName*/ 'browser.clear_data.time_period',
        /*inialPrefValue*/ TimePeriod.LAST_WEEK,
        /*userSelectedTimeFrame*/ TimePeriodExperiment.LAST_15_MINUTES,
        /*expectedDualWrittenPrefValue*/ TimePeriodExperiment.LAST_HOUR);
  });
});

// TODO(crbug.com/40283307): Remove once CbdTimeframeRequired finished.
// This test suite should only test code that exist only during the
// crbug.com/40283307 experiment for the out-of-experiment group.
suite('CbdTimeRangeExperiment_ExperimentOff', function() {
  let testBrowserProxy: TestClearBrowsingDataBrowserProxy;
  let element: SettingsClearBrowsingDataDialogElement;

  setup(async function() {
    testBrowserProxy = new TestClearBrowsingDataBrowserProxy();
    ClearBrowsingDataBrowserProxyImpl.setInstance(testBrowserProxy);
    document.body.innerHTML = window.trustedTypes!.emptyHTML;
    loadTimeData.overrideValues({enableCbdTimeframeRequired: false});
    resetRouterForTesting();

    element = document.createElement('settings-clear-browsing-data-dialog');
    element.set('prefs', getClearBrowsingDataPrefs());
    document.body.appendChild(element);
    await testBrowserProxy.whenCalled('initialize');
    assertTrue(element.$.clearBrowsingDataDialog.open);
  });

  test('DualWritePrefs_BasicDualWrite', function() {
    return testCbdExperimentDualWritesPref(
        /*element*/ element,
        /*tabIndex*/ 0,
        /*prefName*/ 'browser.clear_data.time_period_v2_basic',
        /*inialPrefValue*/ TimePeriodExperiment.LAST_WEEK,
        /*userSelectedTimeFrame*/ TimePeriod.LAST_DAY,
        /*expectedDualWrittenPrefValue*/ TimePeriodExperiment.LAST_DAY);
  });

  test('DualWritePrefs_BasicDontDualWrite', function() {
    return testCbdExperimentDualWritesPref(
        /*element*/ element,
        /*tabIndex*/ 0,
        /*prefName*/ 'browser.clear_data.time_period_v2_basic',
        /*inialPrefValue*/ TimePeriodExperiment.NOT_SELECTED,
        /*userSelectedTimeFrame*/ TimePeriod.LAST_DAY,
        /*expectedDualWrittenPrefValue*/ TimePeriodExperiment.NOT_SELECTED);
  });

  test('DualWritePrefs_AdvancedDualWrite', function() {
    return testCbdExperimentDualWritesPref(
        /*element*/ element,
        /*tabIndex*/ 1,
        /*prefName*/ 'browser.clear_data.time_period_v2',
        /*inialPrefValue*/ TimePeriodExperiment.LAST_WEEK,
        /*userSelectedTimeFrame*/ TimePeriod.LAST_DAY,
        /*expectedDualWrittenPrefValue*/ TimePeriodExperiment.LAST_DAY);
  });

  test('DualWritePrefs_AdvancedDontDualWrite', function() {
    return testCbdExperimentDualWritesPref(
        /*element*/ element,
        /*tabIndex*/ 1,
        /*prefName*/ 'browser.clear_data.time_period_v2',
        /*inialPrefValue*/ TimePeriodExperiment.NOT_SELECTED,
        /*userSelectedTimeFrame*/ TimePeriod.LAST_DAY,
        /*expectedDualWrittenPrefValue*/ TimePeriodExperiment.NOT_SELECTED);
  });
});

suite('ClearBrowsingDataAllPlatforms', function() {
  let testBrowserProxy: TestClearBrowsingDataBrowserProxy;
  let element: SettingsClearBrowsingDataDialogElement;

  setup(function() {
    testBrowserProxy = new TestClearBrowsingDataBrowserProxy();
    ClearBrowsingDataBrowserProxyImpl.setInstance(testBrowserProxy);
    document.body.innerHTML = window.trustedTypes!.emptyHTML;
    element = document.createElement('settings-clear-browsing-data-dialog');
    element.set('prefs', getClearBrowsingDataPrefs());
    document.body.appendChild(element);
    return testBrowserProxy.whenCalled('initialize');
  });

  teardown(function() {
    element.remove();
  });

  async function assertClearBrowsingData(tabIndex: number, prefName: string) {
    assertTrue(element.$.clearBrowsingDataDialog.open);

    // The user selects the tab of interest.
    element.$.tabs.selected = tabIndex;
    await microtasksFinished();

    const page = element.$.pages.selectedItem as HTMLElement;
    const dropdownMenu =
        page.querySelector<SettingsDropdownMenuElement>('.time-range-select');
    assertTrue(!!dropdownMenu);

    // Ensure the test starts with a known pref and dropdown value.
    element.setPrefValue(prefName, TimePeriod.LAST_DAY);
    await microtasksFinished();
    assertEquals(
        TimePeriod.LAST_DAY.toString(), dropdownMenu.getSelectedValue());

    // Initially the clear button is disabled and the spinner isn't active.
    const cancelButton =
        element.shadowRoot!.querySelector<CrButtonElement>('.cancel-button');
    assertTrue(!!cancelButton);
    const spinner = element.shadowRoot!.querySelector('paper-spinner-lite');
    assertTrue(!!spinner);

    assertTrue(element.$.clearButton.disabled);
    assertFalse(cancelButton.disabled);
    assertFalse(spinner.active);

    // Changing the dropdown selection does not persist its value to the pref.
    dropdownMenu.$.dropdownMenu.value = TimePeriod.LAST_WEEK.toString();
    dropdownMenu.$.dropdownMenu.dispatchEvent(new CustomEvent('change'));
    await microtasksFinished();
    assertEquals(TimePeriod.LAST_DAY, element.getPref(prefName).value);

    // Select a datatype for deletion to enable the clear button.
    element.$.cookiesCheckbox.$.checkbox.click();
    element.$.cookiesCheckboxBasic.$.checkbox.click();
    await microtasksFinished();

    assertFalse(element.$.clearButton.disabled);
    assertFalse(cancelButton.disabled);
    assertFalse(spinner.active);

    // Confirming the deletion persists the dropdown selection to the pref,
    // records the time period in metrics, and sends it for clearing.
    const promiseResolver = new PromiseResolver<ClearBrowsingDataResult>();
    testBrowserProxy.setClearBrowsingDataPromise(promiseResolver.promise);
    element.$.clearButton.click();
    await microtasksFinished();

    assertEquals(TimePeriod.LAST_WEEK, element.getPref(prefName).value);
    // TODO(crbug.com/40283307): The in-experiment metrics are slightly
    // different, hence get tested in their own test suite. Remove the
    // surrounding conditional once crbug.com/40283307 completed.
    if (!loadTimeData.getBoolean('enableCbdTimeframeRequired')) {
      const metricValue = await testBrowserProxy.whenCalled(
          tabIndex === 0 ?
              'recordSettingsClearBrowsingDataBasicTimePeriodHistogram' :
              'recordSettingsClearBrowsingDataAdvancedTimePeriodHistogram');
      assertEquals(TimePeriod.LAST_WEEK, metricValue);
    }

    const args = await testBrowserProxy.whenCalled('clearBrowsingData');
    const dataTypes = args[0];
    assertEquals(1, dataTypes.length);
    const expectedDataTypes = tabIndex === 0 ?
        ['browser.clear_data.cookies_basic'] :
        ['browser.clear_data.cookies'];
    assertArrayEquals(expectedDataTypes, dataTypes);
    const timeRange = args[1];
    assertEquals(TimePeriod.LAST_WEEK, timeRange);
    assertTrue(element.$.clearBrowsingDataDialog.open);
    assertTrue(cancelButton.disabled);
    assertTrue(element.$.clearButton.disabled);
    assertTrue(spinner.active);

    // Simulate signal from browser indicating that clearing has
    // completed.
    webUIListenerCallback('browsing-data-removing', false);
    // Yields to the message loop to allow the callback chain of the
    // Promise that was just resolved to execute before the
    // assertions.
    promiseResolver.resolve(
        {showHistoryNotice: false, showPasswordsNotice: false});
    await promiseResolver.promise;

    assertFalse(element.$.clearBrowsingDataDialog.open);
    assertFalse(cancelButton.disabled);
    assertFalse(element.$.clearButton.disabled);
    assertFalse(spinner.active);
    assertFalse(!!element.shadowRoot!.querySelector('#historyNotice'));
    assertFalse(!!element.shadowRoot!.querySelector('#passwordsNotice'));
  }

  test('assertClearBrowsingData_Basic', function() {
    return assertClearBrowsingData(
        /*tabIndex*/ 0,
        loadTimeData.getBoolean('enableCbdTimeframeRequired') ?
            'browser.clear_data.time_period_v2_basic' :
            'browser.clear_data.time_period_basic');
  });

  test('assertClearBrowsingData_Advanced', function() {
    return assertClearBrowsingData(
        /*tabIndex*/ 1,
        loadTimeData.getBoolean('enableCbdTimeframeRequired') ?
            'browser.clear_data.time_period_v2' :
            'browser.clear_data.time_period');
  });

  test('tabSelection', async function() {
    assertTrue(element.$.clearBrowsingDataDialog.open);

    // Ensure the test starts with a known pref state and tab selection.
    element.setPrefValue('browser.last_clear_browsing_data_tab', 0);
    // TODO(crbug.com/40283307): Selecting a time period to enable deletion is
    // only required during the crbug.com/40283307 experiment. Remove it once
    // the experiment completed.
    element.setPrefValue(
        'browser.clear_data.time_period', TimePeriodExperiment.LAST_DAY);
    element.setPrefValue(
        'browser.clear_data.time_period_v2', TimePeriodExperiment.LAST_DAY);
    await microtasksFinished();
    assertEquals(
        0, element.getPref('browser.last_clear_browsing_data_tab').value);
    assertTrue(isChildVisible(element, '#basic-tab'));

    // Changing the tab selection changes the visible tab, but does not persist
    // the tab selection to the pref.
    element.$.tabs.selected = 1;
    await microtasksFinished();
    assertEquals(
        0, element.getPref('browser.last_clear_browsing_data_tab').value);
    assertTrue(isChildVisible(element, '#advanced-tab'));

    // Select a datatype for deletion to enable the clear button.
    element.$.cookiesCheckbox.$.checkbox.click();
    // TODO(crbug.com/40283307): Selecting a time period to enable deletion is
    // only required during the crbug.com/40283307 experiment. Remove it once
    // the experiment completed.
    element.setPrefValue(
        'browser.clear_data.time_period', TimePeriodExperiment.LAST_DAY);
    element.setPrefValue(
        'browser.clear_data.time_period_v2', TimePeriodExperiment.LAST_DAY);
    await microtasksFinished();

    // Confirming the deletion persists the tab selection to the pref.
    element.$.clearButton.click();
    await microtasksFinished();
    assertEquals(
        1, element.getPref('browser.last_clear_browsing_data_tab').value);
  });

  test('ClearBrowsingDataClearButton', async function() {
    assertTrue(element.$.clearBrowsingDataDialog.open);

    // Initially the button is disabled because all checkboxes are off.
    assertTrue(element.$.clearButton.disabled);
    // The button gets enabled if any checkbox is selected.
    element.$.cookiesCheckboxBasic.$.checkbox.click();
    await microtasksFinished();
    assertTrue(element.$.cookiesCheckboxBasic.checked);
    assertFalse(element.$.clearButton.disabled);
    // Switching to advanced disables the button.
    element.$.tabs.selected = 1;
    await microtasksFinished();
    assertTrue(element.$.clearButton.disabled);
    // Switching back enables it again.
    element.$.tabs.selected = 0;
    await microtasksFinished();
    assertFalse(element.$.clearButton.disabled);
  });

  test('showHistoryDeletionDialog', async function() {
    assertTrue(element.$.clearBrowsingDataDialog.open);

    // Select a datatype for deletion to enable the clear button.
    element.$.cookiesCheckboxBasic.$.checkbox.click();
    // TODO(crbug.com/40283307): Selecting a time period to enable deletion is
    // only required during the crbug.com/40283307 experiment. Remove it once
    // the experiment completed.
    element.setPrefValue(
        'browser.clear_data.time_period_basic', TimePeriodExperiment.LAST_DAY);
    element.setPrefValue(
        'browser.clear_data.time_period_v2_basic',
        TimePeriodExperiment.LAST_DAY);
    await microtasksFinished();
    assertFalse(element.$.clearButton.disabled);

    const promiseResolver = new PromiseResolver<ClearBrowsingDataResult>();
    testBrowserProxy.setClearBrowsingDataPromise(promiseResolver.promise);
    element.$.clearButton.click();

    await testBrowserProxy.whenCalled('clearBrowsingData');
    // Passing showHistoryNotice = true should trigger the notice about
    // other forms of browsing history to open, and the dialog to stay
    // open.


    // Yields to the message loop to allow the callback chain of the
    // Promise that was just resolved to execute before the
    // assertions.
    promiseResolver.resolve(
        {showHistoryNotice: true, showPasswordsNotice: false});
    await promiseResolver.promise;

    flush();
    const notice1 =
        element.shadowRoot!.querySelector<SettingsHistoryDeletionDialogElement>(
            '#historyNotice');
    assertTrue(!!notice1);
    const noticeActionButton =
        notice1.shadowRoot!.querySelector<CrButtonElement>('.action-button');
    assertTrue(!!noticeActionButton);

    // The notice should have replaced the main dialog.
    assertFalse(element.$.clearBrowsingDataDialog.open);
    assertTrue(notice1.$.dialog.open);

    const whenNoticeClosed = eventToPromise('close', notice1!);

    // Tapping the action button will close the notice.
    noticeActionButton.click();

    await whenNoticeClosed;
    const notice2 = element.shadowRoot!.querySelector('#historyNotice');
    assertFalse(!!notice2);
    assertFalse(element.$.clearBrowsingDataDialog.open);
  });

  test('showPasswordsDeletionDialog', async function() {
    assertTrue(element.$.clearBrowsingDataDialog.open);

    // Select a datatype for deletion to enable the clear button.
    const cookieCheckbox = element.$.cookiesCheckboxBasic;
    assertTrue(!!cookieCheckbox);
    cookieCheckbox.$.checkbox.click();
    // TODO(crbug.com/40283307): Selecting a time period to enable deletion is
    // only required during the crbug.com/40283307 experiment. Remove it once
    // the experiment completed.
    element.setPrefValue(
        'browser.clear_data.time_period_basic', TimePeriodExperiment.LAST_DAY);
    element.setPrefValue(
        'browser.clear_data.time_period_v2_basic',
        TimePeriodExperiment.LAST_DAY);
    await microtasksFinished();
    assertFalse(element.$.clearButton.disabled);

    const promiseResolver = new PromiseResolver<ClearBrowsingDataResult>();
    testBrowserProxy.setClearBrowsingDataPromise(promiseResolver.promise);
    element.$.clearButton.click();

    await testBrowserProxy.whenCalled('clearBrowsingData');
    // Passing showPasswordsNotice = true should trigger the notice about
    // incomplete password deletions to open, and the dialog to stay open.
    promiseResolver.resolve(
        {showHistoryNotice: false, showPasswordsNotice: true});
    await promiseResolver.promise;

    // Yields to the message loop to allow the callback chain of the
    // Promise that was just resolved to execute before the
    // assertions.
    flush();
    const notice1 = element.shadowRoot!
                        .querySelector<SettingsPasswordsDeletionDialogElement>(
                            '#passwordsNotice');
    assertTrue(!!notice1);
    const noticeActionButton =
        notice1.shadowRoot!.querySelector<CrButtonElement>('.action-button');
    assertTrue(!!noticeActionButton);

    // The notice should have replaced the main dialog.
    assertFalse(element.$.clearBrowsingDataDialog.open);
    assertTrue(notice1.$.dialog.open);

    const whenNoticeClosed = eventToPromise('close', notice1!);

    // Tapping the action button will close the notice.
    noticeActionButton.click();

    await whenNoticeClosed;
    const notice2 = element.shadowRoot!.querySelector('#passwordsNotice');
    assertFalse(!!notice2);
    assertFalse(element.$.clearBrowsingDataDialog.open);
  });

  test('showBothHistoryAndPasswordsDeletionDialog', async function() {
    assertTrue(element.$.clearBrowsingDataDialog.open);

    // Select a datatype for deletion to enable the clear button.
    const cookieCheckbox = element.$.cookiesCheckboxBasic;
    assertTrue(!!cookieCheckbox);
    cookieCheckbox.$.checkbox.click();
    // TODO(crbug.com/40283307): Selecting a time period to enable deletion is
    // only required during the crbug.com/40283307 experiment. Remove it once
    // the experiment completed.
    element.setPrefValue(
        'browser.clear_data.time_period_basic', TimePeriodExperiment.LAST_DAY);
    element.setPrefValue(
        'browser.clear_data.time_period_v2_basic',
        TimePeriodExperiment.LAST_DAY);
    await microtasksFinished();
    assertFalse(element.$.clearButton.disabled);

    const promiseResolver = new PromiseResolver<ClearBrowsingDataResult>();
    testBrowserProxy.setClearBrowsingDataPromise(promiseResolver.promise);
    element.$.clearButton.click();

    await testBrowserProxy.whenCalled('clearBrowsingData');
    // Passing showHistoryNotice = true and showPasswordsNotice = true
    // should first trigger the notice about other forms of browsing
    // history to open, then once that is acknowledged, the notice about
    // incomplete password deletions should open. The main CBD dialog
    // should stay open during that whole time.
    promiseResolver.resolve(
        {showHistoryNotice: true, showPasswordsNotice: true});
    await promiseResolver.promise;

    // Yields to the message loop to allow the callback chain of the
    // Promise that was just resolved to execute before the
    // assertions.
    flush();
    const notice1 =
        element.shadowRoot!.querySelector<SettingsHistoryDeletionDialogElement>(
            '#historyNotice');
    assertTrue(!!notice1);
    const noticeActionButton1 =
        notice1.shadowRoot!.querySelector<CrButtonElement>('.action-button');
    assertTrue(!!noticeActionButton1);

    // The notice should have replaced the main dialog.
    assertFalse(element.$.clearBrowsingDataDialog.open);
    assertTrue(notice1.$.dialog.open);

    const whenNoticeClosed1 = eventToPromise('close', notice1!);

    // Tapping the action button will close the history notice, and
    // display the passwords notice instead.
    noticeActionButton1.click();

    await whenNoticeClosed1;
    // The passwords notice should have replaced the history notice.
    const historyNotice = element.shadowRoot!.querySelector('#historyNotice');
    assertFalse(!!historyNotice);
    const passwordsNotice =
        element.shadowRoot!.querySelector('#passwordsNotice');
    assertTrue(!!passwordsNotice);

    flush();
    const notice2 = element.shadowRoot!
                        .querySelector<SettingsPasswordsDeletionDialogElement>(
                            '#passwordsNotice');
    assertTrue(!!notice2);
    const noticeActionButton2 =
        notice2.shadowRoot!.querySelector<CrButtonElement>('.action-button');
    assertTrue(!!noticeActionButton2);

    assertFalse(element.$.clearBrowsingDataDialog.open);
    assertTrue(notice2.$.dialog.open);

    const whenNoticeClosed2 = eventToPromise('close', notice2!);

    // Tapping the action button will close the notice.
    noticeActionButton2.click();

    await whenNoticeClosed2;
    const notice3 = element.shadowRoot!.querySelector('#passwordsNotice');
    assertFalse(!!notice3);
    assertFalse(element.$.clearBrowsingDataDialog.open);
  });

  async function testDropdownResetsCounters(tabIndex: number) {
    testBrowserProxy.reset();

    // Select the right tab.
    assertTrue(element.$.clearBrowsingDataDialog.open);
    element.$.tabs.selected = tabIndex;
    await microtasksFinished();

    // Wait for the dropdown to render, so that we can select an option.
    const page = element.$.pages.selectedItem as HTMLElement;
    const dropdownMenu =
        page.querySelector<SettingsDropdownMenuElement>('.time-range-select');
    assertTrue(!!dropdownMenu);
    await microtasksFinished();

    // Select a non-default option.
    const selectedOption = TimePeriod.LAST_WEEK;
    dropdownMenu.$.dropdownMenu.value = selectedOption.toString();
    dropdownMenu.$.dropdownMenu.dispatchEvent(new CustomEvent('change'));
    await microtasksFinished();

    // The proxy should request re-calculation for this option.
    const args = await testBrowserProxy.whenCalled('restartCounters');
    assertEquals(args[0] /* isBasic */ ? 0 : 1, tabIndex);
    assertEquals(args[1], selectedOption);
  }

  test('DropdownResetsCounters_Basic', async function() {
    await testDropdownResetsCounters(0 /* tabIndex */);
  });

  test('DropdownResetsCounters_Advanced', async function() {
    await testDropdownResetsCounters(1 /* tabIndex */);
  });

  test('CountersUpdateText', function() {
    assertTrue(element.$.clearBrowsingDataDialog.open);

    const checkbox = element.shadowRoot!.querySelector<SettingsCheckboxElement>(
        '#cacheCheckboxBasic');
    assertTrue(!!checkbox);
    assertEquals('browser.clear_data.cache_basic', checkbox.pref!.key);

    // Simulate a browsing data counter result for history. This checkbox's
    // sublabel should be updated.
    webUIListenerCallback('update-counter-text', checkbox.pref!.key, 'result');
    assertEquals('result', checkbox.subLabel);
  });

  // <if expr="is_chromeos">
  // On ChromeOS the footer is never shown.
  test('ClearBrowsingDataSyncAccountInfo', function() {
    assertTrue(element.$.clearBrowsingDataDialog.open);

    // Not syncing.
    webUIListenerCallback('sync-status-changed', {
      signedInState: SignedInState.SIGNED_IN,
      hasError: false,
    });
    flush();
    assertFalse(!!element.shadowRoot!.querySelector(
        '#clearBrowsingDataDialog [slot=footer]'));

    // Syncing.
    webUIListenerCallback('sync-status-changed', {
      signedInState: SignedInState.SYNCING,
      hasError: false,
    });
    flush();
    assertFalse(!!element.shadowRoot!.querySelector(
        '#clearBrowsingDataDialog [slot=footer]'));

    // Sync passphrase error.
    webUIListenerCallback('sync-status-changed', {
      signedInState: SignedInState.SYNCING,
      hasError: true,
      statusAction: StatusAction.ENTER_PASSPHRASE,
    });
    flush();
    assertFalse(!!element.shadowRoot!.querySelector(
        '#clearBrowsingDataDialog [slot=footer]'));

    // Other sync error.
    webUIListenerCallback('sync-status-changed', {
      signedInState: SignedInState.SYNCING,
      hasError: true,
      statusAction: StatusAction.NO_ACTION,
    });
    flush();
    assertFalse(!!element.shadowRoot!.querySelector(
        '#clearBrowsingDataDialog [slot=footer]'));
  });
  // </if>
});


suite('ClearBrowsingDataForSupervisedUsers', function() {
  let testBrowserProxy: TestClearBrowsingDataBrowserProxy;
  let element: SettingsClearBrowsingDataDialogElement;

  setup(function() {
    testBrowserProxy = new TestClearBrowsingDataBrowserProxy();
    ClearBrowsingDataBrowserProxyImpl.setInstance(testBrowserProxy);
    document.body.innerHTML = window.trustedTypes!.emptyHTML;
    element = document.createElement('settings-clear-browsing-data-dialog');
    element.set('prefs', getClearBrowsingDataPrefs());
    loadTimeData.overrideValues({isChildAccount: true});
    resetRouterForTesting();
  });

  teardown(function() {
    element.remove();
  });

  test('history rows are shown for supervised users', async function() {
    document.body.appendChild(element);
    await testBrowserProxy.whenCalled('initialize');

    assertTrue(element.$.clearBrowsingDataDialog.open);
    assertFalse(element.shadowRoot!
                    .querySelector<SettingsCheckboxElement>(
                        '#browsingCheckbox')!.hidden);
    assertFalse(element.shadowRoot!
                    .querySelector<SettingsCheckboxElement>(
                        '#browsingCheckboxBasic')!.hidden);
    assertFalse(element.shadowRoot!
                    .querySelector<SettingsCheckboxElement>(
                        '#downloadCheckbox')!.hidden);
  });

  // <if expr="is_win or is_macosx or is_linux">
  test(
      'Additional information shown for supervised users when clearing cookies',
      async function() {
        document.body.appendChild(element);
        await testBrowserProxy.whenCalled('initialize');

        assertTrue(element.$.clearBrowsingDataDialog.open);

        // Supervised users will see additional text informing them they will
        // not be signed out when cookies are cleared
        const checkbox =
            element.shadowRoot!.querySelector<SettingsCheckboxElement>(
                '#cookiesCheckboxBasic')!;

        assertEquals(
            element.i18n('clearCookiesSummarySignedInSupervisedProfile')
                .toString(),
            checkbox.subLabel);
      });
  // </if>
});