[go: nahoru, domu]

blob: 0a2d08b35e27aaea4b6e490e5435341bd59d6c54 [file] [log] [blame]
// 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.
import {PrivacyHubBrowserProxyImpl} from 'chrome://os-settings/lazy_load.js';
import {CrDialogElement, createRouterForTesting, CrRadioGroupElement, GeolocationAccessLevel, OsSettingsPrivacyPageElement, PageStatus, PeripheralDataAccessBrowserProxyImpl, Router, routes, SecureDnsMode, settingMojom, SettingsToggleButtonElement, SyncBrowserProxy, SyncBrowserProxyImpl} from 'chrome://os-settings/os_settings.js';
import {assert} from 'chrome://resources/js/assert.js';
import {webUIListenerCallback} from 'chrome://resources/js/cr.js';
import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
import {getDeepActiveElement} from 'chrome://resources/js/util.js';
import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {assertEquals, assertFalse, assertNotEquals, assertNull, assertTrue} from 'chrome://webui-test/chai_assert.js';
import {flushTasks, waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js';
import {eventToPromise} from 'chrome://webui-test/test_util.js';
import {FakeMetricsPrivate} from '../fake_metrics_private.js';
import {FakeQuickUnlockPrivate} from '../fake_quick_unlock_private.js';
import {TestSyncBrowserProxy} from '../test_os_sync_browser_proxy.js';
import {TestPeripheralDataAccessBrowserProxy} from './test_peripheral_data_access_browser_proxy.js';
import {TestPrivacyHubBrowserProxy} from './test_privacy_hub_browser_proxy.js';
const CROS_SETTING_PREF_NAME = 'cros.device.peripheral_data_access_enabled';
const LOCAL_STATE_PREF_NAME =
'settings.local_state_device_pci_data_access_enabled';
suite('with isRevampWayfindingEnabled set to true', () => {
let privacyPage: OsSettingsPrivacyPageElement;
let browserProxy: TestPeripheralDataAccessBrowserProxy;
let syncBrowserProxy: SyncBrowserProxy&TestSyncBrowserProxy;
async function createPage(): Promise<void> {
privacyPage = document.createElement('os-settings-privacy-page');
document.body.appendChild(privacyPage);
flush();
await browserProxy.whenCalled('isThunderboltSupported');
}
setup(() => {
loadTimeData.overrideValues({
isRevampWayfindingEnabled: true,
});
const testRouter = createRouterForTesting();
Router.resetInstanceForTesting(testRouter);
browserProxy = new TestPeripheralDataAccessBrowserProxy();
PeripheralDataAccessBrowserProxyImpl.setInstanceForTesting(browserProxy);
syncBrowserProxy = new TestSyncBrowserProxy();
SyncBrowserProxyImpl.setInstance(syncBrowserProxy);
Router.getInstance().navigateTo(routes.OS_PRIVACY);
});
teardown(() => {
Router.getInstance().resetRouteForTesting();
privacyPage.remove();
});
test('Deep link to encryption options on old sync page', async () => {
createPage();
await waitAfterNextRender(privacyPage);
// Load the sync page.
Router.getInstance().navigateTo(routes.SYNC);
await flushTasks();
// Make the sync page configurable.
const syncPage =
privacyPage.shadowRoot!.querySelector('os-settings-sync-subpage');
assertTrue(!!syncPage);
syncPage.syncPrefs = {
customPassphraseAllowed: true,
passphraseRequired: false,
appsManaged: false,
appsRegistered: false,
appsSynced: false,
autofillManaged: false,
autofillRegistered: false,
autofillSynced: false,
bookmarksManaged: false,
bookmarksRegistered: false,
bookmarksSynced: false,
cookiesManaged: false,
cookiesRegistered: false,
cookiesSynced: false,
encryptAllData: false,
extensionsManaged: false,
extensionsRegistered: false,
extensionsSynced: false,
passwordsManaged: false,
passwordsRegistered: false,
passwordsSynced: false,
paymentsManaged: false,
paymentsRegistered: false,
paymentsSynced: false,
preferencesManaged: false,
preferencesRegistered: false,
preferencesSynced: false,
readingListManaged: false,
readingListRegistered: false,
readingListSynced: false,
savedTabGroupsManaged: false,
savedTabGroupsRegistered: false,
savedTabGroupsSynced: false,
syncAllDataTypes: false,
tabsManaged: false,
tabsRegistered: false,
tabsSynced: false,
themesManaged: false,
themesRegistered: false,
themesSynced: false,
trustedVaultKeysRequired: false,
typedUrlsManaged: false,
typedUrlsRegistered: false,
typedUrlsSynced: false,
wifiConfigurationsManaged: false,
wifiConfigurationsRegistered: false,
wifiConfigurationsSynced: false,
};
webUIListenerCallback('page-status-changed', PageStatus.CONFIGURE);
const configureElement = syncPage.shadowRoot!.querySelector<HTMLElement>(
`#${PageStatus.CONFIGURE}`);
assertTrue(!!configureElement);
assertFalse(configureElement.hidden);
const spinnerElement = syncPage.shadowRoot!.querySelector<HTMLElement>(
`#${PageStatus.SPINNER}`);
assertTrue(!!spinnerElement);
assertTrue(spinnerElement.hidden);
// Try the deep link.
const params = new URLSearchParams();
const syncEncryptionOptionsSettingId =
settingMojom.Setting.kNonSplitSyncEncryptionOptions.toString();
params.append('settingId', syncEncryptionOptionsSettingId);
Router.getInstance().navigateTo(routes.SYNC, params);
// Flush to make sure the dropdown expands.
flush();
const element = syncPage.shadowRoot!.querySelector(
'os-settings-sync-encryption-options');
assertTrue(!!element);
const radioGroupElement =
element.shadowRoot!.querySelector<CrRadioGroupElement>(
'#encryptionRadioGroup');
assertTrue(!!radioGroupElement);
const radioButton = radioGroupElement.get('buttons_')[0];
assertTrue(!!radioButton);
const deepLinkElement = radioButton.shadowRoot!.querySelector('#button');
assert(deepLinkElement);
await waitAfterNextRender(deepLinkElement);
assertEquals(
deepLinkElement, getDeepActiveElement(),
`Encryption option should be focused for settingId=${
syncEncryptionOptionsSettingId}.`);
});
});
suite('<os-settings-privacy-page>', () => {
let privacyPage: OsSettingsPrivacyPageElement;
let browserProxy: TestPeripheralDataAccessBrowserProxy;
const PRIVACY_PAGE_PREFS = {
'ash': {
'user': {
'camera_allowed': {
value: true,
},
'microphone_allowed': {
value: true,
},
'geolocation_access_level': {
key: 'ash.user.geolocation_access_level',
type: chrome.settingsPrivate.PrefType.NUMBER,
value: GeolocationAccessLevel.ALLOWED,
},
},
},
'settings': {
'suggested_content_enabled': {
value: false,
},
},
'cros': {
'device': {
'peripheral_data_access_enabled': {
value: true,
},
},
},
'dns_over_https': {
'mode': {
value: SecureDnsMode.AUTOMATIC,
},
'templates': {
value: '',
},
},
};
setup(async () => {
browserProxy = new TestPeripheralDataAccessBrowserProxy();
PeripheralDataAccessBrowserProxyImpl.setInstanceForTesting(browserProxy);
privacyPage = document.createElement('os-settings-privacy-page');
privacyPage.prefs = Object.assign({}, PRIVACY_PAGE_PREFS);
document.body.appendChild(privacyPage);
flush();
await browserProxy.whenCalled('isThunderboltSupported');
});
teardown(() => {
privacyPage.remove();
Router.getInstance().resetRouteForTesting();
});
/**
* Returns true if the element exists and has not been 'removed' by the
* Polymer template system.
* @param selector The ID of the element about which to query.
* @return Whether or not the element has been masked by the
* template system.
*/
function elementExists(selector: string): boolean {
const el = privacyPage.shadowRoot!.querySelector<HTMLElement>(selector);
return (el !== null) && (el.style.display !== 'none');
}
test(
'Suggested content, hidden when privacy hub feature flag is enabled',
() => {
privacyPage = document.createElement('os-settings-privacy-page');
document.body.appendChild(privacyPage);
flush();
assertFalse(elementExists('#contentRecommendationsToggle'));
});
test('Deep link to verified access', async () => {
const params = new URLSearchParams();
params.append('settingId', settingMojom.Setting.kVerifiedAccess.toString());
Router.getInstance().navigateTo(routes.OS_PRIVACY, params);
flush();
const toggle =
privacyPage.shadowRoot!.querySelector('#verifiedAccessToggle');
assertTrue(!!toggle);
const deepLinkElement = toggle.shadowRoot!.querySelector('cr-toggle');
assertTrue(!!deepLinkElement);
await waitAfterNextRender(deepLinkElement);
assertEquals(
deepLinkElement, getDeepActiveElement(),
'Verified access toggle should be focused for settingId=1101.');
});
test('Deep link to guest browsing on users page', async () => {
const params = new URLSearchParams();
params.append(
'settingId', settingMojom.Setting.kGuestBrowsingV2.toString());
Router.getInstance().navigateTo(routes.ACCOUNTS, params);
flush();
const element =
privacyPage.shadowRoot!.querySelector('settings-manage-users-subpage');
assertTrue(!!element);
const toggle = element.shadowRoot!.querySelector('#allowGuestBrowsing');
assertTrue(!!toggle);
const deepLinkElement = toggle.shadowRoot!.querySelector('cr-toggle');
assertTrue(!!deepLinkElement);
await waitAfterNextRender(deepLinkElement);
assertEquals(
deepLinkElement, getDeepActiveElement(),
'Allow guest browsing should be focused for settingId=1104.');
});
test('Deep link to show usernames on sign in on users page', async () => {
const params = new URLSearchParams();
params.append(
'settingId',
settingMojom.Setting.kShowUsernamesAndPhotosAtSignInV2.toString());
Router.getInstance().navigateTo(routes.ACCOUNTS, params);
flush();
const element =
privacyPage.shadowRoot!.querySelector('settings-manage-users-subpage');
assertTrue(!!element);
const toggle = element.shadowRoot!.querySelector('#showUserNamesOnSignIn');
assertTrue(!!toggle);
const deepLinkElement = toggle.shadowRoot!.querySelector('cr-toggle');
assertTrue(!!deepLinkElement);
await waitAfterNextRender(deepLinkElement);
assertEquals(
deepLinkElement, getDeepActiveElement(),
'Allow guest browsing should be focused for settingId=1105.');
});
test('Deep link to snooping protection on smart privacy page', async () => {
loadTimeData.overrideValues({
isSnoopingProtectionEnabled: true,
});
const params = new URLSearchParams();
params.append(
'settingId', settingMojom.Setting.kSnoopingProtection.toString());
Router.getInstance().navigateTo(routes.SMART_PRIVACY, params);
flush();
const element =
privacyPage.shadowRoot!.querySelector('settings-smart-privacy-subpage');
assertTrue(!!element);
const toggle =
element.shadowRoot!.querySelector('#snoopingProtectionToggle');
assertTrue(!!toggle);
const deepLinkElement = toggle.shadowRoot!.querySelector('cr-toggle');
assertTrue(!!deepLinkElement);
await waitAfterNextRender(deepLinkElement);
assertEquals(
deepLinkElement, getDeepActiveElement(),
'Snooping protection should be focused for settingId=1114.');
});
test('Deep link to quick dim on smart privacy page', async () => {
loadTimeData.overrideValues({
isQuickDimEnabled: true,
});
const params = new URLSearchParams();
params.append('settingId', settingMojom.Setting.kQuickDim.toString());
Router.getInstance().navigateTo(routes.SMART_PRIVACY, params);
flush();
const element =
privacyPage.shadowRoot!.querySelector('settings-smart-privacy-subpage');
assertTrue(!!element);
const quickDimToggle = element.shadowRoot!.querySelector('#quickDimToggle');
assertTrue(!!quickDimToggle);
const deepLinkElement =
quickDimToggle.shadowRoot!.querySelector('cr-toggle');
assertTrue(!!deepLinkElement);
await waitAfterNextRender(deepLinkElement);
assertEquals(
deepLinkElement, getDeepActiveElement(),
'Quick dim should be focused for settingId=1115.');
});
test(
'Manage accounts row is focused when returning from subpage',
async () => {
Router.getInstance().navigateTo(routes.OS_PRIVACY);
const triggerSelector = '#manageOtherPeopleRow';
const subpageTrigger =
privacyPage.shadowRoot!.querySelector<HTMLElement>(triggerSelector);
assertTrue(!!subpageTrigger);
// Sub-page trigger navigates to subpage for route
subpageTrigger.click();
assertEquals(routes.ACCOUNTS, Router.getInstance().currentRoute);
// Navigate back
const popStateEventPromise = eventToPromise('popstate', window);
Router.getInstance().navigateToPreviousRoute();
await popStateEventPromise;
await waitAfterNextRender(privacyPage);
assertEquals(
subpageTrigger, privacyPage.shadowRoot!.activeElement,
`${triggerSelector} should be focused.`);
});
test('Lock screen row is focused when returning from subpage', async () => {
Router.getInstance().navigateTo(routes.OS_PRIVACY);
const quickUnlockPrivateApi = new FakeQuickUnlockPrivate();
privacyPage.set('authTokenInfo_', quickUnlockPrivateApi.getFakeToken());
const triggerSelector = '#lockScreenRow';
const subpageTrigger =
privacyPage.shadowRoot!.querySelector<HTMLElement>(triggerSelector);
assertTrue(!!subpageTrigger);
// Sub-page trigger navigates to subpage for route
subpageTrigger.click();
assertEquals(routes.LOCK_SCREEN, Router.getInstance().currentRoute);
// Navigate back
const popStateEventPromise = eventToPromise('popstate', window);
Router.getInstance().navigateToPreviousRoute();
await popStateEventPromise;
await waitAfterNextRender(privacyPage);
assertEquals(
subpageTrigger, privacyPage.shadowRoot!.activeElement,
`${triggerSelector} should be focused.`);
});
test('Fingerprint dialog closes when token expires', async () => {
loadTimeData.overrideValues({
fingerprintUnlockEnabled: true,
});
privacyPage = document.createElement('os-settings-privacy-page');
document.body.appendChild(privacyPage);
await waitAfterNextRender(privacyPage);
const quickUnlockPrivateApi = new FakeQuickUnlockPrivate();
privacyPage['authTokenInfo_'] = quickUnlockPrivateApi.getFakeToken();
Router.getInstance().navigateTo(routes.LOCK_SCREEN);
flush();
const subpageTrigger =
privacyPage.shadowRoot!.querySelector<HTMLButtonElement>(
'#lockScreenRow');
assertTrue(!!subpageTrigger);
// Sub-page trigger navigates to the lock screen page.
subpageTrigger.click();
flush();
assertEquals(routes.LOCK_SCREEN, Router.getInstance().currentRoute);
const lockScreenPage = privacyPage.shadowRoot!.querySelector('#lockScreen');
assertTrue(!!lockScreenPage);
// Password dialog should not open because the authTokenInfo_ is set.
assertFalse(privacyPage.get('showPasswordPromptDialog_'));
const editFingerprintsTrigger =
lockScreenPage.shadowRoot!.querySelector<HTMLButtonElement>(
'#editFingerprints');
assertTrue(!!editFingerprintsTrigger);
editFingerprintsTrigger.click();
flush();
assertEquals(routes.FINGERPRINT, Router.getInstance().currentRoute);
assertFalse(privacyPage.get('showPasswordPromptDialog_'));
const element = privacyPage.shadowRoot!.querySelector('#fingerprint-list');
assertTrue(!!element);
const fingerprintTrigger =
element.shadowRoot!.querySelector<HTMLButtonElement>('#addFingerprint');
assertTrue(!!fingerprintTrigger);
fingerprintTrigger.click();
// Invalidate the auth token by firing an event.
assertNotEquals(undefined, privacyPage.get('authTokenInfo_'));
const event = new CustomEvent('invalidate-auth-token-requested');
lockScreenPage.dispatchEvent(event);
assertEquals(undefined, privacyPage.get('authTokenInfo_'));
assertEquals(routes.FINGERPRINT, Router.getInstance().currentRoute);
assertTrue(privacyPage.get('showPasswordPromptDialog_'));
});
test('Smart privacy hidden when both features disabled', async () => {
loadTimeData.overrideValues({
isSnoopingProtectionEnabled: false,
isQuickDimEnabled: false,
});
privacyPage = document.createElement('os-settings-privacy-page');
document.body.appendChild(privacyPage);
await waitAfterNextRender(privacyPage);
assertFalse(elementExists('#smartPrivacySubpageTrigger'));
});
test('Smart privacy shown when only quick dim enabled', async () => {
loadTimeData.overrideValues({
isSnoopingProtectionEnabled: false,
isQuickDimEnabled: true,
});
privacyPage = document.createElement('os-settings-privacy-page');
document.body.appendChild(privacyPage);
await waitAfterNextRender(privacyPage);
assertTrue(elementExists('#smartPrivacySubpageTrigger'));
});
test('Smart privacy shown if only snooping protection enabled', async () => {
loadTimeData.overrideValues({
isSnoopingProtectionEnabled: true,
isQuickDimEnabled: false,
});
privacyPage = document.createElement('os-settings-privacy-page');
document.body.appendChild(privacyPage);
await waitAfterNextRender(privacyPage);
assertTrue(elementExists('#smartPrivacySubpageTrigger'));
});
test('Open PrivacyHub', async () => {
const privacyHubBrowserProxy = new TestPrivacyHubBrowserProxy();
PrivacyHubBrowserProxyImpl.setInstanceForTesting(privacyHubBrowserProxy);
const fakeMetricsPrivate = new FakeMetricsPrivate();
chrome.metricsPrivate = fakeMetricsPrivate;
privacyPage = document.createElement('os-settings-privacy-page');
privacyPage.prefs = Object.assign({}, PRIVACY_PAGE_PREFS);
document.body.appendChild(privacyPage);
await waitAfterNextRender(privacyPage);
const privacyHubPageRow =
privacyPage.shadowRoot!.querySelector<HTMLButtonElement>(
'#privacyHubSubpageTrigger');
assertTrue(!!privacyHubPageRow);
assertEquals(
0,
fakeMetricsPrivate.countMetricValue('ChromeOS.PrivacyHub.Opened', 0));
privacyHubPageRow.click();
flush();
await waitAfterNextRender(privacyPage);
assertEquals(
1,
fakeMetricsPrivate.countMetricValue('ChromeOS.PrivacyHub.Opened', 0));
});
// TODO(crbug.com/40202733): add a test for deep linking to snopping setting
// once it has been added.
});
suite('PeripheralDataAccessTest', () => {
let privacyPage: OsSettingsPrivacyPageElement;
let browserProxy: TestPeripheralDataAccessBrowserProxy;
const prefs_ = {
'cros': {
'device': {
'peripheral_data_access_enabled': {
value: false,
},
},
},
'settings': {'local_state_device_pci_data_access_enabled': {value: false}},
'dns_over_https':
{'mode': {value: SecureDnsMode.AUTOMATIC}, 'templates': {value: ''}},
};
setup(() => {
browserProxy = new TestPeripheralDataAccessBrowserProxy();
PeripheralDataAccessBrowserProxyImpl.setInstanceForTesting(browserProxy);
});
teardown(() => {
privacyPage.remove();
Router.getInstance().resetRouteForTesting();
});
async function setUpPage(prefName: string, isUserConfigurable: boolean) {
browserProxy.setPolicyState(prefName, isUserConfigurable);
privacyPage = document.createElement('os-settings-privacy-page');
privacyPage.prefs = Object.assign({}, prefs_);
document.body.appendChild(privacyPage);
flush();
await browserProxy.whenCalled('getPolicyState');
await waitAfterNextRender(privacyPage);
flush();
}
test('DialogOpensOnToggle', async () => {
await setUpPage(CROS_SETTING_PREF_NAME, /**isUserConfigurable=*/ true);
// The default state is checked.
const toggle =
privacyPage.shadowRoot!.querySelector<SettingsToggleButtonElement>(
'#crosSettingDataAccessToggle');
assertTrue(!!toggle);
assertTrue(toggle.checked);
// Attempting to switch the toggle off will result in the warning dialog
// appearing.
toggle.click();
flush();
await waitAfterNextRender(privacyPage);
const protectionDialog =
privacyPage.shadowRoot!.querySelector('#protectionDialog');
assertTrue(!!protectionDialog);
const dialog = protectionDialog.shadowRoot!.querySelector<CrDialogElement>(
'#warningDialog');
assertTrue(!!dialog);
assertTrue(dialog.open);
// Ensure that the toggle is still checked.
assertTrue(toggle.checked);
// Click on the dialog's cancel button and expect the toggle to switch back
// to enabled.
const cancelButton =
dialog.querySelector<HTMLButtonElement>('#cancelButton');
assertTrue(!!cancelButton);
cancelButton.click();
flush();
assertFalse(dialog.open);
// The toggle should not have changed position.
assertTrue(toggle.checked);
});
test('DisableClicked', async () => {
await setUpPage(CROS_SETTING_PREF_NAME, /**isUserConfigurable=*/ true);
// The default state is checked.
const toggle =
privacyPage.shadowRoot!.querySelector<SettingsToggleButtonElement>(
'#crosSettingDataAccessToggle');
assertTrue(!!toggle);
assertTrue(toggle.checked);
// Attempting to switch the toggle off will result in the warning dialog
// appearing.
toggle.click();
flush();
await waitAfterNextRender(privacyPage);
const protectionDialog =
privacyPage.shadowRoot!.querySelector('#protectionDialog');
assertTrue(!!protectionDialog);
const dialog = protectionDialog.shadowRoot!.querySelector<CrDialogElement>(
'#warningDialog');
assertTrue(!!dialog);
assertTrue(dialog.open);
// Advance the dialog and move onto the next dialog.
const disableButton =
dialog.querySelector<HTMLButtonElement>('#disableConfirmation');
assertTrue(!!disableButton);
disableButton.click();
flush();
// The toggle should now be flipped to unset.
assertFalse(toggle.checked);
});
test('managedAndConfigurablePrefIsToggleable', async () => {
await setUpPage(LOCAL_STATE_PREF_NAME, /**isUserConfigurable=*/ true);
flush();
// Ensure only the local state toggle appears.
const crosSettingDataAccessToggle =
privacyPage.shadowRoot!.querySelector<SettingsToggleButtonElement>(
'#crosSettingDataAccessToggle');
assertTrue(!!crosSettingDataAccessToggle);
assertTrue(crosSettingDataAccessToggle.hidden);
// The default state is checked.
const toggle =
privacyPage.shadowRoot!.querySelector<SettingsToggleButtonElement>(
'#localStateDataAccessToggle');
// The default state is checked.
assertTrue(!!toggle);
assertTrue(toggle.checked);
// Attempting to switch the toggle off will result in the warning dialog
// appearing.
toggle.click();
flush();
await waitAfterNextRender(privacyPage);
const protectionDialog =
privacyPage.shadowRoot!.querySelector('#protectionDialog');
assertTrue(!!protectionDialog);
const dialog = protectionDialog.shadowRoot!.querySelector<CrDialogElement>(
'#warningDialog');
assertTrue(!!dialog);
assertTrue(dialog.open);
// Ensure that the toggle is still checked.
assertTrue(toggle.checked);
// Click on the dialog's cancel button and expect the toggle to switch back
// to enabled.
const cancelButton =
dialog.querySelector<HTMLButtonElement>('#cancelButton');
assertTrue(!!cancelButton);
cancelButton.click();
flush();
assertFalse(dialog.open);
// The toggle should not have changed position.
assertTrue(toggle.checked);
});
test('managedAndNonConfigurablePrefIsNotToggleable', async () => {
await setUpPage(LOCAL_STATE_PREF_NAME, /**isUserConfigurable=*/ false);
flush();
// Ensure only the local state toggle appears.
const crosSettingDataAccessToggle =
privacyPage.shadowRoot!.querySelector<SettingsToggleButtonElement>(
'#crosSettingDataAccessToggle');
assertTrue(!!crosSettingDataAccessToggle);
assertTrue(crosSettingDataAccessToggle.hidden);
// The default state is checked.
const toggle =
privacyPage.shadowRoot!.querySelector<SettingsToggleButtonElement>(
'#localStateDataAccessToggle');
// The default state is checked.
assertTrue(!!toggle);
assertTrue(toggle.checked);
// Attempting to switch the toggle off will result in the warning dialog
// appearing.
toggle.click();
flush();
await waitAfterNextRender(privacyPage);
// Dialog should not appear since the toggle is disabled.
const dialog = privacyPage.shadowRoot!.querySelector('#protectionDialog');
assertNull(dialog);
});
});