blob: f0f929765036d0b10d1cc87f75917b78b3f85d1c [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 "base/strings/strcat.h"
#import "base/strings/string_util.h"
#import "base/strings/sys_string_conversions.h"
#import "base/test/ios/wait_util.h"
#import "components/autofill/core/common/autofill_prefs.h"
#import "components/enterprise/browser/enterprise_switches.h"
#import "components/enterprise/connectors/core/features.h"
#import "components/enterprise/connectors/core/reporting_test_utils.h"
#import "components/history/core/common/pref_names.h"
#import "components/password_manager/core/common/password_manager_pref_names.h"
#import "components/policy/core/common/cloud/cloud_policy_constants.h"
#import "components/policy/core/common/policy_loader_ios_constants.h"
#import "components/policy/core/common/policy_switches.h"
#import "components/policy/policy_constants.h"
#import "components/policy/test_support/embedded_policy_test_server.h"
#import "components/policy/test_support/signature_provider.h"
#import "components/safe_browsing/core/common/features.h"
#import "components/strings/grit/components_strings.h"
#import "ios/chrome/browser/authentication/test/signin_earl_grey.h"
#import "ios/chrome/browser/authentication/test/signin_earl_grey_ui_test_util.h"
#import "ios/chrome/browser/content_suggestions/ui_bundled/content_suggestions_constants.h"
#import "ios/chrome/browser/ntp/ui_bundled/new_tab_page_constants.h"
#import "ios/chrome/browser/policy/model/cloud/user_policy_constants.h"
#import "ios/chrome/browser/policy/model/policy_app_interface.h"
#import "ios/chrome/browser/policy/model/policy_earl_grey_utils.h"
#import "ios/chrome/browser/popup_menu/ui_bundled/popup_menu_constants.h"
#import "ios/chrome/browser/settings/ui_bundled/autofill/autofill_settings_constants.h"
#import "ios/chrome/browser/settings/ui_bundled/elements/elements_constants.h"
#import "ios/chrome/browser/settings/ui_bundled/language/language_settings_ui_constants.h"
#import "ios/chrome/browser/settings/ui_bundled/password/password_settings/password_settings_constants.h"
#import "ios/chrome/browser/settings/ui_bundled/password/password_settings_app_interface.h"
#import "ios/chrome/browser/settings/ui_bundled/password/passwords_table_view_constants.h"
#import "ios/chrome/browser/settings/ui_bundled/privacy/privacy_constants.h"
#import "ios/chrome/browser/settings/ui_bundled/settings_root_table_constants.h"
#import "ios/chrome/browser/settings/ui_bundled/settings_table_view_controller_constants.h"
#import "ios/chrome/browser/shared/model/prefs/pref_names.h"
#import "ios/chrome/browser/shared/model/url/chrome_url_constants.h"
#import "ios/chrome/browser/shared/public/features/features.h"
#import "ios/chrome/browser/signin/model/fake_system_identity.h"
#import "ios/chrome/browser/translate/model/translate_app_interface.h"
#import "ios/chrome/common/ui/table_view/table_view_cells_constants.h"
#import "ios/chrome/grit/ios_strings.h"
#import "ios/chrome/test/earl_grey/chrome_actions.h"
#import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
#import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h"
#import "ios/chrome/test/earl_grey/chrome_matchers.h"
#import "ios/chrome/test/earl_grey/chrome_test_case.h"
#import "ios/chrome/test/earl_grey/scoped_disable_timer_tracking.h"
#import "ios/chrome/test/earl_grey/test_switches.h"
#import "ios/testing/earl_grey/app_launch_configuration.h"
#import "ios/testing/earl_grey/app_launch_manager.h"
#import "ios/testing/earl_grey/earl_grey_test.h"
#import "ios/web/public/test/element_selector.h"
#import "net/test/embedded_test_server/embedded_test_server.h"
#import "ui/base/l10n/l10n_util.h"
using policy_test_utils::SetPolicy;
namespace {
// TODO(crbug.com/40124201): Add helpers as needed for:
// - STRING
// - LIST (and subtypes, e.g. int list, string list, etc)
// - DICTIONARY (and subtypes, e.g. int dictionary, string dictionary, etc)
// - Deleting a policy value
// - Setting multiple policies at once
// Verifies that a bool type policy sets the pref properly.
void VerifyBoolPolicy(const std::string& policy_key,
const std::string& pref_name) {
// Loading chrome://policy isn't necessary for the test to succeed, but it
// provides some visual feedback as the test runs.
[ChromeEarlGrey loadURL:GURL(kChromeUIPolicyURL)];
[ChromeEarlGrey waitForWebStateContainingText:l10n_util::GetStringUTF8(
IDS_POLICY_HEADER_NAME)];
// Force the preference off via policy.
SetPolicy(false, policy_key);
GREYAssertFalse([ChromeEarlGrey userBooleanPref:pref_name],
@"Preference was unexpectedly true");
// Force the preference on via policy.
SetPolicy(true, policy_key);
GREYAssertTrue([ChromeEarlGrey userBooleanPref:pref_name],
@"Preference was unexpectedly false");
}
// Returns a matcher for the Translate manual trigger button in the tools menu.
id<GREYMatcher> ToolsMenuTranslateButton() {
return grey_allOf(grey_accessibilityID(kToolsMenuTranslateId),
grey_interactable(), nil);
}
// Verifies that a managed setting item is shown and react properly.
void VerifyManagedSettingItem(NSString* accessibilityID,
NSString* containerViewAccessibilityID) {
// Check if the managed item is shown in the corresponding table view.
[[[EarlGrey
selectElementWithMatcher:grey_allOf(grey_accessibilityID(accessibilityID),
grey_sufficientlyVisible(), nil)]
usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, 200)
onElementWithMatcher:grey_accessibilityID(containerViewAccessibilityID)]
assertWithMatcher:grey_notNil()];
// Click the info button.
[ChromeEarlGreyUI tapSettingsMenuButton:grey_accessibilityID(
kTableViewCellInfoButtonViewId)];
// Check if the contextual bubble is shown.
[[EarlGrey selectElementWithMatcher:grey_accessibilityID(
kEnterpriseInfoBubbleViewId)]
assertWithMatcher:grey_sufficientlyVisible()];
// Tap outside of the bubble.
[[EarlGrey selectElementWithMatcher:grey_accessibilityID(
kTableViewCellInfoButtonViewId)]
performAction:grey_tap()];
// Check if the contextual bubble is hidden.
[[EarlGrey selectElementWithMatcher:grey_accessibilityID(
kEnterpriseInfoBubbleViewId)]
assertWithMatcher:grey_notVisible()];
}
ElementSelector* VisibleElementSelector(NSString* element_id) {
NSString* selector =
[NSString stringWithFormat:
@"(function() {"
" var element = document.getElementById('%@');"
" if (element == null) return false;"
" if (element.classList.contains('hidden')) return false;"
" return true;"
"})()",
element_id];
NSString* description =
[NSString stringWithFormat:@"Visible element with id: %@.", element_id];
return [ElementSelector selectorWithScript:selector
selectorDescription:description];
}
NSString* const kDomain1 = @"domain1.com";
NSString* const kDomain2 = @"domain2.com";
constexpr char kEnrollmentToken[] = "fake-enrollment-token";
} // namespace
// Test case to verify that enterprise policies are set and respected.
@interface PolicyTestCase : ChromeTestCase
@end
@implementation PolicyTestCase {
BOOL _settingsOpened;
std::unique_ptr<policy::EmbeddedPolicyTestServer> _server;
}
- (void)tearDownHelper {
if (_settingsOpened) {
[ChromeEarlGrey dismissSettings];
[ChromeEarlGreyUI waitForAppToIdle];
}
[PolicyAppInterface clearPolicies];
[super tearDownHelper];
}
- (void)openSettingsMenu {
[ChromeEarlGreyUI openSettingsMenu];
_settingsOpened = YES;
}
- (AppLaunchConfiguration)appConfigurationForTestCase {
// Use commandline args to insert fake policy data into NSUserDefaults. To the
// app, this policy data will appear under the
// "com.apple.configuration.managed" key.
AppLaunchConfiguration config = [super appConfigurationForTestCase];
config.relaunch_policy = NoForceRelaunchAndResetState;
return config;
}
// Tests that about:policy is available.
- (void)testAboutPolicy {
[ChromeEarlGrey loadURL:GURL(kChromeUIPolicyURL)];
[ChromeEarlGrey waitForWebStateContainingText:l10n_util::GetStringUTF8(
IDS_POLICY_HEADER_NAME)];
}
// Tests changing the DefaultSearchProviderEnabled policy while the settings
// are open updates the UI.
- (void)testDefaultSearchProviderUpdate {
SetPolicy(true, policy::key::kDefaultSearchProviderEnabled);
[self openSettingsMenu];
// Check that the non-managed item is present.
[[[EarlGrey selectElementWithMatcher:grey_accessibilityID(
kSettingsSearchEngineCellId)]
usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, 200)
onElementWithMatcher:grey_allOf(
grey_accessibilityID(kSettingsTableViewId),
grey_sufficientlyVisible(), nil)]
assertWithMatcher:grey_notNil()];
SetPolicy(false, policy::key::kDefaultSearchProviderEnabled);
// After setting the policy to false, the item should be replaced.
VerifyManagedSettingItem(kSettingsManagedSearchEngineCellId,
kSettingsTableViewId);
}
// Tests for the DefaultSearchProviderEnabled policy.
// 1. Test if the policy can be properly set.
// 2. Test the managed UI item and clicking action.
- (void)testDefaultSearchProviderEnabled {
// Disable default search provider via policy and make sure it does not crash
// the omnibox UI.
SetPolicy(false, policy::key::kDefaultSearchProviderEnabled);
[ChromeEarlGrey loadURL:GURL(kChromeUIPolicyURL)];
// Open a new tab and verify that the NTP does not crash. Regression test for
// http://crbug.com/1148903.
[ChromeEarlGrey openNewTab];
// Open settings menu.
[self openSettingsMenu];
VerifyManagedSettingItem(kSettingsManagedSearchEngineCellId,
kSettingsTableViewId);
}
// Tests for the PasswordManagerEnabled policy.
- (void)testPasswordManagerEnabled {
VerifyBoolPolicy(policy::key::kPasswordManagerEnabled,
password_manager::prefs::kCredentialsEnableService);
}
// Tests for the PasswordManagerEnabled policy Settings UI.
- (void)testPasswordManagerEnabledSettingsUI {
// Force the preference off via policy.
SetPolicy(false, policy::key::kPasswordManagerEnabled);
GREYAssertFalse(
[ChromeEarlGrey
userBooleanPref:password_manager::prefs::kCredentialsEnableService],
@"Preference was unexpectedly true");
// Open settings menu and tap password manager.
[self openSettingsMenu];
// Mock successful reauth when opening the Password Manager.
[PasswordSettingsAppInterface setUpMockReauthenticationModule];
[PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult:
ReauthenticationResult::kSuccess];
[ChromeEarlGreyUI
tapSettingsMenuButton:chrome_test_util::SettingsMenuPasswordsButton()];
// Open password settings.
[[EarlGrey selectElementWithMatcher:grey_accessibilityID(
kSettingsToolbarSettingsButtonId)]
performAction:grey_tap()];
VerifyManagedSettingItem(
kPasswordSettingsManagedSavePasswordSwitchTableViewId,
kPasswordsSettingsTableViewId);
// Remove mock to keep the app in the same state as before running the test.
[PasswordSettingsAppInterface removeMockReauthenticationModule];
}
// Tests for the AutofillAddressEnabled policy Settings UI.
- (void)testAutofillAddressSettingsUI {
// Force the preference off via policy.
SetPolicy(false, policy::key::kAutofillAddressEnabled);
GREYAssertFalse(
[ChromeEarlGrey userBooleanPref:autofill::prefs::kAutofillProfileEnabled],
@"Preference was unexpectedly true");
// Open settings menu and tap Address and More setting.
[self openSettingsMenu];
[ChromeEarlGreyUI
tapSettingsMenuButton:chrome_test_util::AddressesAndMoreButton()];
VerifyManagedSettingItem(kAutofillAddressManagedViewId,
kAutofillProfileTableViewID);
}
// Tests for the AutofillCreditCardEnabled policy Settings UI.
- (void)testAutofillCreditCardSettingsUI {
// Force the preference off via policy.
SetPolicy(false, policy::key::kAutofillCreditCardEnabled);
GREYAssertFalse(
[ChromeEarlGrey
userBooleanPref:autofill::prefs::kAutofillCreditCardEnabled],
@"Preference was unexpectedly true");
// Open settings menu and tap Payment Method setting.
[self openSettingsMenu];
[ChromeEarlGreyUI
tapSettingsMenuButton:chrome_test_util::PaymentMethodsButton()];
VerifyManagedSettingItem(kAutofillCreditCardManagedViewId,
kAutofillCreditCardTableViewId);
}
// Tests for the SavingBrowserHistoryDisabled policy.
- (void)testSavingBrowserHistoryDisabled {
GREYAssertTrue(self.testServer->Start(), @"Test server failed to start.");
const GURL testURL = self.testServer->GetURL("/pony.html");
const std::string pageText = "pony";
// Set history to a clean state and verify it is clean.
if (![ChromeTestCase forceRestartAndWipe]) {
[ChromeEarlGrey clearBrowsingHistory];
}
[ChromeEarlGrey resetBrowsingDataPrefs];
GREYAssertEqual([ChromeEarlGrey browsingHistoryEntryCount], 0,
@"History was unexpectedly non-empty");
// Verify that the unmanaged pref's default value is false. While we generally
// don't want to assert default pref values, in this case we need to start
// from a well-known default value due to the order of the checks we make for
// the history panel. If the default value ever changes for this pref, we'll
// need to adjust the order of the history panel checks.
GREYAssertFalse(
[ChromeEarlGrey userBooleanPref:prefs::kSavingBrowserHistoryDisabled],
@"Unexpected default value");
// Force the preference to true via policy (disables history).
SetPolicy(true, policy::key::kSavingBrowserHistoryDisabled);
GREYAssertTrue(
[ChromeEarlGrey userBooleanPref:prefs::kSavingBrowserHistoryDisabled],
@"Disabling browser history preference was unexpectedly false");
// Perform a navigation and make sure the history isn't changed.
[ChromeEarlGrey loadURL:testURL];
[ChromeEarlGrey waitForWebStateContainingText:pageText];
GREYAssertEqual([ChromeEarlGrey browsingHistoryEntryCount], 0,
@"History was unexpectedly non-empty");
// Force the preference to false via policy (enables history).
SetPolicy(false, policy::key::kSavingBrowserHistoryDisabled);
GREYAssertFalse(
[ChromeEarlGrey userBooleanPref:prefs::kSavingBrowserHistoryDisabled],
@"Disabling browser history preference was unexpectedly true");
// Perform a navigation and make sure history is being saved.
[ChromeEarlGrey loadURL:testURL];
[ChromeEarlGrey waitForWebStateContainingText:pageText];
GREYAssertEqual([ChromeEarlGrey browsingHistoryEntryCount], 1,
@"History had an unexpected entry count");
}
// Tests for the SearchSuggestEnabled policy.
- (void)testSearchSuggestEnabled {
VerifyBoolPolicy(policy::key::kSearchSuggestEnabled,
prefs::kSearchSuggestEnabled);
}
// Tests that language detection is not performed and the tool manual trigger
// button is disabled when the pref kOfferTranslateEnabled is set to false.
- (void)testTranslateEnabled {
GREYAssertTrue(self.testServer->Start(), @"Test server failed to start.");
const GURL testURL = self.testServer->GetURL("/pony.html");
const std::string pageText = "pony";
// Set up a fake language detection observer.
[TranslateAppInterface
setUpWithScriptServer:base::SysUTF8ToNSString(testURL.spec())];
// Disable TranslateEnabled policy.
SetPolicy(false, policy::key::kTranslateEnabled);
// Open some webpage.
[ChromeEarlGrey loadURL:testURL];
// Check that no language has been detected.
GREYCondition* condition = [GREYCondition
conditionWithName:@"Wait for language detection"
block:^BOOL() {
return [TranslateAppInterface isLanguageDetected];
}];
GREYAssertFalse([condition waitWithTimeout:2],
@"The Language is unexpectedly detected.");
// Make sure the Translate manual trigger button disabled.
[ChromeEarlGreyUI openToolsMenu];
id<GREYMatcher> toolsMenuMatcher =
[ChromeEarlGrey isNewOverflowMenuEnabled]
? grey_accessibilityID(kPopupMenuToolsMenuActionListId)
: grey_accessibilityID(kPopupMenuToolsMenuTableViewId);
[[[EarlGrey selectElementWithMatcher:ToolsMenuTranslateButton()]
usingSearchAction:grey_scrollInDirection(kGREYDirectionDown,
/*amount=*/200)
onElementWithMatcher:toolsMenuMatcher]
assertWithMatcher:grey_accessibilityTrait(
UIAccessibilityTraitNotEnabled)];
// Close the tools menu.
[ChromeTestCase removeAnyOpenMenusAndInfoBars];
// Remove any tranlation related setup properly.
[TranslateAppInterface tearDown];
// Enable the policy.
SetPolicy(true, policy::key::kTranslateEnabled);
}
- (void)testBlockPopupsSettingsUI {
// Set the policy to int value 2, which stands for "do not allow any site to
// show popups".
SetPolicy(2, policy::key::kDefaultPopupsSetting);
// Open settings menu and tap Content Settings setting.
[self openSettingsMenu];
[ChromeEarlGreyUI
tapSettingsMenuButton:chrome_test_util::ContentSettingsButton()];
[[EarlGrey
selectElementWithMatcher:grey_accessibilityID(kSettingsBlockPopupsCellId)]
performAction:grey_tap()];
VerifyManagedSettingItem(@"blockPopupsContentView_managed",
@"block_popups_settings_view_controller");
}
- (void)testTranslateEnabledSettingsUI {
// Disable TranslateEnabled policy.
SetPolicy(false, policy::key::kTranslateEnabled);
// Open settings menu and tap Languages setting.
[self openSettingsMenu];
[ChromeEarlGreyUI tapSettingsMenuButton:chrome_test_util::LanguagesButton()];
VerifyManagedSettingItem(kTranslateManagedAccessibilityIdentifier,
kLanguageSettingsTableViewAccessibilityIdentifier);
}
// Tests whether the managed item will be shown if a machine level policy is
// set.
- (void)testPopupMenuItemWithMachineLevelPolicy {
// Setup a machine level policy.
SetPolicy(false, policy::key::kTranslateEnabled);
// Open the menu and click on the item.
[ChromeEarlGreyUI openToolsMenu];
[[EarlGrey selectElementWithMatcher:grey_accessibilityID(
kPopupMenuToolsMenuActionListId)]
performAction:grey_scrollToContentEdge(kGREYContentEdgeBottom)];
[ChromeEarlGreyUI
tapToolsMenuAction:grey_accessibilityID(kTextMenuEnterpriseInfo)];
[ChromeEarlGrey
waitForWebStateContainingText:l10n_util::GetStringUTF8(
IDS_IOS_MANAGEMENT_UI_DESC)];
// Check the navigation.
[[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText(
kChromeUIManagementURL)]
assertWithMatcher:grey_notNil()];
}
// Tests whether the managed item will be shown if UserPolicy is enabled and
// the browser is signed in with a managed account.
// TODO(crbug.com/435333773): Reenable this test.
- (void)FLAKY_testPopupMenuItemWithUserPolicy {
// Sign in with a managed account.
NSString* managedAccountEmail = base::SysUTF8ToNSString(
base::StrCat({"enterprise@", policy::SignatureProvider::kTestDomain1}));
FakeSystemIdentity* fakeManagedIdentity =
[FakeSystemIdentity identityWithEmail:managedAccountEmail];
[SigninEarlGrey
signinWithFakeManagedIdentityInPersonalProfile:fakeManagedIdentity];
// Open the menu and click on the item.
[ChromeEarlGreyUI openToolsMenu];
[[EarlGrey selectElementWithMatcher:grey_accessibilityID(
kPopupMenuToolsMenuActionListId)]
performAction:grey_scrollToContentEdge(kGREYContentEdgeBottom)];
[ChromeEarlGreyUI
tapToolsMenuAction:grey_accessibilityID(kTextMenuEnterpriseInfo)];
[ChromeEarlGrey
waitForWebStateContainingText:l10n_util::GetStringUTF8(
IDS_IOS_MANAGEMENT_UI_DESC)];
// Check the navigation without assert the content (which is done in another
// test case).
[[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText(
kChromeUIManagementURL)]
assertWithMatcher:grey_notNil()];
}
// Tests the chrome://management page when no machine level policy is set.
- (void)testManagementPageUnmanaged {
// Open the management page and check if the content is expected.
[ChromeEarlGrey loadURL:GURL(kChromeUIManagementURL)];
[ChromeEarlGrey
waitForWebStateContainingText:l10n_util::GetStringUTF8(
IDS_IOS_MANAGEMENT_UI_UNMANAGED_DESC)];
}
// Tests the chrome://management page when one or more machine level policies
// are set.
- (void)testManagementPageManaged {
// Setup a machine level policy.
SetPolicy(false, policy::key::kTranslateEnabled);
// Open the management page and check if the content is expected.
[ChromeEarlGrey loadURL:GURL(kChromeUIManagementURL)];
[ChromeEarlGrey
waitForWebStateContainingText:l10n_util::GetStringUTF8(
IDS_IOS_MANAGEMENT_UI_MESSAGE)];
// Open the "learn more" link.
[ChromeEarlGrey tapWebStateElementWithID:@"learn-more-link"];
}
// Tests the chrome://management page when there are machine level policies.
- (void)testManagementPageManagedWithCBCM {
_server = std::make_unique<policy::EmbeddedPolicyTestServer>();
_server->Start();
// Enable machine level (browser) cloud policies.
AppLaunchConfiguration config;
config.additional_args.push_back(
base::StrCat({"--", switches::kEnableChromeBrowserCloudManagement}));
config.additional_args.push_back("-com.apple.configuration.managed");
// Use an enrollment token that will start chrome browser cloud management
// without making network calls.
config.additional_args.push_back(
base::StrCat({"<dict><key>CloudManagementEnrollmentToken</key><string>",
policy::kInvalidEnrollmentToken, "</string></dict>"}));
// Use the embedded test server as the policy server.
config.additional_args.push_back(
base::StrCat({"--", policy::switches::kDeviceManagementUrl, "=",
_server->GetServiceURL().spec()}));
[[AppLaunchManager sharedManager] ensureAppLaunchedWithConfiguration:config];
[PolicyAppInterface setBrowserCloudPolicyDataWithDomain:kDomain1];
// Open the management page and check if the content is expected.
[ChromeEarlGrey loadURL:GURL(kChromeUIManagementURL)];
[ChromeEarlGrey
waitForWebStateContainingText:l10n_util::GetStringFUTF8(
IDS_MANAGEMENT_SUBTITLE_MANAGED_BY,
base::SysNSStringToUTF16(kDomain1))];
}
// Tests the chrome://management page when there are user level policies.
- (void)testManagementPageManagedWithUserPolicy {
// Sign in with a managed account.
NSString* managedAccountEmail =
[@"enterprise@" stringByAppendingString:kDomain1];
FakeSystemIdentity* fakeManagedIdentity =
[FakeSystemIdentity identityWithEmail:managedAccountEmail];
[SigninEarlGrey
signinWithFakeManagedIdentityInPersonalProfile:fakeManagedIdentity];
// Open the management page and check if the content is expected.
[ChromeEarlGrey loadURL:GURL(kChromeUIManagementURL)];
[ChromeEarlGrey
waitForWebStateContainingText:
l10n_util::GetStringFUTF8(IDS_MANAGEMENT_SUBTITLE_PROFILE_MANAGED_BY,
base::SysNSStringToUTF16(kDomain1))];
}
// Tests the chrome://management page when there are machine level policies and
// user level policies from the same domain.
- (void)testManagementPageManagedWithCBCMAndUserPolicyDifferentDomains {
_server = std::make_unique<policy::EmbeddedPolicyTestServer>();
_server->Start();
// Enable browser cloud policies.
AppLaunchConfiguration config;
config.additional_args.push_back(
base::StrCat({"--", switches::kEnableChromeBrowserCloudManagement}));
config.additional_args.push_back("-com.apple.configuration.managed");
// Use a CBCM enrollment token that will start chrome browser cloud management
// without making network calls.
config.additional_args.push_back(
base::StrCat({"<dict><key>CloudManagementEnrollmentToken</key><string>",
policy::kInvalidEnrollmentToken, "</string></dict>"}));
// Use the embedded test server as the policy server.
config.additional_args.push_back(
base::StrCat({"--", policy::switches::kDeviceManagementUrl, "=",
_server->GetServiceURL().spec()}));
[[AppLaunchManager sharedManager] ensureAppLaunchedWithConfiguration:config];
// Set CBCM policies.
[PolicyAppInterface setBrowserCloudPolicyDataWithDomain:kDomain1];
// Sign in with managed account to enable User Policy.
NSString* managedAccountEmail =
[@"enterprise@" stringByAppendingString:kDomain2];
FakeSystemIdentity* fakeManagedIdentity =
[FakeSystemIdentity identityWithEmail:managedAccountEmail];
[SigninEarlGrey
signinWithFakeManagedIdentityInPersonalProfile:fakeManagedIdentity];
// Open the management page and check if the content is expected.
[ChromeEarlGrey loadURL:GURL(kChromeUIManagementURL)];
[ChromeEarlGrey
waitForWebStateContainingText:
l10n_util::GetStringFUTF8(
IDS_MANAGEMENT_SUBTITLE_BROWSER_AND_PROFILE_DIFFERENT_MANAGED_BY,
base::SysNSStringToUTF16(kDomain1),
base::SysNSStringToUTF16(kDomain2))];
}
// Tests the chrome://management page when there are machine level policies and
// user level policies from different domains.
- (void)testManagementPageManagedWithCBCMAndUserPolicySameDomains {
_server = std::make_unique<policy::EmbeddedPolicyTestServer>();
_server->Start();
// Enable browser cloud policies.
AppLaunchConfiguration config;
config.additional_args.push_back(
base::StrCat({"--", switches::kEnableChromeBrowserCloudManagement}));
config.additional_args.push_back("-com.apple.configuration.managed");
// Use a CBCM enrollment token that will start chrome browser cloud management
// without making network calls.
config.additional_args.push_back(
base::StrCat({"<dict><key>CloudManagementEnrollmentToken</key><string>",
policy::kInvalidEnrollmentToken, "</string></dict>"}));
// Use the embedded test server as the policy server.
config.additional_args.push_back(
base::StrCat({"--", policy::switches::kDeviceManagementUrl, "=",
_server->GetServiceURL().spec()}));
[[AppLaunchManager sharedManager] ensureAppLaunchedWithConfiguration:config];
// Set CBCM policies.
[PolicyAppInterface setBrowserCloudPolicyDataWithDomain:kDomain1];
// Sign in with managed account to enable User Policy.
NSString* managedAccountEmail =
[@"enterprise@" stringByAppendingString:kDomain1];
FakeSystemIdentity* fakeManagedIdentity =
[FakeSystemIdentity identityWithEmail:managedAccountEmail];
[SigninEarlGrey
signinWithFakeManagedIdentityInPersonalProfile:fakeManagedIdentity];
// Open the management page and check if the content is expected.
[ChromeEarlGrey loadURL:GURL(kChromeUIManagementURL)];
[ChromeEarlGrey
waitForWebStateContainingText:
l10n_util::GetStringFUTF8(
IDS_MANAGEMENT_SUBTITLE_BROWSER_AND_PROFILE_SAME_MANAGED_BY,
base::SysNSStringToUTF16(kDomain1))];
}
// Tests the chrome://management page when the security event connector is
// enabled.
- (void)testManagementPageManagedSecurityEventConnector {
_server =
enterprise_connectors::test::CreatePolicyTestServerForSecurityEvents();
CHECK(_server);
CHECK(_server->Start());
AppLaunchConfiguration config;
config.additional_args.push_back(
base::StrCat({"--", switches::kEnableChromeBrowserCloudManagement}));
config.additional_args.push_back(base::StrCat(
{"-", base::SysNSStringToUTF8(kPolicyLoaderIOSConfigurationKey)}));
config.additional_args.push_back(
base::StrCat({"<dict><key>", policy::key::kCloudManagementEnrollmentToken,
"</key><string>", kEnrollmentToken, "</string></dict>"}));
config.additional_args.push_back(
base::StrCat({"--", policy::switches::kDeviceManagementUrl, "=",
_server->GetServiceURL().spec()}));
[[AppLaunchManager sharedManager] ensureAppLaunchedWithConfiguration:config];
[ChromeEarlGrey loadURL:GURL(kChromeUIManagementURL)];
// Check that the management domain is part of the connectors disclaimer.
[ChromeEarlGrey
waitForWebStateContainingText:
l10n_util::GetStringFUTF8(
IDS_MANAGEMENT_THREAT_PROTECTION_DESCRIPTION_BY, u"example.com")];
// Validate that the Connectors section is visible.
GREYAssertTrue(
[ChromeEarlGrey
webStateContainsElement:VisibleElementSelector(@"connectors-info")],
@"Connectors section is not visible.");
// Validate that the security event section is visible.
GREYAssertTrue(
[ChromeEarlGrey webStateContainsElement:VisibleElementSelector(
@"security-event-section")],
@"Enterprise Security event section not shown.");
}
// Tests that when the BrowserSignin policy is updated while the app is not
// launched, a policy screen is displayed at startup.
- (void)testBrowserSignInDisabledAtStartup {
FakeSystemIdentity* fakeIdentity = [FakeSystemIdentity fakeIdentity1];
[SigninEarlGrey signinWithFakeIdentity:fakeIdentity];
// Create the config to relaunch Chrome.
AppLaunchConfiguration config;
config.relaunch_policy = ForceRelaunchByCleanShutdown;
// Configure the policy to disable SignIn.
std::string policy_data = "<dict>"
" <key>BrowserSignin</key>"
" <integer>0</integer>"
"</dict>";
base::RemoveChars(policy_data, base::kWhitespaceASCII, &policy_data);
config.additional_args.push_back(
"-" + base::SysNSStringToUTF8(kPolicyLoaderIOSConfigurationKey));
config.additional_args.push_back(policy_data);
// Add the switch to make sure that fakeIdentity1 is known at startup to avoid
// automatic sign out.
config.additional_args.push_back(std::string("-") +
test_switches::kAddFakeIdentitiesAtStartup);
// Relaunch the app to take the configuration into account.
[[AppLaunchManager sharedManager] ensureAppLaunchedWithConfiguration:config];
// Check that the sign out pop up is presented.
ConditionBlock condition = ^{
NSError* error = nil;
[[EarlGrey
selectElementWithMatcher:grey_accessibilityLabel(l10n_util::GetNSString(
IDS_IOS_ENTERPRISE_SIGNED_OUT))]
assertWithMatcher:grey_sufficientlyVisible()
error:&error];
return error == nil;
};
bool promptPresented = base::test::ios::WaitUntilConditionOrTimeout(
base::test::ios::kWaitForUIElementTimeout, condition);
GREYAssertTrue(promptPresented, @"'Signed Out' prompt not shown");
}
// Tests that the UI notifying the user of their sign out is displayed when the
// policy changes while the app is launched.
- (void)testBrowserSignInDisabledWhileAppVisible {
FakeSystemIdentity* fakeIdentity = [FakeSystemIdentity fakeIdentity1];
[SigninEarlGrey signinWithFakeIdentity:fakeIdentity];
// Force sign out.
SetPolicy(0, policy::key::kBrowserSignin);
// Check that the sign out pop up is presented.
ConditionBlock condition = ^{
NSError* error = nil;
[[EarlGrey
selectElementWithMatcher:grey_accessibilityLabel(l10n_util::GetNSString(
IDS_IOS_ENTERPRISE_SIGNED_OUT))]
assertWithMatcher:grey_sufficientlyVisible()
error:&error];
return error == nil;
};
bool promptPresented = base::test::ios::WaitUntilConditionOrTimeout(
base::test::ios::kWaitForUIElementTimeout, condition);
GREYAssertTrue(promptPresented, @"'Signed Out' prompt not shown");
}
// Tests that the UI notifying the user of their sign out is displayed when the
// primary account is restricted.
- (void)testBrowserAccountRestrictedAlert {
FakeSystemIdentity* fakeIdentity = [FakeSystemIdentity fakeIdentity1];
[SigninEarlGrey signinWithFakeIdentity:fakeIdentity];
// Set restrictions.
base::Value::List restrictions;
restrictions.Append("restricted");
SetPolicy(base::Value(std::move(restrictions)),
policy::key::kRestrictAccountsToPatterns);
// Check that the sign out pop up is presented.
ConditionBlock condition = ^{
NSError* error = nil;
[[EarlGrey
selectElementWithMatcher:grey_accessibilityLabel(l10n_util::GetNSString(
IDS_IOS_ENTERPRISE_SIGNED_OUT))]
assertWithMatcher:grey_sufficientlyVisible()
error:&error];
return error == nil;
};
bool promptPresented = base::test::ios::WaitUntilConditionOrTimeout(
base::test::ios::kWaitForUIElementTimeout, condition);
GREYAssertTrue(promptPresented, @"'Signed Out' prompt not shown");
}
// Tests that the UI notifying the user is displayed when sync is disabled by an
// administrator while the app is launched.
- (void)testSyncDisabledPromptWhileAppVisible {
FakeSystemIdentity* fakeIdentity = [FakeSystemIdentity fakeIdentity1];
[SigninEarlGrey signinWithFakeIdentity:fakeIdentity];
// Enable SyncDisabled policy.
SetPolicy(true, policy::key::kSyncDisabled);
// Check that the prompt is presented.
ConditionBlock condition = ^{
NSError* error = nil;
NSString* noticeTitle =
l10n_util::GetNSString(IDS_IOS_ENTERPRISE_SYNC_DISABLED_TITLE_WITH_UNO);
[[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(noticeTitle)]
assertWithMatcher:grey_sufficientlyVisible()
error:&error];
return error == nil;
};
bool promptPresented = base::test::ios::WaitUntilConditionOrTimeout(
base::test::ios::kWaitForUIElementTimeout, condition);
GREYAssertTrue(promptPresented, @"'Sync Disabled' prompt not shown");
}
// Tests enterprise mode in the Privacy Safe Browsing settings as if the
// enterprise selected No Protection as the choice of protection.
- (void)testEnterpriseBubbleInEnhancedSafeBrowsingPage {
SetPolicy(0, policy::key::kSafeBrowsingProtectionLevel);
[ChromeEarlGreyUI openSettingsMenu];
[ChromeEarlGreyUI
tapSettingsMenuButton:chrome_test_util::SettingsMenuPrivacyButton()];
[ChromeEarlGreyUI
tapPrivacyMenuButton:chrome_test_util::ButtonWithAccessibilityLabelId(
IDS_IOS_PRIVACY_SAFE_BROWSING_TITLE)];
// Tap the info button on row. Accessibility point has been changed in this
// TableViewInfoButtonItem to be on the center of the row instead of on the
// "i" button. To tap the "i" button, we select the info button as the
// matcher instead of the row.
[[EarlGrey
selectElementWithMatcher:
grey_allOf(grey_ancestor(grey_accessibilityID(
kSettingsSafeBrowsingEnhancedProtectionCellId)),
grey_accessibilityID(kTableViewCellInfoButtonViewId),
grey_sufficientlyVisible(), nil)]
performAction:grey_tap()];
// Check if the contextual bubble is shown.
[[EarlGrey selectElementWithMatcher:grey_accessibilityID(
kEnterpriseInfoBubbleViewId)]
assertWithMatcher:grey_sufficientlyVisible()];
// Tap outside of the bubble.
[[EarlGrey
selectElementWithMatcher:
grey_accessibilityID(kSettingsSafeBrowsingEnhancedProtectionCellId)]
performAction:grey_tap()];
// Check if the contextual bubble is hidden.
[[EarlGrey selectElementWithMatcher:grey_accessibilityID(
kEnterpriseInfoBubbleViewId)]
assertWithMatcher:grey_notVisible()];
}
@end