| Index: ios/chrome/browser/ui/settings/settings_egtest.mm
|
| diff --git a/ios/chrome/browser/ui/settings/settings_egtest.mm b/ios/chrome/browser/ui/settings/settings_egtest.mm
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..41b8fcee911bece52714fe778cfe6bd180171f26
|
| --- /dev/null
|
| +++ b/ios/chrome/browser/ui/settings/settings_egtest.mm
|
| @@ -0,0 +1,868 @@
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#import <EarlGrey/EarlGrey.h>
|
| +#import <UIKit/UIKit.h>
|
| +#import <XCTest/XCTest.h>
|
| +#include <map>
|
| +
|
| +#include "base/bind.h"
|
| +#import "base/mac/bind_objc_block.h"
|
| +#include "base/memory/ptr_util.h"
|
| +#include "base/strings/sys_string_conversions.h"
|
| +#include "components/browsing_data/core/pref_names.h"
|
| +#include "components/metrics/metrics_pref_names.h"
|
| +#include "components/password_manager/core/common/password_manager_pref_names.h"
|
| +#include "components/prefs/pref_member.h"
|
| +#include "components/prefs/pref_service.h"
|
| +#include "components/strings/grit/components_strings.h"
|
| +#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
|
| +#include "ios/chrome/browser/content_settings/host_content_settings_map_factory.h"
|
| +#include "ios/chrome/browser/pref_names.h"
|
| +#import "ios/chrome/browser/ui/settings/clear_browsing_data_collection_view_controller.h"
|
| +#import "ios/chrome/browser/ui/settings/settings_collection_view_controller.h"
|
| +#import "ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.h"
|
| +#import "ios/chrome/browser/ui/tools_menu/tools_popup_controller.h"
|
| +#include "ios/chrome/grit/ios_chromium_strings.h"
|
| +#include "ios/chrome/grit/ios_strings.h"
|
| +#include "ios/chrome/grit/ios_theme_resources.h"
|
| +#import "ios/chrome/test/app/chrome_test_util.h"
|
| +#import "ios/chrome/test/app/navigation_test_util.h"
|
| +#import "ios/chrome/test/app/tab_test_util.h"
|
| +#include "ios/chrome/test/app/web_view_interaction_test_util.h"
|
| +#import "ios/chrome/test/earl_grey/accessibility_util.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/web/public/test/http_server.h"
|
| +#import "ios/web/public/test/http_server_util.h"
|
| +#import "ios/web/public/test/web_view_interaction_test_util.h"
|
| +#include "ios/web/public/web_state/web_state.h"
|
| +#include "ios/web/public/web_thread.h"
|
| +#include "net/ssl/channel_id_service.h"
|
| +#include "net/ssl/channel_id_store.h"
|
| +#include "net/url_request/url_request_context.h"
|
| +#include "net/url_request/url_request_context_getter.h"
|
| +#include "ui/base/l10n/l10n_util.h"
|
| +#include "url/gurl.h"
|
| +
|
| +using chrome_test_util::buttonWithAccessibilityLabelId;
|
| +
|
| +namespace {
|
| +
|
| +const char kTestOrigin1[] = "http://host1:1/";
|
| +
|
| +const char kUrl[] = "http://foo/browsing";
|
| +const char kUrlWithSetCookie[] = "http://foo/set_cookie";
|
| +const char kResponse[] = "bar";
|
| +const char kResponseWithSetCookie[] = "bar with set cookie";
|
| +const char kNoCookieText[] = "No cookies";
|
| +const char kCookie[] = "a=b";
|
| +const char kJavaScriptGetCookies[] =
|
| + "var c = document.cookie ? document.cookie.split(/;\\s*/) : [];"
|
| + "if (!c.length) {"
|
| + " document.documentElement.innerHTML = 'No cookies!';"
|
| + "} else {"
|
| + " document.documentElement.innerHTML = 'OK: ' + c.join(',');"
|
| + "}";
|
| +
|
| +enum MetricsServiceType {
|
| + kMetrics,
|
| + kBreakpad,
|
| + kBreakpadFirstLaunch,
|
| +};
|
| +
|
| +// Matcher for the clear browsing history cell on the clear browsing data panel.
|
| +id<GREYMatcher> clearBrowsingHistoryButton() {
|
| + return grey_allOf(grey_accessibilityID(kClearBrowsingHistoryCellId),
|
| + grey_sufficientlyVisible(), nil);
|
| +}
|
| +// Matcher for the clear cookies cell on the clear browsing data panel.
|
| +id<GREYMatcher> clearCookiesButton() {
|
| + return grey_accessibilityID(kClearCookiesCellId);
|
| +}
|
| +// Matcher for the clear cache cell on the clear browsing data panel.
|
| +id<GREYMatcher> clearCacheButton() {
|
| + return grey_allOf(grey_accessibilityID(kClearCacheCellId),
|
| + grey_sufficientlyVisible(), nil);
|
| +}
|
| +// Matcher for the clear saved passwords cell on the clear browsing data panel.
|
| +id<GREYMatcher> clearSavedPasswordsButton() {
|
| + return grey_allOf(grey_accessibilityID(kClearSavedPasswordsCellId),
|
| + grey_sufficientlyVisible(), nil);
|
| +}
|
| +// Matcher for the clear browsing data button on the clear browsing data panel.
|
| +id<GREYMatcher> clearBrowsingDataButton() {
|
| + return buttonWithAccessibilityLabelId(IDS_IOS_CLEAR_BUTTON);
|
| +}
|
| +// Matcher for the done button in the navigation bar.
|
| +id<GREYMatcher> navigationDoneButton() {
|
| + return buttonWithAccessibilityLabelId(IDS_IOS_NAVIGATION_BAR_DONE_BUTTON);
|
| +}
|
| +// Matcher for the Settings button in the tools menu.
|
| +id<GREYMatcher> settingsButton() {
|
| + return grey_accessibilityID(kToolsMenuSettingsId);
|
| +}
|
| +// Matcher for the Save Passwords cell on the main Settings screen.
|
| +id<GREYMatcher> passwordsButton() {
|
| + return buttonWithAccessibilityLabelId(IDS_IOS_SAVE_PASSWORDS);
|
| +}
|
| +// Matcher for the Privacy cell on the main Settings screen.
|
| +id<GREYMatcher> privacyButton() {
|
| + return buttonWithAccessibilityLabelId(
|
| + IDS_OPTIONS_ADVANCED_SECTION_TITLE_PRIVACY);
|
| +}
|
| +// Matcher for the Clear Browsing Data cell on the Privacy screen.
|
| +id<GREYMatcher> clearBrowsingDataCell() {
|
| + return buttonWithAccessibilityLabelId(IDS_IOS_CLEAR_BROWSING_DATA_TITLE);
|
| +}
|
| +
|
| +// Matcher for the Search Engine cell on the main Settings screen.
|
| +id<GREYMatcher> searchEngineButton() {
|
| + return buttonWithAccessibilityLabelId(IDS_IOS_SEARCH_ENGINE_SETTING_TITLE);
|
| +}
|
| +
|
| +// Matcher for the Autofill Forms cell on the main Settings screen.
|
| +id<GREYMatcher> autofillButton() {
|
| + return buttonWithAccessibilityLabelId(IDS_IOS_AUTOFILL);
|
| +}
|
| +
|
| +// Matcher for the Google Apps cell on the main Settings screen.
|
| +id<GREYMatcher> googleAppsButton() {
|
| + return buttonWithAccessibilityLabelId(IDS_IOS_GOOGLE_APPS_SM_SETTINGS);
|
| +}
|
| +
|
| +// Matcher for the Google Chrome cell on the main Settings screen.
|
| +id<GREYMatcher> googleChromeButton() {
|
| + return buttonWithAccessibilityLabelId(IDS_IOS_PRODUCT_NAME);
|
| +}
|
| +
|
| +// Matcher for the Google Chrome cell on the main Settings screen.
|
| +id<GREYMatcher> voiceSearchButton() {
|
| + return grey_allOf(grey_accessibilityID(kSettingsVoiceSearchCellId),
|
| + grey_accessibilityTrait(UIAccessibilityTraitButton), nil);
|
| +}
|
| +
|
| +// Asserts that there is no cookie in current web state.
|
| +void AssertNoCookieExists() {
|
| + NSError* error = nil;
|
| + chrome_test_util::ExecuteJavaScript(
|
| + base::SysUTF8ToNSString(kJavaScriptGetCookies), &error);
|
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::webViewContainingText(
|
| + kNoCookieText)]
|
| + assertWithMatcher:grey_notNil()];
|
| +}
|
| +
|
| +// Asserts |cookie| exists in current web state.
|
| +void AssertCookieExists(const char cookie[]) {
|
| + NSError* error = nil;
|
| + chrome_test_util::ExecuteJavaScript(
|
| + base::SysUTF8ToNSString(kJavaScriptGetCookies), &error);
|
| + NSString* const expectedCookieText =
|
| + [NSString stringWithFormat:@"OK: %@", base::SysUTF8ToNSString(cookie)];
|
| + [[EarlGrey
|
| + selectElementWithMatcher:chrome_test_util::webViewContainingText(
|
| + base::SysNSStringToUTF8(expectedCookieText))]
|
| + assertWithMatcher:grey_notNil()];
|
| +}
|
| +
|
| +// Run as a task to check if a certificate has been added to the ChannelIDStore.
|
| +// Signals the given |semaphore| if the cert was added, or reposts itself
|
| +// otherwise.
|
| +void CheckCertificate(scoped_refptr<net::URLRequestContextGetter> getter,
|
| + dispatch_semaphore_t semaphore) {
|
| + net::ChannelIDService* channel_id_service =
|
| + getter->GetURLRequestContext()->channel_id_service();
|
| + if (channel_id_service->channel_id_count() == 0) {
|
| + // If the channel_id_count is still 0, no certs have been added yet.
|
| + // Re-post this task and check again later.
|
| + web::WebThread::PostTask(web::WebThread::IO, FROM_HERE,
|
| + base::Bind(&CheckCertificate, getter, semaphore));
|
| + } else {
|
| + // If certs have been added, signal the calling thread.
|
| + dispatch_semaphore_signal(semaphore);
|
| + }
|
| +}
|
| +
|
| +// Set certificate for host |kTestOrigin1| for testing.
|
| +void SetCertificate() {
|
| + ios::ChromeBrowserState* browserState =
|
| + chrome_test_util::GetOriginalBrowserState();
|
| + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
|
| + scoped_refptr<net::URLRequestContextGetter> getter =
|
| + browserState->GetRequestContext();
|
| + web::WebThread::PostTask(
|
| + web::WebThread::IO, FROM_HERE, base::BindBlock(^{
|
| + net::ChannelIDService* channel_id_service =
|
| + getter->GetURLRequestContext()->channel_id_service();
|
| + net::ChannelIDStore* channel_id_store =
|
| + channel_id_service->GetChannelIDStore();
|
| + base::Time now = base::Time::Now();
|
| + channel_id_store->SetChannelID(
|
| + base::MakeUnique<net::ChannelIDStore::ChannelID>(
|
| + kTestOrigin1, now, crypto::ECPrivateKey::Create()));
|
| + }));
|
| +
|
| + // The ChannelIDStore may not be loaded, so adding the new cert may not happen
|
| + // immediately. This posted task signals the semaphore if the cert was added,
|
| + // or re-posts itself to check again later otherwise.
|
| + web::WebThread::PostTask(web::WebThread::IO, FROM_HERE,
|
| + base::Bind(&CheckCertificate, getter, semaphore));
|
| +
|
| + dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
|
| + dispatch_release(semaphore);
|
| +}
|
| +
|
| +// Fetching channel id is expected to complete immediately in this test, so a
|
| +// dummy callback function is set for testing.
|
| +void CertCallback(int err,
|
| + const std::string& server_identifier,
|
| + std::unique_ptr<crypto::ECPrivateKey> key) {}
|
| +
|
| +// Check if certificate is empty for host |kTestOrigin1|.
|
| +bool IsCertificateCleared() {
|
| + ios::ChromeBrowserState* browserState =
|
| + chrome_test_util::GetOriginalBrowserState();
|
| + __block int result;
|
| + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
|
| + scoped_refptr<net::URLRequestContextGetter> getter =
|
| + browserState->GetRequestContext();
|
| + web::WebThread::PostTask(
|
| + web::WebThread::IO, FROM_HERE, base::BindBlock(^{
|
| + net::ChannelIDService* channel_id_service =
|
| + getter->GetURLRequestContext()->channel_id_service();
|
| + std::unique_ptr<crypto::ECPrivateKey> dummy_key;
|
| + result = channel_id_service->GetChannelIDStore()->GetChannelID(
|
| + kTestOrigin1, &dummy_key, base::Bind(CertCallback));
|
| + dispatch_semaphore_signal(semaphore);
|
| + }));
|
| + dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
|
| + dispatch_release(semaphore);
|
| + return result == net::ERR_FILE_NOT_FOUND;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +// Settings tests for Chrome.
|
| +@interface SettingsTestCase : ChromeTestCase
|
| +@end
|
| +
|
| +@implementation SettingsTestCase
|
| +
|
| +// Opens the a submenu from the settings page. Must be called from the NTP.
|
| +- (void)openSubSettingMenu:(id<GREYMatcher>)settingToTap {
|
| + const CGFloat kScrollDisplacement = 150.0;
|
| + id<GREYMatcher> toolsMenuTableViewMatcher =
|
| + grey_accessibilityID(kToolsMenuTableViewId);
|
| + id<GREYMatcher> settingsButtonMatcher =
|
| + grey_accessibilityID(kToolsMenuSettingsId);
|
| + id<GREYMatcher> settingsCollectionViewMatcher =
|
| + grey_accessibilityID(kSettingsCollectionViewId);
|
| +
|
| + [ChromeEarlGreyUI openToolsMenu];
|
| + [[[EarlGrey selectElementWithMatcher:settingsButtonMatcher]
|
| + usingSearchAction:grey_scrollInDirection(kGREYDirectionDown,
|
| + kScrollDisplacement)
|
| + onElementWithMatcher:toolsMenuTableViewMatcher] performAction:grey_tap()];
|
| + [[[EarlGrey selectElementWithMatcher:settingToTap]
|
| + usingSearchAction:grey_scrollInDirection(kGREYDirectionDown,
|
| + kScrollDisplacement)
|
| + onElementWithMatcher:settingsCollectionViewMatcher]
|
| + performAction:grey_tap()];
|
| +}
|
| +
|
| +// Closes the a sub-settings menu, and then the general Settings menu.
|
| +- (void)closeSubSettingsMenu {
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_allOf(
|
| + grey_accessibilityID(@"back_bar_button"),
|
| + grey_accessibilityTrait(
|
| + UIAccessibilityTraitButton),
|
| + nil)] performAction:grey_tap()];
|
| + [[EarlGrey
|
| + selectElementWithMatcher:chrome_test_util::buttonWithAccessibilityLabelId(
|
| + IDS_IOS_NAVIGATION_BAR_DONE_BUTTON)]
|
| + performAction:grey_tap()];
|
| +}
|
| +
|
| +// Performs the steps to clear browsing data. Must be called on the
|
| +// Clear Browsing Data settings screen, after having selected the data types
|
| +// scheduled for removal.
|
| +- (void)clearBrowsingData {
|
| + [[EarlGrey selectElementWithMatcher:clearBrowsingDataButton()]
|
| + performAction:grey_tap()];
|
| +
|
| + // There is not currently a matcher for accessibilityElementIsFocused or
|
| + // userInteractionEnabled which could be used here instead of checking that
|
| + // the button is not a MDCCollectionViewTextCell. Use when available.
|
| + // TODO(crbug.com/638674): Evaluate if this can move to shared code.
|
| + id<GREYMatcher> confirmClear = grey_allOf(
|
| + clearBrowsingDataButton(),
|
| + grey_not(grey_kindOfClass([MDCCollectionViewTextCell class])), nil);
|
| + [[EarlGrey selectElementWithMatcher:confirmClear] performAction:grey_tap()];
|
| +}
|
| +
|
| +// Exits Settings by clicking on the Done button.
|
| +- (void)dismissSettings {
|
| + // Dismiss the settings.
|
| + [[EarlGrey selectElementWithMatcher:navigationDoneButton()]
|
| + performAction:grey_tap()];
|
| +
|
| + // Wait for UI components to finish loading.
|
| + [[GREYUIThreadExecutor sharedInstance] drainUntilIdle];
|
| +}
|
| +
|
| +// From the NTP, clears the cookies and site data via the UI.
|
| +- (void)clearCookiesAndSiteData {
|
| + [ChromeEarlGreyUI openToolsMenu];
|
| + [[EarlGrey selectElementWithMatcher:settingsButton()]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:privacyButton()]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:clearBrowsingDataCell()]
|
| + performAction:grey_tap()];
|
| +
|
| + // "Browsing history", "Cookies, Site Data" and "Cached Images and Files"
|
| + // are the default checked options when the prefs are registered. Uncheck
|
| + // "Browsing history" and "Cached Images and Files".
|
| + // Prefs are reset to default at the end of each test.
|
| + [[EarlGrey selectElementWithMatcher:clearBrowsingHistoryButton()]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:clearCacheButton()]
|
| + performAction:grey_tap()];
|
| +
|
| + [self clearBrowsingData];
|
| + [self dismissSettings];
|
| +}
|
| +
|
| +// From the NTP, clears the saved passwords via the UI.
|
| +- (void)clearPasswords {
|
| + [ChromeEarlGreyUI openToolsMenu];
|
| + [[EarlGrey selectElementWithMatcher:settingsButton()]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:privacyButton()]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:clearBrowsingDataCell()]
|
| + performAction:grey_tap()];
|
| +
|
| + // "Browsing history", "Cookies, Site Data" and "Cached Images and Files"
|
| + // are the default checked options when the prefs are registered. Unckeck all
|
| + // of them and check "Passwords".
|
| + [[EarlGrey selectElementWithMatcher:clearBrowsingHistoryButton()]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:clearCookiesButton()]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:clearCacheButton()]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:clearSavedPasswordsButton()]
|
| + performAction:grey_tap()];
|
| +
|
| + [self clearBrowsingData];
|
| +
|
| + // Re-tap all the previously tapped cells, so that the default state of the
|
| + // checkmarks is preserved.
|
| + [[EarlGrey selectElementWithMatcher:clearBrowsingHistoryButton()]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:clearCookiesButton()]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:clearCacheButton()]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:clearSavedPasswordsButton()]
|
| + performAction:grey_tap()];
|
| +
|
| + [self dismissSettings];
|
| +}
|
| +
|
| +// Checks the presence (or absence) of saved passwords.
|
| +// If |saved| is YES, it checks that there is a Saved Passwords section.
|
| +// If |saved| is NO, it checks that there is no Saved Passwords section.
|
| +- (void)checkIfPasswordsSaved:(BOOL)saved {
|
| + [ChromeEarlGreyUI openToolsMenu];
|
| + [[EarlGrey selectElementWithMatcher:settingsButton()]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:passwordsButton()]
|
| + performAction:grey_tap()];
|
| +
|
| + id<GREYMatcher> visibilityMatcher =
|
| + saved ? grey_sufficientlyVisible() : grey_notVisible();
|
| + [[EarlGrey selectElementWithMatcher:
|
| + grey_text(l10n_util::GetNSString(
|
| + IDS_PASSWORD_MANAGER_SHOW_PASSWORDS_TAB_TITLE))]
|
| + assertWithMatcher:visibilityMatcher];
|
| +
|
| + // Close the Settings.
|
| + [self closeSubSettingsMenu];
|
| +}
|
| +
|
| +// Checks for a given service that it is both recording and uploading, where
|
| +// appropriate.
|
| +- (void)assertMetricsServiceEnabled:(MetricsServiceType)serviceType {
|
| + switch (serviceType) {
|
| + case kMetrics:
|
| + GREYAssertTrue(chrome_test_util::IsMetricsRecordingEnabled(),
|
| + @"Metrics recording should be enabled.");
|
| + GREYAssertTrue(chrome_test_util::IsMetricsReportingEnabled(),
|
| + @"Metrics reporting should be enabled.");
|
| + break;
|
| + case kBreakpad:
|
| + GREYAssertTrue(chrome_test_util::IsBreakpadEnabled(),
|
| + @"Breakpad should be enabled.");
|
| + GREYAssertTrue(chrome_test_util::IsBreakpadReportingEnabled(),
|
| + @"Breakpad reporting should be enabled.");
|
| + break;
|
| + case kBreakpadFirstLaunch:
|
| + // For first launch after upgrade, or after install, uploading of crash
|
| + // reports is always disabled. Check that the first launch flag is being
|
| + // honored.
|
| + GREYAssertTrue(chrome_test_util::IsBreakpadEnabled(),
|
| + @"Breakpad should be enabled.");
|
| + GREYAssertFalse(chrome_test_util::IsBreakpadReportingEnabled(),
|
| + @"Breakpad reporting should be disabled.");
|
| + break;
|
| + }
|
| +}
|
| +
|
| +// Checks for a given service that it is completely disabled.
|
| +- (void)assertMetricsServiceDisabled:(MetricsServiceType)serviceType {
|
| + switch (serviceType) {
|
| + case kMetrics: {
|
| + GREYAssertFalse(chrome_test_util::IsMetricsRecordingEnabled(),
|
| + @"Metrics recording should be disabled.");
|
| + GREYAssertFalse(chrome_test_util::IsMetricsReportingEnabled(),
|
| + @"Metrics reporting should be disabled.");
|
| + break;
|
| + }
|
| + case kBreakpad:
|
| + case kBreakpadFirstLaunch: {
|
| + // Check only whether or not breakpad is enabled. Disabling
|
| + // breakpad does stop uploading, and does not change the flag
|
| + // used to check whether or not it's uploading.
|
| + GREYAssertFalse(chrome_test_util::IsBreakpadEnabled(),
|
| + @"Breakpad should be disabled.");
|
| + break;
|
| + }
|
| + }
|
| +}
|
| +
|
| +// Checks for a given service that it is recording, but not uploading anything.
|
| +// Used to test that the wifi-only preference is honored when the device is
|
| +// using a cellular network.
|
| +- (void)assertMetricsServiceEnabledButNotUploading:
|
| + (MetricsServiceType)serviceType {
|
| + switch (serviceType) {
|
| + case kMetrics: {
|
| + GREYAssertTrue(chrome_test_util::IsMetricsRecordingEnabled(),
|
| + @"Metrics recording should be enabled.");
|
| + GREYAssertFalse(chrome_test_util::IsMetricsReportingEnabled(),
|
| + @"Metrics reporting should be disabled.");
|
| + break;
|
| + }
|
| + case kBreakpad:
|
| + case kBreakpadFirstLaunch: {
|
| + GREYAssertTrue(chrome_test_util::IsBreakpadEnabled(),
|
| + @"Breakpad should be enabled.");
|
| + GREYAssertFalse(chrome_test_util::IsBreakpadReportingEnabled(),
|
| + @"Breakpad reporting should be disabled.");
|
| + break;
|
| + }
|
| + }
|
| +}
|
| +
|
| +- (void)assertsMetricsPrefsForService:(MetricsServiceType)serviceType {
|
| + // Two preferences, each with two values - on or off. Check all four
|
| + // combinations:
|
| + // kMetricsReportingEnabled OFF and kMetricsReportingWifiOnly OFF
|
| + // - Services do not record data and do not upload data.
|
| +
|
| + // kMetricsReportingEnabled OFF and kMetricsReportingWifiOnly ON
|
| + // - Services do not record data and do not upload data.
|
| + // Note that if kMetricsReportingEnabled is OFF, the state of
|
| + // kMetricsReportingWifiOnly does not matter.
|
| +
|
| + // kMetricsReportingEnabled ON and kMetricsReportingWifiOnly ON
|
| + // - Services record data and upload data only when the device is using
|
| + // a wifi connection. Note: rather than checking for wifi, the code
|
| + // checks for a cellular network (wwan). wwan != wifi. So if wwan is
|
| + // true, services do not upload any data.
|
| +
|
| + // kMetricsReportingEnabled ON and kMetricsReportingWifiOnly OFF
|
| + // - Services record data and upload data.
|
| +
|
| + // kMetricsReportingEnabled OFF and kMetricsReportingWifiOnly OFF
|
| + chrome_test_util::SetBooleanLocalStatePref(
|
| + metrics::prefs::kMetricsReportingEnabled, NO);
|
| + chrome_test_util::SetBooleanLocalStatePref(prefs::kMetricsReportingWifiOnly,
|
| + NO);
|
| + // Service should be completely disabled.
|
| + // I.e. no recording of data, and no uploading of what's been recorded.
|
| + [self assertMetricsServiceDisabled:serviceType];
|
| +
|
| + // kMetricsReportingEnabled OFF and kMetricsReportingWifiOnly ON
|
| + chrome_test_util::SetBooleanLocalStatePref(
|
| + metrics::prefs::kMetricsReportingEnabled, NO);
|
| + chrome_test_util::SetBooleanLocalStatePref(prefs::kMetricsReportingWifiOnly,
|
| + YES);
|
| + // If kMetricsReportingEnabled is OFF, any service should remain completely
|
| + // disabled, i.e. no uploading even if kMetricsReportingWifiOnly is ON.
|
| + [self assertMetricsServiceDisabled:serviceType];
|
| +
|
| +// Split here: Official build vs. Development build.
|
| +// Official builds allow recording and uploading of data, honoring the
|
| +// metrics prefs. Development builds should never record or upload data.
|
| +#if defined(GOOGLE_CHROME_BUILD)
|
| + // Official build.
|
| + // The values of the prefs and the wwan vs wifi state should be honored by
|
| + // the services, turning on and off according to the rules laid out above.
|
| +
|
| + // kMetricsReportingEnabled ON and kMetricsReportingWifiOnly ON.
|
| + chrome_test_util::SetBooleanLocalStatePref(
|
| + metrics::prefs::kMetricsReportingEnabled, YES);
|
| + chrome_test_util::SetBooleanLocalStatePref(prefs::kMetricsReportingWifiOnly,
|
| + YES);
|
| + // Service should be enabled.
|
| + [self assertMetricsServiceEnabled:serviceType];
|
| +
|
| + // Set the network to use a cellular network, which should disable uploading
|
| + // when the wifi-only flag is set.
|
| + chrome_test_util::SetWWANStateTo(YES);
|
| + [self assertMetricsServiceEnabledButNotUploading:serviceType];
|
| +
|
| + // Turn off cellular network usage, which should enable uploading.
|
| + chrome_test_util::SetWWANStateTo(NO);
|
| + [self assertMetricsServiceEnabled:serviceType];
|
| +
|
| + // kMetricsReportingEnabled ON and kMetricsReportingWifiOnly OFF
|
| + chrome_test_util::SetBooleanLocalStatePref(
|
| + metrics::prefs::kMetricsReportingEnabled, YES);
|
| + chrome_test_util::SetBooleanLocalStatePref(prefs::kMetricsReportingWifiOnly,
|
| + NO);
|
| + // Service should be always enabled regardless of network settings.
|
| + chrome_test_util::SetWWANStateTo(YES);
|
| + [self assertMetricsServiceEnabled:serviceType];
|
| + chrome_test_util::SetWWANStateTo(NO);
|
| + [self assertMetricsServiceDisabled:serviceType];
|
| +#else
|
| + // Development build. Do not allow any recording or uploading of data.
|
| + // Specifically, the kMetricsReportingEnabled preference is completely
|
| + // disregarded for non-official builds, and checking its value always returns
|
| + // false (NO).
|
| + // This tests that no matter the state change, pref or network connection,
|
| + // services remain disabled.
|
| +
|
| + // kMetricsReportingEnabled ON and kMetricsReportingWifiOnly ON
|
| + chrome_test_util::SetBooleanLocalStatePref(
|
| + metrics::prefs::kMetricsReportingEnabled, YES);
|
| + chrome_test_util::SetBooleanLocalStatePref(prefs::kMetricsReportingWifiOnly,
|
| + YES);
|
| + // Service should remain disabled.
|
| + [self assertMetricsServiceDisabled:serviceType];
|
| +
|
| + // kMetricsReportingEnabled ON and kMetricsReportingWifiOnly OFF
|
| + chrome_test_util::SetBooleanLocalStatePref(
|
| + metrics::prefs::kMetricsReportingEnabled, YES);
|
| + chrome_test_util::SetBooleanLocalStatePref(prefs::kMetricsReportingWifiOnly,
|
| + NO);
|
| + // Service should remain disabled.
|
| + [self assertMetricsServiceDisabled:serviceType];
|
| +#endif
|
| +}
|
| +
|
| +#pragma mark Tests
|
| +
|
| +// Tests that clearing the cookies through the UI does clear all of them. Use a
|
| +// local server to navigate to a page that sets then tests a cookie, and then
|
| +// clears the cookie and tests it is not set.
|
| +// TODO(crbug.com/638674): Evaluate if this can move to shared code.
|
| +- (void)testClearCookies {
|
| + // Creates a map of canned responses and set up the test HTML server.
|
| + std::map<GURL, std::pair<std::string, std::string>> response;
|
| +
|
| + response[web::test::HttpServer::MakeUrl(kUrlWithSetCookie)] =
|
| + std::pair<std::string, std::string>(kCookie, kResponseWithSetCookie);
|
| + response[web::test::HttpServer::MakeUrl(kUrl)] =
|
| + std::pair<std::string, std::string>("", kResponse);
|
| +
|
| + web::test::SetUpSimpleHttpServerWithSetCookies(response);
|
| +
|
| + // Load |kUrl| and check that cookie is not set.
|
| + [ChromeEarlGrey loadURL:web::test::HttpServer::MakeUrl(kUrl)];
|
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::webViewContainingText(
|
| + kResponse)]
|
| + assertWithMatcher:grey_notNil()];
|
| + AssertNoCookieExists();
|
| +
|
| + // Visit |kUrlWithSetCookie| to set a cookie and then load |kUrl| to check it
|
| + // is still set.
|
| + [ChromeEarlGrey loadURL:web::test::HttpServer::MakeUrl(kUrlWithSetCookie)];
|
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::webViewContainingText(
|
| + kResponseWithSetCookie)]
|
| + assertWithMatcher:grey_notNil()];
|
| + [ChromeEarlGrey loadURL:web::test::HttpServer::MakeUrl(kUrl)];
|
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::webViewContainingText(
|
| + kResponse)]
|
| + assertWithMatcher:grey_notNil()];
|
| +
|
| + AssertCookieExists(kCookie);
|
| +
|
| + // Restore the Clear Browsing Data checkmarks prefs to their default state in
|
| + // Teardown.
|
| + [self setTearDownHandler:^{
|
| + ios::ChromeBrowserState* browserState =
|
| + chrome_test_util::GetOriginalBrowserState();
|
| + PrefService* preferences = browserState->GetPrefs();
|
| +
|
| + preferences->SetBoolean(browsing_data::prefs::kDeleteBrowsingHistory, true);
|
| + preferences->SetBoolean(browsing_data::prefs::kDeleteCache, true);
|
| + preferences->SetBoolean(browsing_data::prefs::kDeleteCookies, true);
|
| + preferences->SetBoolean(browsing_data::prefs::kDeletePasswords, false);
|
| + preferences->SetBoolean(browsing_data::prefs::kDeleteFormData, false);
|
| + }];
|
| +
|
| + // Clear all cookies.
|
| + [self clearCookiesAndSiteData];
|
| +
|
| + // Reload and test that there are no cookies left.
|
| + [ChromeEarlGrey loadURL:web::test::HttpServer::MakeUrl(kUrl)];
|
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::webViewContainingText(
|
| + kResponse)]
|
| + assertWithMatcher:grey_notNil()];
|
| + AssertNoCookieExists();
|
| + chrome_test_util::CloseAllTabs();
|
| +}
|
| +
|
| +// Verifies that logging into a form on a web page allows the user to save and
|
| +// then clear a password.
|
| +- (void)testClearPasswords {
|
| + std::map<GURL, std::string> responses;
|
| + const GURL URL = web::test::HttpServer::MakeUrl("http://testClearPasswords");
|
| + // TODO(crbug.com/432596): There looks to be a bug where the save password
|
| + // infobar is not displayed if the action is about:blank.
|
| + responses[URL] =
|
| + "<form method=\"POST\" action=\"dest\">"
|
| + "Username:<input type=\"text\" name=\"username\" value=\"name\" /><br />"
|
| + "Password:<input type=\"password\""
|
| + "name=\"password\" value=\"pass\"/><br />"
|
| + "<input type=\"submit\" value=\"Login\" id=\"Login\"/>"
|
| + "</form>";
|
| + const GURL destinationURL =
|
| + web::test::HttpServer::MakeUrl("http://testClearPasswords/dest");
|
| + responses[destinationURL] = "Logged in!";
|
| + web::test::SetUpSimpleHttpServer(responses);
|
| +
|
| + // Enable password management.
|
| + ios::ChromeBrowserState* browserState =
|
| + chrome_test_util::GetOriginalBrowserState();
|
| + PrefService* preferences = browserState->GetPrefs();
|
| + bool originalPasswordManagerSavingEnabled = preferences->GetBoolean(
|
| + password_manager::prefs::kPasswordManagerSavingEnabled);
|
| + preferences->SetBoolean(
|
| + password_manager::prefs::kPasswordManagerSavingEnabled, true);
|
| + [self setTearDownHandler:^{
|
| + // Restore the password management pref state.
|
| + ios::ChromeBrowserState* browserState =
|
| + chrome_test_util::GetOriginalBrowserState();
|
| + PrefService* preferences = browserState->GetPrefs();
|
| + preferences->SetBoolean(
|
| + password_manager::prefs::kPasswordManagerSavingEnabled,
|
| + originalPasswordManagerSavingEnabled);
|
| +
|
| + // Restore the Clear Browsing Data checkmarks prefs to their default state.
|
| + preferences->SetBoolean(browsing_data::prefs::kDeleteBrowsingHistory, true);
|
| + preferences->SetBoolean(browsing_data::prefs::kDeleteCache, true);
|
| + preferences->SetBoolean(browsing_data::prefs::kDeleteCookies, true);
|
| + preferences->SetBoolean(browsing_data::prefs::kDeletePasswords, false);
|
| + preferences->SetBoolean(browsing_data::prefs::kDeleteFormData, false);
|
| + }];
|
| +
|
| + // Clear passwords and check that none are saved.
|
| + [self clearPasswords];
|
| + [self checkIfPasswordsSaved:NO];
|
| +
|
| + // Login to page and click to save password and check that its saved.
|
| + [ChromeEarlGrey loadURL:URL];
|
| + chrome_test_util::TapWebViewElementWithId("Login");
|
| + [[EarlGrey selectElementWithMatcher:buttonWithAccessibilityLabelId(
|
| + IDS_IOS_PASSWORD_MANAGER_SAVE_BUTTON)]
|
| + performAction:grey_tap()];
|
| +
|
| + [self checkIfPasswordsSaved:YES];
|
| +
|
| + // Clear passwords and check that none are saved.
|
| + [self clearPasswords];
|
| + [self checkIfPasswordsSaved:NO];
|
| +}
|
| +
|
| +// Verifies that metrics reporting works properly under possible settings of the
|
| +// preferences kMetricsReportingEnabled and kMetricsReportingWifiOnly.
|
| +- (void)testMetricsReporting {
|
| + [self assertsMetricsPrefsForService:kMetrics];
|
| +}
|
| +
|
| +// Verifies that breakpad reporting works properly under possible settings of
|
| +// the preferences |kMetricsReportingEnabled| and |kMetricsReportingWifiOnly|
|
| +// for non-first-launch runs.
|
| +// NOTE: breakpad only allows uploading for non-first-launch runs.
|
| +- (void)testBreakpadReporting {
|
| + [self setTearDownHandler:^{
|
| + // Restore the first launch state to previous state.
|
| + chrome_test_util::SetFirstLaunchStateTo(
|
| + chrome_test_util::IsFirstLaunchAfterUpgrade());
|
| + }];
|
| +
|
| + chrome_test_util::SetFirstLaunchStateTo(NO);
|
| + [self assertsMetricsPrefsForService:kBreakpad];
|
| +}
|
| +
|
| +// Verifies that breakpad reporting works properly under possible settings of
|
| +// the preferences |kMetricsReportingEnabled| and |kMetricsReportingWifiOnly|
|
| +// for first-launch runs.
|
| +// NOTE: breakpad only allows uploading for non-first-launch runs.
|
| +- (void)testBreakpadReportingFirstLaunch {
|
| + [self setTearDownHandler:^{
|
| + // Restore the first launch state to previous state.
|
| + chrome_test_util::SetFirstLaunchStateTo(
|
| + chrome_test_util::IsFirstLaunchAfterUpgrade());
|
| + }];
|
| +
|
| + chrome_test_util::SetFirstLaunchStateTo(YES);
|
| + [self assertsMetricsPrefsForService:kBreakpadFirstLaunch];
|
| +}
|
| +
|
| +// Set a server bound certificate, clears the site data through the UI and
|
| +// checks that the certificate is deleted.
|
| +- (void)testClearCertificates {
|
| + SetCertificate();
|
| + // Restore the Clear Browsing Data checkmarks prefs to their default state in
|
| + // Teardown.
|
| + [self setTearDownHandler:^{
|
| + ios::ChromeBrowserState* browserState =
|
| + chrome_test_util::GetOriginalBrowserState();
|
| + PrefService* preferences = browserState->GetPrefs();
|
| +
|
| + preferences->SetBoolean(browsing_data::prefs::kDeleteBrowsingHistory, true);
|
| + preferences->SetBoolean(browsing_data::prefs::kDeleteCache, true);
|
| + preferences->SetBoolean(browsing_data::prefs::kDeleteCookies, true);
|
| + preferences->SetBoolean(browsing_data::prefs::kDeletePasswords, false);
|
| + preferences->SetBoolean(browsing_data::prefs::kDeleteFormData, false);
|
| + }];
|
| + GREYAssertFalse(IsCertificateCleared(), @"Failed to set certificate.");
|
| + [self clearCookiesAndSiteData];
|
| + GREYAssertTrue(IsCertificateCleared(),
|
| + @"Certificate is expected to be deleted.");
|
| +}
|
| +
|
| +// Verifies that Settings opens when signed-out and in Incognito mode.
|
| +// This tests that crbug.com/607335 has not regressed.
|
| +- (void)testSettingsSignedOutIncognito {
|
| + chrome_test_util::OpenNewIncognitoTab();
|
| +
|
| + [ChromeEarlGreyUI openToolsMenu];
|
| + [[EarlGrey selectElementWithMatcher:settingsButton()]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(kSettingsCollectionViewId)]
|
| + assertWithMatcher:grey_notNil()];
|
| +
|
| + [[EarlGrey selectElementWithMatcher:navigationDoneButton()]
|
| + performAction:grey_tap()];
|
| + chrome_test_util::CloseAllIncognitoTabs();
|
| +}
|
| +
|
| +// Verifies the UI elements are accessibile on the Settings page.
|
| +- (void)testAccessibilityOnSettingsPage {
|
| + [ChromeEarlGreyUI openToolsMenu];
|
| + [[EarlGrey selectElementWithMatcher:settingsButton()]
|
| + performAction:grey_tap()];
|
| + chrome_test_util::VerifyAccessibilityForCurrentScreen();
|
| + [[EarlGrey
|
| + selectElementWithMatcher:chrome_test_util::buttonWithAccessibilityLabelId(
|
| + IDS_IOS_NAVIGATION_BAR_DONE_BUTTON)]
|
| + performAction:grey_tap()];
|
| +}
|
| +
|
| +// Verifies the UI elements are accessibile on the Content Settings page.
|
| +- (void)testAccessibilityOnContentSettingsPage {
|
| + [self openSubSettingMenu:chrome_test_util::buttonWithAccessibilityLabelId(
|
| + IDS_IOS_CONTENT_SETTINGS_TITLE)];
|
| + chrome_test_util::VerifyAccessibilityForCurrentScreen();
|
| + [self closeSubSettingsMenu];
|
| +}
|
| +
|
| +// Verifies the UI elements are accessibile on the Privacy Settings page.
|
| +- (void)testAccessibilityOnPrivacySettingsPage {
|
| + [self openSubSettingMenu:chrome_test_util::buttonWithAccessibilityLabelId(
|
| + IDS_OPTIONS_ADVANCED_SECTION_TITLE_PRIVACY)];
|
| + chrome_test_util::VerifyAccessibilityForCurrentScreen();
|
| + [self closeSubSettingsMenu];
|
| +}
|
| +
|
| +// Verifies the UI elements are accessibile on the Bandwidth Management Settings
|
| +// page.
|
| +- (void)testAccessibilityOnBandwidthManagementSettingsPage {
|
| + [self openSubSettingMenu:chrome_test_util::buttonWithAccessibilityLabelId(
|
| + IDS_IOS_BANDWIDTH_MANAGEMENT_SETTINGS)];
|
| + chrome_test_util::VerifyAccessibilityForCurrentScreen();
|
| + [self closeSubSettingsMenu];
|
| +}
|
| +
|
| +// Verifies the UI elements are accessible on the Save Passwords page.
|
| +- (void)testAccessibilityOnSavePasswords {
|
| + [ChromeEarlGreyUI openToolsMenu];
|
| + [[EarlGrey selectElementWithMatcher:settingsButton()]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:passwordsButton()]
|
| + performAction:grey_tap()];
|
| + chrome_test_util::VerifyAccessibilityForCurrentScreen();
|
| + [self closeSubSettingsMenu];
|
| +}
|
| +
|
| +// Verifies the UI elements are accessible on the Search engine page.
|
| +- (void)testAccessibilityOnSearchEngine {
|
| + [ChromeEarlGreyUI openToolsMenu];
|
| + [[EarlGrey selectElementWithMatcher:settingsButton()]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:searchEngineButton()]
|
| + performAction:grey_tap()];
|
| + chrome_test_util::VerifyAccessibilityForCurrentScreen();
|
| + [self closeSubSettingsMenu];
|
| +}
|
| +
|
| +// Verifies the UI elements are accessible on the Autofill Forms page.
|
| +- (void)testAccessibilityOnAutofillForms {
|
| + [ChromeEarlGreyUI openToolsMenu];
|
| + [[EarlGrey selectElementWithMatcher:settingsButton()]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:autofillButton()]
|
| + performAction:grey_tap()];
|
| + chrome_test_util::VerifyAccessibilityForCurrentScreen();
|
| + [self closeSubSettingsMenu];
|
| +}
|
| +
|
| +// Verifies the UI elements are accessible on the Google Apps page.
|
| +- (void)testAccessibilityOnGoogleApps {
|
| + [ChromeEarlGreyUI openToolsMenu];
|
| + [[EarlGrey selectElementWithMatcher:settingsButton()]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:googleAppsButton()]
|
| + performAction:grey_tap()];
|
| + chrome_test_util::VerifyAccessibilityForCurrentScreen();
|
| + [self closeSubSettingsMenu];
|
| +}
|
| +
|
| +// Verifies the UI elements are accessible on the About Chrome page.
|
| +- (void)testAccessibilityOnGoogleChrome {
|
| + [self openSubSettingMenu:googleChromeButton()];
|
| + chrome_test_util::VerifyAccessibilityForCurrentScreen();
|
| + [self closeSubSettingsMenu];
|
| +}
|
| +
|
| +// Verifies the UI elements are accessible on the Voice Search page.
|
| +- (void)testAccessibilityOnVoiceSearch {
|
| + [self openSubSettingMenu:voiceSearchButton()];
|
| + chrome_test_util::VerifyAccessibilityForCurrentScreen();
|
| + [self closeSubSettingsMenu];
|
| +}
|
| +
|
| +@end
|
|
|