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 <XCTest/XCTest.h> |
| 7 |
| 8 #include "base/strings/sys_string_conversions.h" |
| 9 #include "components/signin/core/browser/signin_manager.h" |
| 10 #include "components/strings/grit/components_strings.h" |
| 11 #include "ios/chrome/browser/signin/signin_manager_factory.h" |
| 12 #import "ios/chrome/browser/ui/settings/accounts_collection_view_controller.h" |
| 13 #import "ios/chrome/browser/ui/settings/settings_collection_view_controller.h" |
| 14 #import "ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.h" |
| 15 #import "ios/chrome/browser/ui/tools_menu/tools_popup_controller.h" |
| 16 #include "ios/chrome/grit/ios_strings.h" |
| 17 #import "ios/chrome/test/app/chrome_test_util.h" |
| 18 #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" |
| 19 #import "ios/chrome/test/earl_grey/chrome_matchers.h" |
| 20 #import "ios/chrome/test/earl_grey/chrome_test_case.h" |
| 21 #import "ios/public/provider/chrome/browser/signin/fake_chrome_identity.h" |
| 22 #import "ios/public/provider/chrome/browser/signin/fake_chrome_identity_service.
h" |
| 23 #import "ios/testing/earl_grey/disabled_test_macros.h" |
| 24 |
| 25 namespace { |
| 26 |
| 27 // Returns a fake identity. |
| 28 ChromeIdentity* GetFakeIdentity1() { |
| 29 return [FakeChromeIdentity identityWithEmail:@"foo@gmail.com" |
| 30 gaiaID:@"fooID" |
| 31 name:@"Fake Foo"]; |
| 32 } |
| 33 |
| 34 // Returns a second fake identity. |
| 35 ChromeIdentity* GetFakeIdentity2() { |
| 36 return [FakeChromeIdentity identityWithEmail:@"bar@gmail.com" |
| 37 gaiaID:@"barID" |
| 38 name:@"Fake Bar"]; |
| 39 } |
| 40 |
| 41 // Taps the view with acessibility identifier |accessibility_id|. |
| 42 void TapViewWithAccessibilityId(NSString* accessiblity_id) { |
| 43 // grey_sufficientlyVisible() is necessary because reloading a cell in a |
| 44 // collection view might duplicate it (with the old one being hidden but |
| 45 // EarlGrey can find it). |
| 46 id<GREYMatcher> matcher = grey_allOf(grey_accessibilityID(accessiblity_id), |
| 47 grey_sufficientlyVisible(), nil); |
| 48 [[EarlGrey selectElementWithMatcher:matcher] performAction:grey_tap()]; |
| 49 } |
| 50 |
| 51 // Taps the button with accessibility label |label|. |
| 52 void TapButtonWithAccessibilityLabel(NSString* label) { |
| 53 id<GREYMatcher> matcher = |
| 54 chrome_test_util::buttonWithAccessibilityLabel(label); |
| 55 [[EarlGrey selectElementWithMatcher:matcher] performAction:grey_tap()]; |
| 56 } |
| 57 |
| 58 // Taps the button with accessibility labelId |message_id|. |
| 59 void TapButtonWithLabelId(int message_id) { |
| 60 id<GREYMatcher> matcher = |
| 61 chrome_test_util::buttonWithAccessibilityLabelId(message_id); |
| 62 [[EarlGrey selectElementWithMatcher:matcher] performAction:grey_tap()]; |
| 63 } |
| 64 |
| 65 // Opens the signin screen from the settings page. Assumes the tools menu is |
| 66 // accessible. User must not be signed in. |
| 67 void OpenSignInFromSettings() { |
| 68 const CGFloat scroll_displacement = 50.0; |
| 69 |
| 70 [ChromeEarlGreyUI openToolsMenu]; |
| 71 [[[EarlGrey |
| 72 selectElementWithMatcher:grey_accessibilityID(kToolsMenuSettingsId)] |
| 73 usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, |
| 74 scroll_displacement) |
| 75 onElementWithMatcher:grey_accessibilityID(kToolsMenuTableViewId)] |
| 76 performAction:grey_tap()]; |
| 77 |
| 78 TapViewWithAccessibilityId(kSettingsSignInCellId); |
| 79 } |
| 80 |
| 81 // Asserts that |identity| is actually signed in to the active profile. |
| 82 void AssertAuthenticatedIdentityInActiveProfile(ChromeIdentity* identity) { |
| 83 [[GREYUIThreadExecutor sharedInstance] drainUntilIdle]; |
| 84 |
| 85 ios::ChromeBrowserState* browser_state = |
| 86 chrome_test_util::GetOriginalBrowserState(); |
| 87 AccountInfo info = |
| 88 ios::SigninManagerFactory::GetForBrowserState(browser_state) |
| 89 ->GetAuthenticatedAccountInfo(); |
| 90 |
| 91 GREYAssertEqual(base::SysNSStringToUTF8(identity.gaiaID), info.gaia, |
| 92 @"Unexpected Gaia ID of the signed in user [expected = " |
| 93 @"\"%@\", actual = \"%s\"]", |
| 94 identity.gaiaID, info.gaia.c_str()); |
| 95 } |
| 96 } |
| 97 |
| 98 // Integration tests using the Account Settings screen. |
| 99 @interface AccountCollectionsTestCase : ChromeTestCase |
| 100 @end |
| 101 |
| 102 @implementation AccountCollectionsTestCase |
| 103 |
| 104 // Tests that the Sync and Account Settings screen are correctly popped if the |
| 105 // signed in account is removed. |
| 106 - (void)testSignInPopUpAccountOnSyncSettings { |
| 107 ChromeIdentity* identity = GetFakeIdentity1(); |
| 108 ios::FakeChromeIdentityService::GetInstanceFromChromeProvider()->AddIdentity( |
| 109 identity); |
| 110 |
| 111 // Sign In |identity|, then open the Sync Settings. |
| 112 OpenSignInFromSettings(); |
| 113 TapButtonWithAccessibilityLabel(identity.userEmail); |
| 114 TapButtonWithLabelId(IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_SIGNIN_BUTTON); |
| 115 TapButtonWithLabelId(IDS_IOS_ACCOUNT_CONSISTENCY_CONFIRMATION_OK_BUTTON); |
| 116 AssertAuthenticatedIdentityInActiveProfile(identity); |
| 117 TapViewWithAccessibilityId(kSettingsAccountCellId); |
| 118 TapViewWithAccessibilityId(kSettingsAccountsSyncCellId); |
| 119 |
| 120 // Forget |identity|, screens should be popped back to the Main Settings. |
| 121 [[GREYUIThreadExecutor sharedInstance] drainUntilIdle]; |
| 122 ios::FakeChromeIdentityService::GetInstanceFromChromeProvider() |
| 123 ->ForgetIdentity(identity, nil); |
| 124 |
| 125 [[EarlGrey |
| 126 selectElementWithMatcher:grey_accessibilityID(kSettingsSignInCellId)] |
| 127 assertWithMatcher:grey_sufficientlyVisible()]; |
| 128 AssertAuthenticatedIdentityInActiveProfile(nil); |
| 129 |
| 130 // Close Settings. |
| 131 TapButtonWithLabelId(IDS_IOS_NAVIGATION_BAR_DONE_BUTTON); |
| 132 } |
| 133 |
| 134 // Tests that the Account Settings screen is correctly popped if the signed in |
| 135 // account is removed while the "Disconnect Account" dialog is up. |
| 136 - (void)testSignInPopUpAccountOnDisconnectAccount { |
| 137 ChromeIdentity* identity = GetFakeIdentity1(); |
| 138 ios::FakeChromeIdentityService::GetInstanceFromChromeProvider()->AddIdentity( |
| 139 identity); |
| 140 |
| 141 // Sign In |identity|, then open the Account Settings. |
| 142 OpenSignInFromSettings(); |
| 143 TapButtonWithAccessibilityLabel(identity.userEmail); |
| 144 TapButtonWithLabelId(IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_SIGNIN_BUTTON); |
| 145 TapButtonWithLabelId(IDS_IOS_ACCOUNT_CONSISTENCY_CONFIRMATION_OK_BUTTON); |
| 146 AssertAuthenticatedIdentityInActiveProfile(identity); |
| 147 TapViewWithAccessibilityId(kSettingsAccountCellId); |
| 148 |
| 149 // Open the "Disconnect Account" dialog. |
| 150 const CGFloat scroll_displacement = 100.0; |
| 151 [[[EarlGrey selectElementWithMatcher:grey_accessibilityID( |
| 152 kSettingsAccountsSignoutCellId)] |
| 153 usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, |
| 154 scroll_displacement) |
| 155 onElementWithMatcher:grey_accessibilityID(kSettingsAccountsId)] |
| 156 performAction:grey_tap()]; |
| 157 |
| 158 // Forget |identity|, screens should be popped back to the Main Settings. |
| 159 [[GREYUIThreadExecutor sharedInstance] drainUntilIdle]; |
| 160 ios::FakeChromeIdentityService::GetInstanceFromChromeProvider() |
| 161 ->ForgetIdentity(identity, nil); |
| 162 |
| 163 [[EarlGrey |
| 164 selectElementWithMatcher:grey_accessibilityID(kSettingsSignInCellId)] |
| 165 assertWithMatcher:grey_sufficientlyVisible()]; |
| 166 AssertAuthenticatedIdentityInActiveProfile(nil); |
| 167 |
| 168 // Close Settings. |
| 169 TapButtonWithLabelId(IDS_IOS_NAVIGATION_BAR_DONE_BUTTON); |
| 170 } |
| 171 |
| 172 // Tests that the Account Settings screen is correctly reloaded when one of |
| 173 // the non-primary account is removed. |
| 174 - (void)testSignInReloadOnRemoveAccount { |
| 175 ios::FakeChromeIdentityService* identity_service = |
| 176 ios::FakeChromeIdentityService::GetInstanceFromChromeProvider(); |
| 177 ChromeIdentity* identity1 = GetFakeIdentity1(); |
| 178 ChromeIdentity* identity2 = GetFakeIdentity2(); |
| 179 identity_service->AddIdentity(identity1); |
| 180 identity_service->AddIdentity(identity2); |
| 181 |
| 182 // Sign In |identity|, then open the Account Settings. |
| 183 OpenSignInFromSettings(); |
| 184 TapButtonWithAccessibilityLabel(identity1.userEmail); |
| 185 TapButtonWithLabelId(IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_SIGNIN_BUTTON); |
| 186 TapButtonWithLabelId(IDS_IOS_ACCOUNT_CONSISTENCY_CONFIRMATION_OK_BUTTON); |
| 187 AssertAuthenticatedIdentityInActiveProfile(identity1); |
| 188 TapViewWithAccessibilityId(kSettingsAccountCellId); |
| 189 |
| 190 // Remove |identity2| from the device. |
| 191 TapButtonWithAccessibilityLabel(identity2.userEmail); |
| 192 TapButtonWithAccessibilityLabel(@"Remove account"); |
| 193 |
| 194 // Check that |identity2| isn't available anymore on the Account Settings. |
| 195 [[EarlGrey |
| 196 selectElementWithMatcher:grey_allOf( |
| 197 grey_accessibilityLabel(identity2.userEmail), |
| 198 grey_sufficientlyVisible(), nil)] |
| 199 assertWithMatcher:grey_nil()]; |
| 200 AssertAuthenticatedIdentityInActiveProfile(identity1); |
| 201 |
| 202 // Close Settings. |
| 203 TapButtonWithLabelId(IDS_IOS_NAVIGATION_BAR_DONE_BUTTON); |
| 204 } |
| 205 |
| 206 // Tests that the Sync Settings screen is correctly reloaded when one of the |
| 207 // secondary accounts disappears. |
| 208 - (void)testSignInReloadSyncOnForgetIdentity { |
| 209 ios::FakeChromeIdentityService* identity_service = |
| 210 ios::FakeChromeIdentityService::GetInstanceFromChromeProvider(); |
| 211 ChromeIdentity* identity1 = GetFakeIdentity1(); |
| 212 ChromeIdentity* identity2 = GetFakeIdentity2(); |
| 213 identity_service->AddIdentity(identity1); |
| 214 identity_service->AddIdentity(identity2); |
| 215 |
| 216 // Sign In |identity|, then open the Sync Settings. |
| 217 OpenSignInFromSettings(); |
| 218 TapButtonWithAccessibilityLabel(identity1.userEmail); |
| 219 TapButtonWithLabelId(IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_SIGNIN_BUTTON); |
| 220 TapButtonWithLabelId(IDS_IOS_ACCOUNT_CONSISTENCY_CONFIRMATION_OK_BUTTON); |
| 221 AssertAuthenticatedIdentityInActiveProfile(identity1); |
| 222 TapViewWithAccessibilityId(kSettingsAccountCellId); |
| 223 TapViewWithAccessibilityId(kSettingsAccountsSyncCellId); |
| 224 |
| 225 // Forget |identity2|. |
| 226 [[GREYUIThreadExecutor sharedInstance] drainUntilIdle]; |
| 227 identity_service->ForgetIdentity(identity2, nil); |
| 228 |
| 229 // Check that both |identity1| and |identity2| aren't shown in the Sync |
| 230 // Settings. |
| 231 [[EarlGrey |
| 232 selectElementWithMatcher:grey_allOf( |
| 233 grey_accessibilityLabel(identity1.userEmail), |
| 234 grey_sufficientlyVisible(), nil)] |
| 235 assertWithMatcher:grey_nil()]; |
| 236 [[EarlGrey |
| 237 selectElementWithMatcher:grey_allOf( |
| 238 grey_accessibilityLabel(identity2.userEmail), |
| 239 grey_sufficientlyVisible(), nil)] |
| 240 assertWithMatcher:grey_nil()]; |
| 241 AssertAuthenticatedIdentityInActiveProfile(identity1); |
| 242 |
| 243 // Close Settings. |
| 244 TapButtonWithLabelId(IDS_IOS_NAVIGATION_BAR_DONE_BUTTON); |
| 245 } |
| 246 |
| 247 // Tests that the Account Settings screen is popped and the user signed out |
| 248 // when the account is removed. |
| 249 - (void)testSignOutOnRemoveAccount { |
| 250 ChromeIdentity* identity = GetFakeIdentity1(); |
| 251 ios::FakeChromeIdentityService::GetInstanceFromChromeProvider()->AddIdentity( |
| 252 identity); |
| 253 |
| 254 // Sign In |identity|, then open the Account Settings. |
| 255 OpenSignInFromSettings(); |
| 256 TapButtonWithAccessibilityLabel(identity.userEmail); |
| 257 TapButtonWithLabelId(IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_SIGNIN_BUTTON); |
| 258 TapButtonWithLabelId(IDS_IOS_ACCOUNT_CONSISTENCY_CONFIRMATION_OK_BUTTON); |
| 259 AssertAuthenticatedIdentityInActiveProfile(identity); |
| 260 TapViewWithAccessibilityId(kSettingsAccountCellId); |
| 261 |
| 262 // Remove |identity| from the device. |
| 263 TapButtonWithAccessibilityLabel(identity.userEmail); |
| 264 TapButtonWithAccessibilityLabel(@"Remove account"); |
| 265 |
| 266 // Check that the user is signed out and the Main Settings screen is shown. |
| 267 [[EarlGrey |
| 268 selectElementWithMatcher:grey_accessibilityID(kSettingsSignInCellId)] |
| 269 assertWithMatcher:grey_sufficientlyVisible()]; |
| 270 AssertAuthenticatedIdentityInActiveProfile(nil); |
| 271 |
| 272 // Close Settings. |
| 273 TapButtonWithLabelId(IDS_IOS_NAVIGATION_BAR_DONE_BUTTON); |
| 274 } |
| 275 |
| 276 // Tests that the user isn't signed out and the UI is correct when the |
| 277 // disconnect is cancelled in the Account Settings screen. |
| 278 - (void)testSignInDisconnectCancelled { |
| 279 // TODO(crbug.com/669613): Re-enable this test on devices. |
| 280 #if !TARGET_IPHONE_SIMULATOR |
| 281 EARL_GREY_TEST_DISABLED(@"Test disabled on device."); |
| 282 #endif |
| 283 ChromeIdentity* identity = GetFakeIdentity1(); |
| 284 ios::FakeChromeIdentityService::GetInstanceFromChromeProvider()->AddIdentity( |
| 285 identity); |
| 286 |
| 287 // Sign In |identity|, then open the Account Settings. |
| 288 OpenSignInFromSettings(); |
| 289 TapButtonWithAccessibilityLabel(identity.userEmail); |
| 290 TapButtonWithLabelId(IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_SIGNIN_BUTTON); |
| 291 TapButtonWithLabelId(IDS_IOS_ACCOUNT_CONSISTENCY_CONFIRMATION_OK_BUTTON); |
| 292 AssertAuthenticatedIdentityInActiveProfile(identity); |
| 293 TapViewWithAccessibilityId(kSettingsAccountCellId); |
| 294 |
| 295 // Open the "Disconnect Account" dialog, then tap "Cancel". |
| 296 const CGFloat scroll_displacement = 100.0; |
| 297 [[[EarlGrey selectElementWithMatcher:grey_accessibilityID( |
| 298 kSettingsAccountsSignoutCellId)] |
| 299 usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, |
| 300 scroll_displacement) |
| 301 onElementWithMatcher:grey_accessibilityID(kSettingsAccountsId)] |
| 302 performAction:grey_tap()]; |
| 303 TapButtonWithLabelId(IDS_CANCEL); |
| 304 |
| 305 // Check that Account Settings screen is open and |identity| is signed in. |
| 306 [[EarlGrey selectElementWithMatcher:grey_accessibilityID(kSettingsAccountsId)] |
| 307 assertWithMatcher:grey_sufficientlyVisible()]; |
| 308 AssertAuthenticatedIdentityInActiveProfile(identity); |
| 309 |
| 310 // Close Settings. |
| 311 TapButtonWithLabelId(IDS_IOS_NAVIGATION_BAR_DONE_BUTTON); |
| 312 } |
| 313 |
| 314 @end |
OLD | NEW |