OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #import <EarlGrey/EarlGrey.h> |
| 6 #import <UIKit/UIKit.h> |
| 7 #import <XCTest/XCTest.h> |
| 8 #include <map> |
| 9 |
| 10 #include "base/bind.h" |
| 11 #import "base/mac/bind_objc_block.h" |
| 12 #include "base/memory/ptr_util.h" |
| 13 #include "base/strings/sys_string_conversions.h" |
| 14 #include "components/browsing_data/core/pref_names.h" |
| 15 #include "components/metrics/metrics_pref_names.h" |
| 16 #include "components/password_manager/core/common/password_manager_pref_names.h" |
| 17 #include "components/prefs/pref_member.h" |
| 18 #include "components/prefs/pref_service.h" |
| 19 #include "components/strings/grit/components_strings.h" |
| 20 #include "ios/chrome/browser/browser_state/chrome_browser_state.h" |
| 21 #include "ios/chrome/browser/content_settings/host_content_settings_map_factory.
h" |
| 22 #include "ios/chrome/browser/pref_names.h" |
| 23 #import "ios/chrome/browser/ui/settings/clear_browsing_data_collection_view_cont
roller.h" |
| 24 #import "ios/chrome/browser/ui/settings/settings_collection_view_controller.h" |
| 25 #import "ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.h" |
| 26 #import "ios/chrome/browser/ui/tools_menu/tools_popup_controller.h" |
| 27 #include "ios/chrome/grit/ios_chromium_strings.h" |
| 28 #include "ios/chrome/grit/ios_strings.h" |
| 29 #include "ios/chrome/grit/ios_theme_resources.h" |
| 30 #import "ios/chrome/test/app/chrome_test_util.h" |
| 31 #import "ios/chrome/test/app/navigation_test_util.h" |
| 32 #import "ios/chrome/test/app/tab_test_util.h" |
| 33 #include "ios/chrome/test/app/web_view_interaction_test_util.h" |
| 34 #import "ios/chrome/test/earl_grey/accessibility_util.h" |
| 35 #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" |
| 36 #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" |
| 37 #import "ios/chrome/test/earl_grey/chrome_matchers.h" |
| 38 #import "ios/chrome/test/earl_grey/chrome_test_case.h" |
| 39 #import "ios/web/public/test/http_server.h" |
| 40 #import "ios/web/public/test/http_server_util.h" |
| 41 #import "ios/web/public/test/web_view_interaction_test_util.h" |
| 42 #include "ios/web/public/web_state/web_state.h" |
| 43 #include "ios/web/public/web_thread.h" |
| 44 #include "net/ssl/channel_id_service.h" |
| 45 #include "net/ssl/channel_id_store.h" |
| 46 #include "net/url_request/url_request_context.h" |
| 47 #include "net/url_request/url_request_context_getter.h" |
| 48 #include "ui/base/l10n/l10n_util.h" |
| 49 #include "url/gurl.h" |
| 50 |
| 51 using chrome_test_util::buttonWithAccessibilityLabelId; |
| 52 |
| 53 namespace { |
| 54 |
| 55 const char kTestOrigin1[] = "http://host1:1/"; |
| 56 |
| 57 const char kUrl[] = "http://foo/browsing"; |
| 58 const char kUrlWithSetCookie[] = "http://foo/set_cookie"; |
| 59 const char kResponse[] = "bar"; |
| 60 const char kResponseWithSetCookie[] = "bar with set cookie"; |
| 61 const char kNoCookieText[] = "No cookies"; |
| 62 const char kCookie[] = "a=b"; |
| 63 const char kJavaScriptGetCookies[] = |
| 64 "var c = document.cookie ? document.cookie.split(/;\\s*/) : [];" |
| 65 "if (!c.length) {" |
| 66 " document.documentElement.innerHTML = 'No cookies!';" |
| 67 "} else {" |
| 68 " document.documentElement.innerHTML = 'OK: ' + c.join(',');" |
| 69 "}"; |
| 70 |
| 71 enum MetricsServiceType { |
| 72 kMetrics, |
| 73 kBreakpad, |
| 74 kBreakpadFirstLaunch, |
| 75 }; |
| 76 |
| 77 // Matcher for the clear browsing history cell on the clear browsing data panel. |
| 78 id<GREYMatcher> clearBrowsingHistoryButton() { |
| 79 return grey_allOf(grey_accessibilityID(kClearBrowsingHistoryCellId), |
| 80 grey_sufficientlyVisible(), nil); |
| 81 } |
| 82 // Matcher for the clear cookies cell on the clear browsing data panel. |
| 83 id<GREYMatcher> clearCookiesButton() { |
| 84 return grey_accessibilityID(kClearCookiesCellId); |
| 85 } |
| 86 // Matcher for the clear cache cell on the clear browsing data panel. |
| 87 id<GREYMatcher> clearCacheButton() { |
| 88 return grey_allOf(grey_accessibilityID(kClearCacheCellId), |
| 89 grey_sufficientlyVisible(), nil); |
| 90 } |
| 91 // Matcher for the clear saved passwords cell on the clear browsing data panel. |
| 92 id<GREYMatcher> clearSavedPasswordsButton() { |
| 93 return grey_allOf(grey_accessibilityID(kClearSavedPasswordsCellId), |
| 94 grey_sufficientlyVisible(), nil); |
| 95 } |
| 96 // Matcher for the clear browsing data button on the clear browsing data panel. |
| 97 id<GREYMatcher> clearBrowsingDataButton() { |
| 98 return buttonWithAccessibilityLabelId(IDS_IOS_CLEAR_BUTTON); |
| 99 } |
| 100 // Matcher for the done button in the navigation bar. |
| 101 id<GREYMatcher> navigationDoneButton() { |
| 102 return buttonWithAccessibilityLabelId(IDS_IOS_NAVIGATION_BAR_DONE_BUTTON); |
| 103 } |
| 104 // Matcher for the Settings button in the tools menu. |
| 105 id<GREYMatcher> settingsButton() { |
| 106 return grey_accessibilityID(kToolsMenuSettingsId); |
| 107 } |
| 108 // Matcher for the Save Passwords cell on the main Settings screen. |
| 109 id<GREYMatcher> passwordsButton() { |
| 110 return buttonWithAccessibilityLabelId(IDS_IOS_SAVE_PASSWORDS); |
| 111 } |
| 112 // Matcher for the Privacy cell on the main Settings screen. |
| 113 id<GREYMatcher> privacyButton() { |
| 114 return buttonWithAccessibilityLabelId( |
| 115 IDS_OPTIONS_ADVANCED_SECTION_TITLE_PRIVACY); |
| 116 } |
| 117 // Matcher for the Clear Browsing Data cell on the Privacy screen. |
| 118 id<GREYMatcher> clearBrowsingDataCell() { |
| 119 return buttonWithAccessibilityLabelId(IDS_IOS_CLEAR_BROWSING_DATA_TITLE); |
| 120 } |
| 121 |
| 122 // Matcher for the Search Engine cell on the main Settings screen. |
| 123 id<GREYMatcher> searchEngineButton() { |
| 124 return buttonWithAccessibilityLabelId(IDS_IOS_SEARCH_ENGINE_SETTING_TITLE); |
| 125 } |
| 126 |
| 127 // Matcher for the Autofill Forms cell on the main Settings screen. |
| 128 id<GREYMatcher> autofillButton() { |
| 129 return buttonWithAccessibilityLabelId(IDS_IOS_AUTOFILL); |
| 130 } |
| 131 |
| 132 // Matcher for the Google Apps cell on the main Settings screen. |
| 133 id<GREYMatcher> googleAppsButton() { |
| 134 return buttonWithAccessibilityLabelId(IDS_IOS_GOOGLE_APPS_SM_SETTINGS); |
| 135 } |
| 136 |
| 137 // Matcher for the Google Chrome cell on the main Settings screen. |
| 138 id<GREYMatcher> googleChromeButton() { |
| 139 return buttonWithAccessibilityLabelId(IDS_IOS_PRODUCT_NAME); |
| 140 } |
| 141 |
| 142 // Matcher for the Google Chrome cell on the main Settings screen. |
| 143 id<GREYMatcher> voiceSearchButton() { |
| 144 return grey_allOf(grey_accessibilityID(kSettingsVoiceSearchCellId), |
| 145 grey_accessibilityTrait(UIAccessibilityTraitButton), nil); |
| 146 } |
| 147 |
| 148 // Asserts that there is no cookie in current web state. |
| 149 void AssertNoCookieExists() { |
| 150 NSError* error = nil; |
| 151 chrome_test_util::ExecuteJavaScript( |
| 152 base::SysUTF8ToNSString(kJavaScriptGetCookies), &error); |
| 153 [[EarlGrey selectElementWithMatcher:chrome_test_util::webViewContainingText( |
| 154 kNoCookieText)] |
| 155 assertWithMatcher:grey_notNil()]; |
| 156 } |
| 157 |
| 158 // Asserts |cookie| exists in current web state. |
| 159 void AssertCookieExists(const char cookie[]) { |
| 160 NSError* error = nil; |
| 161 chrome_test_util::ExecuteJavaScript( |
| 162 base::SysUTF8ToNSString(kJavaScriptGetCookies), &error); |
| 163 NSString* const expectedCookieText = |
| 164 [NSString stringWithFormat:@"OK: %@", base::SysUTF8ToNSString(cookie)]; |
| 165 [[EarlGrey |
| 166 selectElementWithMatcher:chrome_test_util::webViewContainingText( |
| 167 base::SysNSStringToUTF8(expectedCookieText))] |
| 168 assertWithMatcher:grey_notNil()]; |
| 169 } |
| 170 |
| 171 // Run as a task to check if a certificate has been added to the ChannelIDStore. |
| 172 // Signals the given |semaphore| if the cert was added, or reposts itself |
| 173 // otherwise. |
| 174 void CheckCertificate(scoped_refptr<net::URLRequestContextGetter> getter, |
| 175 dispatch_semaphore_t semaphore) { |
| 176 net::ChannelIDService* channel_id_service = |
| 177 getter->GetURLRequestContext()->channel_id_service(); |
| 178 if (channel_id_service->channel_id_count() == 0) { |
| 179 // If the channel_id_count is still 0, no certs have been added yet. |
| 180 // Re-post this task and check again later. |
| 181 web::WebThread::PostTask(web::WebThread::IO, FROM_HERE, |
| 182 base::Bind(&CheckCertificate, getter, semaphore)); |
| 183 } else { |
| 184 // If certs have been added, signal the calling thread. |
| 185 dispatch_semaphore_signal(semaphore); |
| 186 } |
| 187 } |
| 188 |
| 189 // Set certificate for host |kTestOrigin1| for testing. |
| 190 void SetCertificate() { |
| 191 ios::ChromeBrowserState* browserState = |
| 192 chrome_test_util::GetOriginalBrowserState(); |
| 193 dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); |
| 194 scoped_refptr<net::URLRequestContextGetter> getter = |
| 195 browserState->GetRequestContext(); |
| 196 web::WebThread::PostTask( |
| 197 web::WebThread::IO, FROM_HERE, base::BindBlock(^{ |
| 198 net::ChannelIDService* channel_id_service = |
| 199 getter->GetURLRequestContext()->channel_id_service(); |
| 200 net::ChannelIDStore* channel_id_store = |
| 201 channel_id_service->GetChannelIDStore(); |
| 202 base::Time now = base::Time::Now(); |
| 203 channel_id_store->SetChannelID( |
| 204 base::MakeUnique<net::ChannelIDStore::ChannelID>( |
| 205 kTestOrigin1, now, crypto::ECPrivateKey::Create())); |
| 206 })); |
| 207 |
| 208 // The ChannelIDStore may not be loaded, so adding the new cert may not happen |
| 209 // immediately. This posted task signals the semaphore if the cert was added, |
| 210 // or re-posts itself to check again later otherwise. |
| 211 web::WebThread::PostTask(web::WebThread::IO, FROM_HERE, |
| 212 base::Bind(&CheckCertificate, getter, semaphore)); |
| 213 |
| 214 dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); |
| 215 dispatch_release(semaphore); |
| 216 } |
| 217 |
| 218 // Fetching channel id is expected to complete immediately in this test, so a |
| 219 // dummy callback function is set for testing. |
| 220 void CertCallback(int err, |
| 221 const std::string& server_identifier, |
| 222 std::unique_ptr<crypto::ECPrivateKey> key) {} |
| 223 |
| 224 // Check if certificate is empty for host |kTestOrigin1|. |
| 225 bool IsCertificateCleared() { |
| 226 ios::ChromeBrowserState* browserState = |
| 227 chrome_test_util::GetOriginalBrowserState(); |
| 228 __block int result; |
| 229 dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); |
| 230 scoped_refptr<net::URLRequestContextGetter> getter = |
| 231 browserState->GetRequestContext(); |
| 232 web::WebThread::PostTask( |
| 233 web::WebThread::IO, FROM_HERE, base::BindBlock(^{ |
| 234 net::ChannelIDService* channel_id_service = |
| 235 getter->GetURLRequestContext()->channel_id_service(); |
| 236 std::unique_ptr<crypto::ECPrivateKey> dummy_key; |
| 237 result = channel_id_service->GetChannelIDStore()->GetChannelID( |
| 238 kTestOrigin1, &dummy_key, base::Bind(CertCallback)); |
| 239 dispatch_semaphore_signal(semaphore); |
| 240 })); |
| 241 dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); |
| 242 dispatch_release(semaphore); |
| 243 return result == net::ERR_FILE_NOT_FOUND; |
| 244 } |
| 245 |
| 246 } // namespace |
| 247 |
| 248 // Settings tests for Chrome. |
| 249 @interface SettingsTestCase : ChromeTestCase |
| 250 @end |
| 251 |
| 252 @implementation SettingsTestCase |
| 253 |
| 254 // Opens the a submenu from the settings page. Must be called from the NTP. |
| 255 - (void)openSubSettingMenu:(id<GREYMatcher>)settingToTap { |
| 256 const CGFloat kScrollDisplacement = 150.0; |
| 257 id<GREYMatcher> toolsMenuTableViewMatcher = |
| 258 grey_accessibilityID(kToolsMenuTableViewId); |
| 259 id<GREYMatcher> settingsButtonMatcher = |
| 260 grey_accessibilityID(kToolsMenuSettingsId); |
| 261 id<GREYMatcher> settingsCollectionViewMatcher = |
| 262 grey_accessibilityID(kSettingsCollectionViewId); |
| 263 |
| 264 [ChromeEarlGreyUI openToolsMenu]; |
| 265 [[[EarlGrey selectElementWithMatcher:settingsButtonMatcher] |
| 266 usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, |
| 267 kScrollDisplacement) |
| 268 onElementWithMatcher:toolsMenuTableViewMatcher] performAction:grey_tap()]; |
| 269 [[[EarlGrey selectElementWithMatcher:settingToTap] |
| 270 usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, |
| 271 kScrollDisplacement) |
| 272 onElementWithMatcher:settingsCollectionViewMatcher] |
| 273 performAction:grey_tap()]; |
| 274 } |
| 275 |
| 276 // Closes the a sub-settings menu, and then the general Settings menu. |
| 277 - (void)closeSubSettingsMenu { |
| 278 [[EarlGrey |
| 279 selectElementWithMatcher:grey_allOf( |
| 280 grey_accessibilityID(@"back_bar_button"), |
| 281 grey_accessibilityTrait( |
| 282 UIAccessibilityTraitButton), |
| 283 nil)] performAction:grey_tap()]; |
| 284 [[EarlGrey |
| 285 selectElementWithMatcher:chrome_test_util::buttonWithAccessibilityLabelId( |
| 286 IDS_IOS_NAVIGATION_BAR_DONE_BUTTON)] |
| 287 performAction:grey_tap()]; |
| 288 } |
| 289 |
| 290 // Performs the steps to clear browsing data. Must be called on the |
| 291 // Clear Browsing Data settings screen, after having selected the data types |
| 292 // scheduled for removal. |
| 293 - (void)clearBrowsingData { |
| 294 [[EarlGrey selectElementWithMatcher:clearBrowsingDataButton()] |
| 295 performAction:grey_tap()]; |
| 296 |
| 297 // There is not currently a matcher for accessibilityElementIsFocused or |
| 298 // userInteractionEnabled which could be used here instead of checking that |
| 299 // the button is not a MDCCollectionViewTextCell. Use when available. |
| 300 // TODO(crbug.com/638674): Evaluate if this can move to shared code. |
| 301 id<GREYMatcher> confirmClear = grey_allOf( |
| 302 clearBrowsingDataButton(), |
| 303 grey_not(grey_kindOfClass([MDCCollectionViewTextCell class])), nil); |
| 304 [[EarlGrey selectElementWithMatcher:confirmClear] performAction:grey_tap()]; |
| 305 } |
| 306 |
| 307 // Exits Settings by clicking on the Done button. |
| 308 - (void)dismissSettings { |
| 309 // Dismiss the settings. |
| 310 [[EarlGrey selectElementWithMatcher:navigationDoneButton()] |
| 311 performAction:grey_tap()]; |
| 312 |
| 313 // Wait for UI components to finish loading. |
| 314 [[GREYUIThreadExecutor sharedInstance] drainUntilIdle]; |
| 315 } |
| 316 |
| 317 // From the NTP, clears the cookies and site data via the UI. |
| 318 - (void)clearCookiesAndSiteData { |
| 319 [ChromeEarlGreyUI openToolsMenu]; |
| 320 [[EarlGrey selectElementWithMatcher:settingsButton()] |
| 321 performAction:grey_tap()]; |
| 322 [[EarlGrey selectElementWithMatcher:privacyButton()] |
| 323 performAction:grey_tap()]; |
| 324 [[EarlGrey selectElementWithMatcher:clearBrowsingDataCell()] |
| 325 performAction:grey_tap()]; |
| 326 |
| 327 // "Browsing history", "Cookies, Site Data" and "Cached Images and Files" |
| 328 // are the default checked options when the prefs are registered. Uncheck |
| 329 // "Browsing history" and "Cached Images and Files". |
| 330 // Prefs are reset to default at the end of each test. |
| 331 [[EarlGrey selectElementWithMatcher:clearBrowsingHistoryButton()] |
| 332 performAction:grey_tap()]; |
| 333 [[EarlGrey selectElementWithMatcher:clearCacheButton()] |
| 334 performAction:grey_tap()]; |
| 335 |
| 336 [self clearBrowsingData]; |
| 337 [self dismissSettings]; |
| 338 } |
| 339 |
| 340 // From the NTP, clears the saved passwords via the UI. |
| 341 - (void)clearPasswords { |
| 342 [ChromeEarlGreyUI openToolsMenu]; |
| 343 [[EarlGrey selectElementWithMatcher:settingsButton()] |
| 344 performAction:grey_tap()]; |
| 345 [[EarlGrey selectElementWithMatcher:privacyButton()] |
| 346 performAction:grey_tap()]; |
| 347 [[EarlGrey selectElementWithMatcher:clearBrowsingDataCell()] |
| 348 performAction:grey_tap()]; |
| 349 |
| 350 // "Browsing history", "Cookies, Site Data" and "Cached Images and Files" |
| 351 // are the default checked options when the prefs are registered. Unckeck all |
| 352 // of them and check "Passwords". |
| 353 [[EarlGrey selectElementWithMatcher:clearBrowsingHistoryButton()] |
| 354 performAction:grey_tap()]; |
| 355 [[EarlGrey selectElementWithMatcher:clearCookiesButton()] |
| 356 performAction:grey_tap()]; |
| 357 [[EarlGrey selectElementWithMatcher:clearCacheButton()] |
| 358 performAction:grey_tap()]; |
| 359 [[EarlGrey selectElementWithMatcher:clearSavedPasswordsButton()] |
| 360 performAction:grey_tap()]; |
| 361 |
| 362 [self clearBrowsingData]; |
| 363 |
| 364 // Re-tap all the previously tapped cells, so that the default state of the |
| 365 // checkmarks is preserved. |
| 366 [[EarlGrey selectElementWithMatcher:clearBrowsingHistoryButton()] |
| 367 performAction:grey_tap()]; |
| 368 [[EarlGrey selectElementWithMatcher:clearCookiesButton()] |
| 369 performAction:grey_tap()]; |
| 370 [[EarlGrey selectElementWithMatcher:clearCacheButton()] |
| 371 performAction:grey_tap()]; |
| 372 [[EarlGrey selectElementWithMatcher:clearSavedPasswordsButton()] |
| 373 performAction:grey_tap()]; |
| 374 |
| 375 [self dismissSettings]; |
| 376 } |
| 377 |
| 378 // Checks the presence (or absence) of saved passwords. |
| 379 // If |saved| is YES, it checks that there is a Saved Passwords section. |
| 380 // If |saved| is NO, it checks that there is no Saved Passwords section. |
| 381 - (void)checkIfPasswordsSaved:(BOOL)saved { |
| 382 [ChromeEarlGreyUI openToolsMenu]; |
| 383 [[EarlGrey selectElementWithMatcher:settingsButton()] |
| 384 performAction:grey_tap()]; |
| 385 [[EarlGrey selectElementWithMatcher:passwordsButton()] |
| 386 performAction:grey_tap()]; |
| 387 |
| 388 id<GREYMatcher> visibilityMatcher = |
| 389 saved ? grey_sufficientlyVisible() : grey_notVisible(); |
| 390 [[EarlGrey selectElementWithMatcher: |
| 391 grey_text(l10n_util::GetNSString( |
| 392 IDS_PASSWORD_MANAGER_SHOW_PASSWORDS_TAB_TITLE))] |
| 393 assertWithMatcher:visibilityMatcher]; |
| 394 |
| 395 // Close the Settings. |
| 396 [self closeSubSettingsMenu]; |
| 397 } |
| 398 |
| 399 // Checks for a given service that it is both recording and uploading, where |
| 400 // appropriate. |
| 401 - (void)assertMetricsServiceEnabled:(MetricsServiceType)serviceType { |
| 402 switch (serviceType) { |
| 403 case kMetrics: |
| 404 GREYAssertTrue(chrome_test_util::IsMetricsRecordingEnabled(), |
| 405 @"Metrics recording should be enabled."); |
| 406 GREYAssertTrue(chrome_test_util::IsMetricsReportingEnabled(), |
| 407 @"Metrics reporting should be enabled."); |
| 408 break; |
| 409 case kBreakpad: |
| 410 GREYAssertTrue(chrome_test_util::IsBreakpadEnabled(), |
| 411 @"Breakpad should be enabled."); |
| 412 GREYAssertTrue(chrome_test_util::IsBreakpadReportingEnabled(), |
| 413 @"Breakpad reporting should be enabled."); |
| 414 break; |
| 415 case kBreakpadFirstLaunch: |
| 416 // For first launch after upgrade, or after install, uploading of crash |
| 417 // reports is always disabled. Check that the first launch flag is being |
| 418 // honored. |
| 419 GREYAssertTrue(chrome_test_util::IsBreakpadEnabled(), |
| 420 @"Breakpad should be enabled."); |
| 421 GREYAssertFalse(chrome_test_util::IsBreakpadReportingEnabled(), |
| 422 @"Breakpad reporting should be disabled."); |
| 423 break; |
| 424 } |
| 425 } |
| 426 |
| 427 // Checks for a given service that it is completely disabled. |
| 428 - (void)assertMetricsServiceDisabled:(MetricsServiceType)serviceType { |
| 429 switch (serviceType) { |
| 430 case kMetrics: { |
| 431 GREYAssertFalse(chrome_test_util::IsMetricsRecordingEnabled(), |
| 432 @"Metrics recording should be disabled."); |
| 433 GREYAssertFalse(chrome_test_util::IsMetricsReportingEnabled(), |
| 434 @"Metrics reporting should be disabled."); |
| 435 break; |
| 436 } |
| 437 case kBreakpad: |
| 438 case kBreakpadFirstLaunch: { |
| 439 // Check only whether or not breakpad is enabled. Disabling |
| 440 // breakpad does stop uploading, and does not change the flag |
| 441 // used to check whether or not it's uploading. |
| 442 GREYAssertFalse(chrome_test_util::IsBreakpadEnabled(), |
| 443 @"Breakpad should be disabled."); |
| 444 break; |
| 445 } |
| 446 } |
| 447 } |
| 448 |
| 449 // Checks for a given service that it is recording, but not uploading anything. |
| 450 // Used to test that the wifi-only preference is honored when the device is |
| 451 // using a cellular network. |
| 452 - (void)assertMetricsServiceEnabledButNotUploading: |
| 453 (MetricsServiceType)serviceType { |
| 454 switch (serviceType) { |
| 455 case kMetrics: { |
| 456 GREYAssertTrue(chrome_test_util::IsMetricsRecordingEnabled(), |
| 457 @"Metrics recording should be enabled."); |
| 458 GREYAssertFalse(chrome_test_util::IsMetricsReportingEnabled(), |
| 459 @"Metrics reporting should be disabled."); |
| 460 break; |
| 461 } |
| 462 case kBreakpad: |
| 463 case kBreakpadFirstLaunch: { |
| 464 GREYAssertTrue(chrome_test_util::IsBreakpadEnabled(), |
| 465 @"Breakpad should be enabled."); |
| 466 GREYAssertFalse(chrome_test_util::IsBreakpadReportingEnabled(), |
| 467 @"Breakpad reporting should be disabled."); |
| 468 break; |
| 469 } |
| 470 } |
| 471 } |
| 472 |
| 473 - (void)assertsMetricsPrefsForService:(MetricsServiceType)serviceType { |
| 474 // Two preferences, each with two values - on or off. Check all four |
| 475 // combinations: |
| 476 // kMetricsReportingEnabled OFF and kMetricsReportingWifiOnly OFF |
| 477 // - Services do not record data and do not upload data. |
| 478 |
| 479 // kMetricsReportingEnabled OFF and kMetricsReportingWifiOnly ON |
| 480 // - Services do not record data and do not upload data. |
| 481 // Note that if kMetricsReportingEnabled is OFF, the state of |
| 482 // kMetricsReportingWifiOnly does not matter. |
| 483 |
| 484 // kMetricsReportingEnabled ON and kMetricsReportingWifiOnly ON |
| 485 // - Services record data and upload data only when the device is using |
| 486 // a wifi connection. Note: rather than checking for wifi, the code |
| 487 // checks for a cellular network (wwan). wwan != wifi. So if wwan is |
| 488 // true, services do not upload any data. |
| 489 |
| 490 // kMetricsReportingEnabled ON and kMetricsReportingWifiOnly OFF |
| 491 // - Services record data and upload data. |
| 492 |
| 493 // kMetricsReportingEnabled OFF and kMetricsReportingWifiOnly OFF |
| 494 chrome_test_util::SetBooleanLocalStatePref( |
| 495 metrics::prefs::kMetricsReportingEnabled, NO); |
| 496 chrome_test_util::SetBooleanLocalStatePref(prefs::kMetricsReportingWifiOnly, |
| 497 NO); |
| 498 // Service should be completely disabled. |
| 499 // I.e. no recording of data, and no uploading of what's been recorded. |
| 500 [self assertMetricsServiceDisabled:serviceType]; |
| 501 |
| 502 // kMetricsReportingEnabled OFF and kMetricsReportingWifiOnly ON |
| 503 chrome_test_util::SetBooleanLocalStatePref( |
| 504 metrics::prefs::kMetricsReportingEnabled, NO); |
| 505 chrome_test_util::SetBooleanLocalStatePref(prefs::kMetricsReportingWifiOnly, |
| 506 YES); |
| 507 // If kMetricsReportingEnabled is OFF, any service should remain completely |
| 508 // disabled, i.e. no uploading even if kMetricsReportingWifiOnly is ON. |
| 509 [self assertMetricsServiceDisabled:serviceType]; |
| 510 |
| 511 // Split here: Official build vs. Development build. |
| 512 // Official builds allow recording and uploading of data, honoring the |
| 513 // metrics prefs. Development builds should never record or upload data. |
| 514 #if defined(GOOGLE_CHROME_BUILD) |
| 515 // Official build. |
| 516 // The values of the prefs and the wwan vs wifi state should be honored by |
| 517 // the services, turning on and off according to the rules laid out above. |
| 518 |
| 519 // kMetricsReportingEnabled ON and kMetricsReportingWifiOnly ON. |
| 520 chrome_test_util::SetBooleanLocalStatePref( |
| 521 metrics::prefs::kMetricsReportingEnabled, YES); |
| 522 chrome_test_util::SetBooleanLocalStatePref(prefs::kMetricsReportingWifiOnly, |
| 523 YES); |
| 524 // Service should be enabled. |
| 525 [self assertMetricsServiceEnabled:serviceType]; |
| 526 |
| 527 // Set the network to use a cellular network, which should disable uploading |
| 528 // when the wifi-only flag is set. |
| 529 chrome_test_util::SetWWANStateTo(YES); |
| 530 [self assertMetricsServiceEnabledButNotUploading:serviceType]; |
| 531 |
| 532 // Turn off cellular network usage, which should enable uploading. |
| 533 chrome_test_util::SetWWANStateTo(NO); |
| 534 [self assertMetricsServiceEnabled:serviceType]; |
| 535 |
| 536 // kMetricsReportingEnabled ON and kMetricsReportingWifiOnly OFF |
| 537 chrome_test_util::SetBooleanLocalStatePref( |
| 538 metrics::prefs::kMetricsReportingEnabled, YES); |
| 539 chrome_test_util::SetBooleanLocalStatePref(prefs::kMetricsReportingWifiOnly, |
| 540 NO); |
| 541 // Service should be always enabled regardless of network settings. |
| 542 chrome_test_util::SetWWANStateTo(YES); |
| 543 [self assertMetricsServiceEnabled:serviceType]; |
| 544 chrome_test_util::SetWWANStateTo(NO); |
| 545 [self assertMetricsServiceDisabled:serviceType]; |
| 546 #else |
| 547 // Development build. Do not allow any recording or uploading of data. |
| 548 // Specifically, the kMetricsReportingEnabled preference is completely |
| 549 // disregarded for non-official builds, and checking its value always returns |
| 550 // false (NO). |
| 551 // This tests that no matter the state change, pref or network connection, |
| 552 // services remain disabled. |
| 553 |
| 554 // kMetricsReportingEnabled ON and kMetricsReportingWifiOnly ON |
| 555 chrome_test_util::SetBooleanLocalStatePref( |
| 556 metrics::prefs::kMetricsReportingEnabled, YES); |
| 557 chrome_test_util::SetBooleanLocalStatePref(prefs::kMetricsReportingWifiOnly, |
| 558 YES); |
| 559 // Service should remain disabled. |
| 560 [self assertMetricsServiceDisabled:serviceType]; |
| 561 |
| 562 // kMetricsReportingEnabled ON and kMetricsReportingWifiOnly OFF |
| 563 chrome_test_util::SetBooleanLocalStatePref( |
| 564 metrics::prefs::kMetricsReportingEnabled, YES); |
| 565 chrome_test_util::SetBooleanLocalStatePref(prefs::kMetricsReportingWifiOnly, |
| 566 NO); |
| 567 // Service should remain disabled. |
| 568 [self assertMetricsServiceDisabled:serviceType]; |
| 569 #endif |
| 570 } |
| 571 |
| 572 #pragma mark Tests |
| 573 |
| 574 // Tests that clearing the cookies through the UI does clear all of them. Use a |
| 575 // local server to navigate to a page that sets then tests a cookie, and then |
| 576 // clears the cookie and tests it is not set. |
| 577 // TODO(crbug.com/638674): Evaluate if this can move to shared code. |
| 578 - (void)testClearCookies { |
| 579 // Creates a map of canned responses and set up the test HTML server. |
| 580 std::map<GURL, std::pair<std::string, std::string>> response; |
| 581 |
| 582 response[web::test::HttpServer::MakeUrl(kUrlWithSetCookie)] = |
| 583 std::pair<std::string, std::string>(kCookie, kResponseWithSetCookie); |
| 584 response[web::test::HttpServer::MakeUrl(kUrl)] = |
| 585 std::pair<std::string, std::string>("", kResponse); |
| 586 |
| 587 web::test::SetUpSimpleHttpServerWithSetCookies(response); |
| 588 |
| 589 // Load |kUrl| and check that cookie is not set. |
| 590 [ChromeEarlGrey loadURL:web::test::HttpServer::MakeUrl(kUrl)]; |
| 591 [[EarlGrey selectElementWithMatcher:chrome_test_util::webViewContainingText( |
| 592 kResponse)] |
| 593 assertWithMatcher:grey_notNil()]; |
| 594 AssertNoCookieExists(); |
| 595 |
| 596 // Visit |kUrlWithSetCookie| to set a cookie and then load |kUrl| to check it |
| 597 // is still set. |
| 598 [ChromeEarlGrey loadURL:web::test::HttpServer::MakeUrl(kUrlWithSetCookie)]; |
| 599 [[EarlGrey selectElementWithMatcher:chrome_test_util::webViewContainingText( |
| 600 kResponseWithSetCookie)] |
| 601 assertWithMatcher:grey_notNil()]; |
| 602 [ChromeEarlGrey loadURL:web::test::HttpServer::MakeUrl(kUrl)]; |
| 603 [[EarlGrey selectElementWithMatcher:chrome_test_util::webViewContainingText( |
| 604 kResponse)] |
| 605 assertWithMatcher:grey_notNil()]; |
| 606 |
| 607 AssertCookieExists(kCookie); |
| 608 |
| 609 // Restore the Clear Browsing Data checkmarks prefs to their default state in |
| 610 // Teardown. |
| 611 [self setTearDownHandler:^{ |
| 612 ios::ChromeBrowserState* browserState = |
| 613 chrome_test_util::GetOriginalBrowserState(); |
| 614 PrefService* preferences = browserState->GetPrefs(); |
| 615 |
| 616 preferences->SetBoolean(browsing_data::prefs::kDeleteBrowsingHistory, true); |
| 617 preferences->SetBoolean(browsing_data::prefs::kDeleteCache, true); |
| 618 preferences->SetBoolean(browsing_data::prefs::kDeleteCookies, true); |
| 619 preferences->SetBoolean(browsing_data::prefs::kDeletePasswords, false); |
| 620 preferences->SetBoolean(browsing_data::prefs::kDeleteFormData, false); |
| 621 }]; |
| 622 |
| 623 // Clear all cookies. |
| 624 [self clearCookiesAndSiteData]; |
| 625 |
| 626 // Reload and test that there are no cookies left. |
| 627 [ChromeEarlGrey loadURL:web::test::HttpServer::MakeUrl(kUrl)]; |
| 628 [[EarlGrey selectElementWithMatcher:chrome_test_util::webViewContainingText( |
| 629 kResponse)] |
| 630 assertWithMatcher:grey_notNil()]; |
| 631 AssertNoCookieExists(); |
| 632 chrome_test_util::CloseAllTabs(); |
| 633 } |
| 634 |
| 635 // Verifies that logging into a form on a web page allows the user to save and |
| 636 // then clear a password. |
| 637 - (void)testClearPasswords { |
| 638 std::map<GURL, std::string> responses; |
| 639 const GURL URL = web::test::HttpServer::MakeUrl("http://testClearPasswords"); |
| 640 // TODO(crbug.com/432596): There looks to be a bug where the save password |
| 641 // infobar is not displayed if the action is about:blank. |
| 642 responses[URL] = |
| 643 "<form method=\"POST\" action=\"dest\">" |
| 644 "Username:<input type=\"text\" name=\"username\" value=\"name\" /><br />" |
| 645 "Password:<input type=\"password\"" |
| 646 "name=\"password\" value=\"pass\"/><br />" |
| 647 "<input type=\"submit\" value=\"Login\" id=\"Login\"/>" |
| 648 "</form>"; |
| 649 const GURL destinationURL = |
| 650 web::test::HttpServer::MakeUrl("http://testClearPasswords/dest"); |
| 651 responses[destinationURL] = "Logged in!"; |
| 652 web::test::SetUpSimpleHttpServer(responses); |
| 653 |
| 654 // Enable password management. |
| 655 ios::ChromeBrowserState* browserState = |
| 656 chrome_test_util::GetOriginalBrowserState(); |
| 657 PrefService* preferences = browserState->GetPrefs(); |
| 658 bool originalPasswordManagerSavingEnabled = preferences->GetBoolean( |
| 659 password_manager::prefs::kPasswordManagerSavingEnabled); |
| 660 preferences->SetBoolean( |
| 661 password_manager::prefs::kPasswordManagerSavingEnabled, true); |
| 662 [self setTearDownHandler:^{ |
| 663 // Restore the password management pref state. |
| 664 ios::ChromeBrowserState* browserState = |
| 665 chrome_test_util::GetOriginalBrowserState(); |
| 666 PrefService* preferences = browserState->GetPrefs(); |
| 667 preferences->SetBoolean( |
| 668 password_manager::prefs::kPasswordManagerSavingEnabled, |
| 669 originalPasswordManagerSavingEnabled); |
| 670 |
| 671 // Restore the Clear Browsing Data checkmarks prefs to their default state. |
| 672 preferences->SetBoolean(browsing_data::prefs::kDeleteBrowsingHistory, true); |
| 673 preferences->SetBoolean(browsing_data::prefs::kDeleteCache, true); |
| 674 preferences->SetBoolean(browsing_data::prefs::kDeleteCookies, true); |
| 675 preferences->SetBoolean(browsing_data::prefs::kDeletePasswords, false); |
| 676 preferences->SetBoolean(browsing_data::prefs::kDeleteFormData, false); |
| 677 }]; |
| 678 |
| 679 // Clear passwords and check that none are saved. |
| 680 [self clearPasswords]; |
| 681 [self checkIfPasswordsSaved:NO]; |
| 682 |
| 683 // Login to page and click to save password and check that its saved. |
| 684 [ChromeEarlGrey loadURL:URL]; |
| 685 chrome_test_util::TapWebViewElementWithId("Login"); |
| 686 [[EarlGrey selectElementWithMatcher:buttonWithAccessibilityLabelId( |
| 687 IDS_IOS_PASSWORD_MANAGER_SAVE_BUTTON)] |
| 688 performAction:grey_tap()]; |
| 689 |
| 690 [self checkIfPasswordsSaved:YES]; |
| 691 |
| 692 // Clear passwords and check that none are saved. |
| 693 [self clearPasswords]; |
| 694 [self checkIfPasswordsSaved:NO]; |
| 695 } |
| 696 |
| 697 // Verifies that metrics reporting works properly under possible settings of the |
| 698 // preferences kMetricsReportingEnabled and kMetricsReportingWifiOnly. |
| 699 - (void)testMetricsReporting { |
| 700 [self assertsMetricsPrefsForService:kMetrics]; |
| 701 } |
| 702 |
| 703 // Verifies that breakpad reporting works properly under possible settings of |
| 704 // the preferences |kMetricsReportingEnabled| and |kMetricsReportingWifiOnly| |
| 705 // for non-first-launch runs. |
| 706 // NOTE: breakpad only allows uploading for non-first-launch runs. |
| 707 - (void)testBreakpadReporting { |
| 708 [self setTearDownHandler:^{ |
| 709 // Restore the first launch state to previous state. |
| 710 chrome_test_util::SetFirstLaunchStateTo( |
| 711 chrome_test_util::IsFirstLaunchAfterUpgrade()); |
| 712 }]; |
| 713 |
| 714 chrome_test_util::SetFirstLaunchStateTo(NO); |
| 715 [self assertsMetricsPrefsForService:kBreakpad]; |
| 716 } |
| 717 |
| 718 // Verifies that breakpad reporting works properly under possible settings of |
| 719 // the preferences |kMetricsReportingEnabled| and |kMetricsReportingWifiOnly| |
| 720 // for first-launch runs. |
| 721 // NOTE: breakpad only allows uploading for non-first-launch runs. |
| 722 - (void)testBreakpadReportingFirstLaunch { |
| 723 [self setTearDownHandler:^{ |
| 724 // Restore the first launch state to previous state. |
| 725 chrome_test_util::SetFirstLaunchStateTo( |
| 726 chrome_test_util::IsFirstLaunchAfterUpgrade()); |
| 727 }]; |
| 728 |
| 729 chrome_test_util::SetFirstLaunchStateTo(YES); |
| 730 [self assertsMetricsPrefsForService:kBreakpadFirstLaunch]; |
| 731 } |
| 732 |
| 733 // Set a server bound certificate, clears the site data through the UI and |
| 734 // checks that the certificate is deleted. |
| 735 - (void)testClearCertificates { |
| 736 SetCertificate(); |
| 737 // Restore the Clear Browsing Data checkmarks prefs to their default state in |
| 738 // Teardown. |
| 739 [self setTearDownHandler:^{ |
| 740 ios::ChromeBrowserState* browserState = |
| 741 chrome_test_util::GetOriginalBrowserState(); |
| 742 PrefService* preferences = browserState->GetPrefs(); |
| 743 |
| 744 preferences->SetBoolean(browsing_data::prefs::kDeleteBrowsingHistory, true); |
| 745 preferences->SetBoolean(browsing_data::prefs::kDeleteCache, true); |
| 746 preferences->SetBoolean(browsing_data::prefs::kDeleteCookies, true); |
| 747 preferences->SetBoolean(browsing_data::prefs::kDeletePasswords, false); |
| 748 preferences->SetBoolean(browsing_data::prefs::kDeleteFormData, false); |
| 749 }]; |
| 750 GREYAssertFalse(IsCertificateCleared(), @"Failed to set certificate."); |
| 751 [self clearCookiesAndSiteData]; |
| 752 GREYAssertTrue(IsCertificateCleared(), |
| 753 @"Certificate is expected to be deleted."); |
| 754 } |
| 755 |
| 756 // Verifies that Settings opens when signed-out and in Incognito mode. |
| 757 // This tests that crbug.com/607335 has not regressed. |
| 758 - (void)testSettingsSignedOutIncognito { |
| 759 chrome_test_util::OpenNewIncognitoTab(); |
| 760 |
| 761 [ChromeEarlGreyUI openToolsMenu]; |
| 762 [[EarlGrey selectElementWithMatcher:settingsButton()] |
| 763 performAction:grey_tap()]; |
| 764 [[EarlGrey |
| 765 selectElementWithMatcher:grey_accessibilityID(kSettingsCollectionViewId)] |
| 766 assertWithMatcher:grey_notNil()]; |
| 767 |
| 768 [[EarlGrey selectElementWithMatcher:navigationDoneButton()] |
| 769 performAction:grey_tap()]; |
| 770 chrome_test_util::CloseAllIncognitoTabs(); |
| 771 } |
| 772 |
| 773 // Verifies the UI elements are accessibile on the Settings page. |
| 774 - (void)testAccessibilityOnSettingsPage { |
| 775 [ChromeEarlGreyUI openToolsMenu]; |
| 776 [[EarlGrey selectElementWithMatcher:settingsButton()] |
| 777 performAction:grey_tap()]; |
| 778 chrome_test_util::VerifyAccessibilityForCurrentScreen(); |
| 779 [[EarlGrey |
| 780 selectElementWithMatcher:chrome_test_util::buttonWithAccessibilityLabelId( |
| 781 IDS_IOS_NAVIGATION_BAR_DONE_BUTTON)] |
| 782 performAction:grey_tap()]; |
| 783 } |
| 784 |
| 785 // Verifies the UI elements are accessibile on the Content Settings page. |
| 786 - (void)testAccessibilityOnContentSettingsPage { |
| 787 [self openSubSettingMenu:chrome_test_util::buttonWithAccessibilityLabelId( |
| 788 IDS_IOS_CONTENT_SETTINGS_TITLE)]; |
| 789 chrome_test_util::VerifyAccessibilityForCurrentScreen(); |
| 790 [self closeSubSettingsMenu]; |
| 791 } |
| 792 |
| 793 // Verifies the UI elements are accessibile on the Privacy Settings page. |
| 794 - (void)testAccessibilityOnPrivacySettingsPage { |
| 795 [self openSubSettingMenu:chrome_test_util::buttonWithAccessibilityLabelId( |
| 796 IDS_OPTIONS_ADVANCED_SECTION_TITLE_PRIVACY)]; |
| 797 chrome_test_util::VerifyAccessibilityForCurrentScreen(); |
| 798 [self closeSubSettingsMenu]; |
| 799 } |
| 800 |
| 801 // Verifies the UI elements are accessibile on the Bandwidth Management Settings |
| 802 // page. |
| 803 - (void)testAccessibilityOnBandwidthManagementSettingsPage { |
| 804 [self openSubSettingMenu:chrome_test_util::buttonWithAccessibilityLabelId( |
| 805 IDS_IOS_BANDWIDTH_MANAGEMENT_SETTINGS)]; |
| 806 chrome_test_util::VerifyAccessibilityForCurrentScreen(); |
| 807 [self closeSubSettingsMenu]; |
| 808 } |
| 809 |
| 810 // Verifies the UI elements are accessible on the Save Passwords page. |
| 811 - (void)testAccessibilityOnSavePasswords { |
| 812 [ChromeEarlGreyUI openToolsMenu]; |
| 813 [[EarlGrey selectElementWithMatcher:settingsButton()] |
| 814 performAction:grey_tap()]; |
| 815 [[EarlGrey selectElementWithMatcher:passwordsButton()] |
| 816 performAction:grey_tap()]; |
| 817 chrome_test_util::VerifyAccessibilityForCurrentScreen(); |
| 818 [self closeSubSettingsMenu]; |
| 819 } |
| 820 |
| 821 // Verifies the UI elements are accessible on the Search engine page. |
| 822 - (void)testAccessibilityOnSearchEngine { |
| 823 [ChromeEarlGreyUI openToolsMenu]; |
| 824 [[EarlGrey selectElementWithMatcher:settingsButton()] |
| 825 performAction:grey_tap()]; |
| 826 [[EarlGrey selectElementWithMatcher:searchEngineButton()] |
| 827 performAction:grey_tap()]; |
| 828 chrome_test_util::VerifyAccessibilityForCurrentScreen(); |
| 829 [self closeSubSettingsMenu]; |
| 830 } |
| 831 |
| 832 // Verifies the UI elements are accessible on the Autofill Forms page. |
| 833 - (void)testAccessibilityOnAutofillForms { |
| 834 [ChromeEarlGreyUI openToolsMenu]; |
| 835 [[EarlGrey selectElementWithMatcher:settingsButton()] |
| 836 performAction:grey_tap()]; |
| 837 [[EarlGrey selectElementWithMatcher:autofillButton()] |
| 838 performAction:grey_tap()]; |
| 839 chrome_test_util::VerifyAccessibilityForCurrentScreen(); |
| 840 [self closeSubSettingsMenu]; |
| 841 } |
| 842 |
| 843 // Verifies the UI elements are accessible on the Google Apps page. |
| 844 - (void)testAccessibilityOnGoogleApps { |
| 845 [ChromeEarlGreyUI openToolsMenu]; |
| 846 [[EarlGrey selectElementWithMatcher:settingsButton()] |
| 847 performAction:grey_tap()]; |
| 848 [[EarlGrey selectElementWithMatcher:googleAppsButton()] |
| 849 performAction:grey_tap()]; |
| 850 chrome_test_util::VerifyAccessibilityForCurrentScreen(); |
| 851 [self closeSubSettingsMenu]; |
| 852 } |
| 853 |
| 854 // Verifies the UI elements are accessible on the About Chrome page. |
| 855 - (void)testAccessibilityOnGoogleChrome { |
| 856 [self openSubSettingMenu:googleChromeButton()]; |
| 857 chrome_test_util::VerifyAccessibilityForCurrentScreen(); |
| 858 [self closeSubSettingsMenu]; |
| 859 } |
| 860 |
| 861 // Verifies the UI elements are accessible on the Voice Search page. |
| 862 - (void)testAccessibilityOnVoiceSearch { |
| 863 [self openSubSettingMenu:voiceSearchButton()]; |
| 864 chrome_test_util::VerifyAccessibilityForCurrentScreen(); |
| 865 [self closeSubSettingsMenu]; |
| 866 } |
| 867 |
| 868 @end |
OLD | NEW |