| // 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 "base/ios/block_types.h" |
| #include "base/ios/ios_util.h" |
| #include "base/strings/sys_string_conversions.h" |
| #import "base/test/ios/wait_util.h" |
| #import "ios/chrome/browser/ui/authentication/signin_earl_grey.h" |
| #import "ios/chrome/browser/ui/authentication/signin_earl_grey_ui.h" |
| #import "ios/chrome/browser/ui/authentication/unified_consent/unified_consent_constants.h" |
| #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.h" |
| #import "ios/chrome/browser/ui/recent_tabs/recent_tabs_constants.h" |
| #include "ios/chrome/grit/ios_strings.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/public/provider/chrome/browser/signin/fake_chrome_identity.h" |
| #import "ios/public/provider/chrome/browser/signin/fake_chrome_identity_interaction_manager_constants.h" |
| #import "ios/testing/earl_grey/earl_grey_test.h" |
| #import "ios/testing/earl_grey/matchers.h" |
| #include "ui/base/l10n/l10n_util_mac.h" |
| |
| #if !defined(__has_feature) || !__has_feature(objc_arc) |
| #error "This file requires ARC support." |
| #endif |
| |
| using chrome_test_util::BookmarksNavigationBarDoneButton; |
| using chrome_test_util::ButtonWithAccessibilityLabelId; |
| using chrome_test_util::GoogleServicesSettingsView; |
| using chrome_test_util::PrimarySignInButton; |
| using chrome_test_util::SecondarySignInButton; |
| using chrome_test_util::SettingsDoneButton; |
| using chrome_test_util::SettingsImportDataContinueButton; |
| using chrome_test_util::SettingsImportDataImportButton; |
| using chrome_test_util::SettingsImportDataKeepSeparateButton; |
| using chrome_test_util::SettingsMenuBackButton; |
| using chrome_test_util::StaticTextWithAccessibilityLabelId; |
| using chrome_test_util::SyncSettingsConfirmButton; |
| using l10n_util::GetNSString; |
| using testing::ButtonWithAccessibilityLabel; |
| |
| typedef NS_ENUM(NSInteger, OpenSigninMethod) { |
| OpenSigninMethodFromSettings, |
| OpenSigninMethodFromBookmarks, |
| OpenSigninMethodFromRecentTabs, |
| OpenSigninMethodFromTabSwitcher, |
| }; |
| |
| namespace { |
| |
| // Returns a matcher for |userEmail| in IdentityChooserViewController. |
| id<GREYMatcher> identityChooserButtonMatcherWithEmail(NSString* userEmail) { |
| return grey_allOf(grey_accessibilityID(userEmail), |
| grey_kindOfClassName(@"IdentityChooserCell"), |
| grey_sufficientlyVisible(), nil); |
| } |
| |
| void ChooseImportOrKeepDataSepareteDialog(id<GREYMatcher> choiceButtonMatcher) { |
| // Set up the fake identities. |
| FakeChromeIdentity* fakeIdentity1 = [SigninEarlGrey fakeIdentity1]; |
| FakeChromeIdentity* fakeIdentity2 = [SigninEarlGrey fakeIdentity2]; |
| [SigninEarlGrey addFakeIdentity:fakeIdentity1]; |
| [SigninEarlGrey addFakeIdentity:fakeIdentity2]; |
| |
| // Sign in to |fakeIdentity1|. |
| [SigninEarlGreyUI signinWithFakeIdentity:fakeIdentity1]; |
| [SigninEarlGreyUI signOut]; |
| |
| // Sign in with |fakeIdentity2|. |
| [ChromeEarlGreyUI openSettingsMenu]; |
| [[EarlGrey selectElementWithMatcher:SecondarySignInButton()] |
| performAction:grey_tap()]; |
| [SigninEarlGreyUI selectIdentityWithEmail:fakeIdentity2.userEmail]; |
| [SigninEarlGreyUI tapSigninConfirmationDialog]; |
| |
| // Switch Sync account to |fakeIdentity2| should ask whether date should be |
| // imported or kept separate. Choose to keep data separate. |
| [[EarlGrey selectElementWithMatcher:choiceButtonMatcher] |
| performAction:grey_tap()]; |
| |
| [[EarlGrey selectElementWithMatcher:SettingsImportDataContinueButton()] |
| performAction:grey_tap()]; |
| |
| // Check the signed-in user did change. |
| [SigninEarlGrey verifySignedInWithFakeIdentity:fakeIdentity2]; |
| |
| [[EarlGrey selectElementWithMatcher:SettingsDoneButton()] |
| performAction:grey_tap()]; |
| } |
| |
| } // namespace |
| |
| // Sign-in interaction tests that work both with Unified Consent enabled or |
| // disabled. |
| @interface SigninCoordinatorTestCase : ChromeTestCase |
| @end |
| |
| @implementation SigninCoordinatorTestCase |
| |
| - (AppLaunchConfiguration)appConfigurationForTestCase { |
| AppLaunchConfiguration config; |
| config.features_disabled.push_back(kDiscoverFeedInNtp); |
| return config; |
| } |
| |
| - (void)setUp { |
| [super setUp]; |
| // Remove closed tab history to make sure the sign-in promo is always visible |
| // in recent tabs. |
| [ChromeEarlGrey clearBrowsingHistory]; |
| } |
| |
| // Tests that opening the sign-in screen from the Settings and signing in works |
| // correctly when there is already an identity on the device. |
| - (void)testSignInOneUser { |
| // Set up a fake identity. |
| FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1]; |
| [SigninEarlGreyUI signinWithFakeIdentity:fakeIdentity]; |
| |
| // Check |fakeIdentity| is signed-in. |
| [SigninEarlGrey verifySignedInWithFakeIdentity:fakeIdentity]; |
| } |
| |
| // Tests signing in with one account, switching sync account to a second and |
| // choosing to keep the browsing data separate during the switch. |
| - (void)testSignInSwitchAccountsAndKeepDataSeparate { |
| ChooseImportOrKeepDataSepareteDialog(SettingsImportDataKeepSeparateButton()); |
| } |
| |
| // Tests signing in with one account, switching sync account to a second and |
| // choosing to import the browsing data during the switch. |
| - (void)testSignInSwitchAccountsAndImportData { |
| ChooseImportOrKeepDataSepareteDialog(SettingsImportDataImportButton()); |
| } |
| |
| // Tests that signing out from the Settings works correctly. |
| - (void)testSignInDisconnectFromChrome { |
| FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1]; |
| [SigninEarlGreyUI signinWithFakeIdentity:fakeIdentity]; |
| |
| // Sign out. |
| [SigninEarlGreyUI signOut]; |
| } |
| |
| // Tests that signing out of a managed account from the Settings works |
| // correctly. |
| - (void)testSignInDisconnectFromChromeManaged { |
| // Sign-in with a managed account. |
| FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeManagedIdentity]; |
| [SigninEarlGreyUI signinWithFakeIdentity:fakeIdentity]; |
| |
| // Sign out. |
| [SigninEarlGreyUI signOutAndClearDataFromDevice]; |
| } |
| |
| // Opens the sign in screen and then cancel it by opening a new tab. Ensures |
| // that the sign in screen is correctly dismissed. crbug.com/462200 |
| - (void)testSignInCancelIdentityPicker { |
| // Add an identity to avoid arriving on the Add Account screen when opening |
| // sign-in. |
| FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1]; |
| [SigninEarlGrey addFakeIdentity:fakeIdentity]; |
| |
| [ChromeEarlGreyUI openSettingsMenu]; |
| [ChromeEarlGreyUI tapSettingsMenuButton:SecondarySignInButton()]; |
| // Waits until the UI is fully presented before opening an URL. |
| [ChromeEarlGreyUI waitForAppToIdle]; |
| |
| // Open new tab to cancel sign-in. |
| [ChromeEarlGrey simulateExternalAppURLOpening]; |
| |
| // Re-open the sign-in screen. If it wasn't correctly dismissed previously, |
| // this will fail. |
| [ChromeEarlGreyUI openSettingsMenu]; |
| [ChromeEarlGreyUI tapSettingsMenuButton:SecondarySignInButton()]; |
| [SigninEarlGreyUI selectIdentityWithEmail:fakeIdentity.userEmail]; |
| |
| // Verifies that the Chrome sign-in view is visible. |
| id<GREYMatcher> signin_matcher = StaticTextWithAccessibilityLabelId( |
| IDS_IOS_ACCOUNT_UNIFIED_CONSENT_SYNC_SUBTITLE); |
| [[EarlGrey selectElementWithMatcher:signin_matcher] |
| assertWithMatcher:grey_sufficientlyVisible()]; |
| |
| // Close sign-in screen and Settings. |
| [[EarlGrey selectElementWithMatcher: |
| ButtonWithAccessibilityLabelId( |
| IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_SKIP_BUTTON)] |
| performAction:grey_tap()]; |
| [[EarlGrey selectElementWithMatcher:SettingsDoneButton()] |
| performAction:grey_tap()]; |
| } |
| |
| // Starts an authentication flow and cancel it by opening a new tab. Ensures |
| // that the authentication flow is correctly canceled and dismissed. |
| // crbug.com/462202 |
| - (void)testSignInCancelAuthenticationFlow { |
| // Set up the fake identities. |
| FakeChromeIdentity* fakeIdentity1 = [SigninEarlGrey fakeIdentity1]; |
| FakeChromeIdentity* fakeIdentity2 = [SigninEarlGrey fakeIdentity2]; |
| [SigninEarlGrey addFakeIdentity:fakeIdentity1]; |
| [SigninEarlGrey addFakeIdentity:fakeIdentity2]; |
| |
| // This signs in |fakeIdentity2| first, ensuring that the "Clear Data Before |
| // Syncing" dialog is shown during the second sign-in. This dialog will |
| // effectively block the authentication flow, ensuring that the authentication |
| // flow is always still running when the sign-in is being cancelled. |
| [SigninEarlGreyUI signinWithFakeIdentity:fakeIdentity2]; |
| |
| // Sign out. |
| [SigninEarlGreyUI signOut]; |
| // Sign in with |fakeIdentity1|. |
| [ChromeEarlGreyUI openSettingsMenu]; |
| [[EarlGrey selectElementWithMatcher:SecondarySignInButton()] |
| performAction:grey_tap()]; |
| [SigninEarlGreyUI selectIdentityWithEmail:fakeIdentity1.userEmail]; |
| // The authentication flow is only created when the confirm button is |
| // selected. Note that authentication flow actually blocks as the |
| // "Clear Browsing Before Syncing" dialog is presented. |
| [SigninEarlGreyUI tapSigninConfirmationDialog]; |
| // Waits until the merge/delete data panel is shown. |
| [[EarlGrey selectElementWithMatcher:SettingsImportDataKeepSeparateButton()] |
| assertWithMatcher:grey_interactable()]; |
| |
| // Open new tab to cancel sign-in. |
| [ChromeEarlGrey simulateExternalAppURLOpening]; |
| |
| // Re-open the sign-in screen. If it wasn't correctly dismissed previously, |
| // this will fail. |
| [ChromeEarlGreyUI openSettingsMenu]; |
| [ChromeEarlGreyUI tapSettingsMenuButton:SecondarySignInButton()]; |
| [SigninEarlGreyUI selectIdentityWithEmail:fakeIdentity1.userEmail]; |
| |
| // Verifies that the Chrome sign-in view is visible. |
| id<GREYMatcher> signin_matcher = StaticTextWithAccessibilityLabelId( |
| IDS_IOS_ACCOUNT_UNIFIED_CONSENT_SYNC_SUBTITLE); |
| [[EarlGrey selectElementWithMatcher:signin_matcher] |
| assertWithMatcher:grey_sufficientlyVisible()]; |
| |
| // Close sign-in screen and Settings. |
| [[EarlGrey selectElementWithMatcher: |
| ButtonWithAccessibilityLabelId( |
| IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_SKIP_BUTTON)] |
| performAction:grey_tap()]; |
| [[EarlGrey selectElementWithMatcher:SettingsDoneButton()] |
| performAction:grey_tap()]; |
| [SigninEarlGrey verifySignedOut]; |
| } |
| |
| // Opens the sign in screen from the bookmarks and then cancel it by tapping on |
| // done. Ensures that the sign in screen is correctly dismissed. |
| // Regression test for crbug.com/596029. |
| - (void)testSignInCancelFromBookmarks { |
| FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1]; |
| [SigninEarlGrey addFakeIdentity:fakeIdentity]; |
| |
| // Open Bookmarks and tap on Sign In promo button. |
| [ChromeEarlGreyUI openToolsMenu]; |
| [ChromeEarlGreyUI tapToolsMenuButton:chrome_test_util::BookmarksMenuButton()]; |
| [ChromeEarlGreyUI tapSettingsMenuButton:SecondarySignInButton()]; |
| |
| // Assert sign-in screen was shown. |
| [SigninEarlGreyUI selectIdentityWithEmail:fakeIdentity.userEmail]; |
| |
| // Verifies that the Chrome sign-in view is visible. |
| id<GREYMatcher> signin_matcher = StaticTextWithAccessibilityLabelId( |
| IDS_IOS_ACCOUNT_UNIFIED_CONSENT_SYNC_SUBTITLE); |
| [[EarlGrey selectElementWithMatcher:signin_matcher] |
| assertWithMatcher:grey_sufficientlyVisible()]; |
| |
| // Open new tab to cancel sign-in. |
| [ChromeEarlGrey simulateExternalAppURLOpening]; |
| |
| // Re-open the sign-in screen. If it wasn't correctly dismissed previously, |
| // this will fail. |
| [ChromeEarlGreyUI openToolsMenu]; |
| [ChromeEarlGreyUI tapToolsMenuButton:chrome_test_util::BookmarksMenuButton()]; |
| [ChromeEarlGreyUI tapSettingsMenuButton:SecondarySignInButton()]; |
| [SigninEarlGreyUI selectIdentityWithEmail:fakeIdentity.userEmail]; |
| |
| // Verifies that the Chrome sign-in view is visible. |
| [[EarlGrey selectElementWithMatcher:signin_matcher] |
| assertWithMatcher:grey_sufficientlyVisible()]; |
| |
| // Close sign-in screen and Bookmarks. |
| [[EarlGrey selectElementWithMatcher: |
| ButtonWithAccessibilityLabelId( |
| IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_SKIP_BUTTON)] |
| performAction:grey_tap()]; |
| [[EarlGrey selectElementWithMatcher:BookmarksNavigationBarDoneButton()] |
| performAction:grey_tap()]; |
| } |
| |
| #pragma mark - Dismiss tests |
| |
| // Tests to dismiss sign-in by opening an URL from another app. |
| // Sign-in opened from: setting menu. |
| // Interrupted at: user consent. |
| - (void)testDismissSigninFromSettings { |
| [self assertOpenURLWhenSigninFromView:OpenSigninMethodFromSettings |
| tapSettingsLink:NO]; |
| } |
| |
| // Tests to dismiss sign-in by opening an URL from another app. |
| // Sign-in opened from: setting menu. |
| // Interrupted at: advanced sign-in. |
| - (void)testDismissAdvancedSigninSettingsFromAdvancedSigninSettings { |
| [self assertOpenURLWhenSigninFromView:OpenSigninMethodFromSettings |
| tapSettingsLink:YES]; |
| } |
| |
| // Tests to dismiss sign-in by opening an URL from another app. |
| // Sign-in opened from: bookmark view. |
| // Interrupted at: user consent. |
| - (void)testDismissSigninFromBookmarks { |
| [self assertOpenURLWhenSigninFromView:OpenSigninMethodFromBookmarks |
| tapSettingsLink:NO]; |
| } |
| |
| // Tests to dismiss sign-in by opening an URL from another app. |
| // Sign-in opened from: bookmark view. |
| // Interrupted at: advanced sign-in. |
| - (void)testDismissAdvancedSigninBookmarksFromAdvancedSigninSettings { |
| [self assertOpenURLWhenSigninFromView:OpenSigninMethodFromBookmarks |
| tapSettingsLink:YES]; |
| } |
| |
| // Tests to dismiss sign-in by opening an URL from another app. |
| // Sign-in opened from: recent tabs. |
| // Interrupted at: user consent. |
| - (void)testDismissSigninFromRecentTabs { |
| [self assertOpenURLWhenSigninFromView:OpenSigninMethodFromRecentTabs |
| tapSettingsLink:NO]; |
| } |
| |
| // Tests to dismiss sign-in by opening an URL from another app. |
| // Sign-in opened from: recent tabs. |
| // Interrupted at: identity selection in user consent. |
| - (void)testDismissIdentityPickerSigninFromRecentTabs { |
| FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1]; |
| [SigninEarlGrey addFakeIdentity:fakeIdentity]; |
| [self openSigninFromView:OpenSigninMethodFromRecentTabs tapSettingsLink:NO]; |
| [[EarlGrey selectElementWithMatcher:grey_accessibilityID( |
| kIdentityPickerViewIdentifier)] |
| performAction:grey_tap()]; |
| |
| // Open the URL as if it was opened from another app. |
| [ChromeEarlGrey simulateExternalAppURLOpening]; |
| |
| // Check if the URL was opened. |
| const GURL expectedURL("http://www.example.com/"); |
| GREYAssertEqual(expectedURL, [ChromeEarlGrey webStateVisibleURL], |
| @"Didn't open new tab with example.com."); |
| |
| // Should be not signed in. |
| [SigninEarlGrey verifySignedOut]; |
| } |
| |
| // Tests to dismiss sign-in by opening an URL from another app. |
| // Sign-in opened from: recent tabs. |
| // Interrupted at: advanced sign-in. |
| - (void)testDismissSigninFromRecentTabsFromAdvancedSigninSettings { |
| [self assertOpenURLWhenSigninFromView:OpenSigninMethodFromRecentTabs |
| tapSettingsLink:YES]; |
| } |
| |
| // Tests to dismiss sign-in by opening an URL from another app. |
| // Sign-in opened from: tab switcher. |
| // Interrupted at: user consent. |
| - (void)testDismissSigninFromTabSwitcher { |
| [self assertOpenURLWhenSigninFromView:OpenSigninMethodFromTabSwitcher |
| tapSettingsLink:NO]; |
| } |
| |
| // Tests to dismiss sign-in by opening an URL from another app. |
| // Sign-in opened from: tab switcher. |
| // Interrupted at: advanced sign-in. |
| - (void)testDismissSigninFromTabSwitcherFromAdvancedSigninSettings { |
| [self assertOpenURLWhenSigninFromView:OpenSigninMethodFromTabSwitcher |
| tapSettingsLink:YES]; |
| } |
| |
| // Verifies that advanced sign-in shows an alert dialog when being swiped to |
| // dismiss. |
| - (void)testSwipeDownToCancelAdvancedSignin { |
| if (!base::ios::IsRunningOnOrLater(13, 0, 0)) { |
| EARL_GREY_TEST_SKIPPED(@"Test disabled on iOS 12 and lower."); |
| } |
| FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1]; |
| [SigninEarlGrey addFakeIdentity:fakeIdentity]; |
| [self openSigninFromView:OpenSigninMethodFromSettings tapSettingsLink:YES]; |
| |
| [[EarlGrey selectElementWithMatcher:GoogleServicesSettingsView()] |
| performAction:grey_swipeFastInDirection(kGREYDirectionDown)]; |
| [[EarlGrey |
| selectElementWithMatcher: |
| ButtonWithAccessibilityLabel(GetNSString( |
| IDS_IOS_ADVANCED_SIGNIN_SETTINGS_CANCEL_SYNC_ALERT_CANCEL_SYNC_BUTTON))] |
| performAction:grey_tap()]; |
| [SigninEarlGrey verifySignedOut]; |
| } |
| |
| #pragma mark - Utils |
| |
| // Opens sign-in view. |
| // |openSigninMethod| is the way to start the sign-in. |
| // |tapSettingsLink| if YES, the setting link is tapped before opening the URL. |
| - (void)openSigninFromView:(OpenSigninMethod)openSigninMethod |
| tapSettingsLink:(BOOL)tapSettingsLink { |
| switch (openSigninMethod) { |
| case OpenSigninMethodFromSettings: |
| [ChromeEarlGreyUI openSettingsMenu]; |
| [ChromeEarlGreyUI tapSettingsMenuButton:PrimarySignInButton()]; |
| break; |
| case OpenSigninMethodFromBookmarks: |
| [ChromeEarlGreyUI openToolsMenu]; |
| [ChromeEarlGreyUI |
| tapToolsMenuButton:chrome_test_util::BookmarksMenuButton()]; |
| [[EarlGrey selectElementWithMatcher:PrimarySignInButton()] |
| performAction:grey_tap()]; |
| break; |
| case OpenSigninMethodFromRecentTabs: |
| [ChromeEarlGreyUI openToolsMenu]; |
| [ChromeEarlGreyUI |
| tapToolsMenuButton:chrome_test_util::RecentTabsMenuButton()]; |
| [SigninEarlGreyUI scrollToPrimarySignInButtonInRecentTabs]; |
| break; |
| case OpenSigninMethodFromTabSwitcher: |
| [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] |
| performAction:grey_tap()]; |
| [[EarlGrey selectElementWithMatcher:chrome_test_util:: |
| TabGridOtherDevicesPanelButton()] |
| performAction:grey_tap()]; |
| |
| [SigninEarlGreyUI collapseRecentlyClosedTabsIfSigninPromoNotVisible]; |
| [SigninEarlGreyUI scrollToPrimarySignInButtonInRecentTabs]; |
| break; |
| } |
| if (tapSettingsLink) { |
| [ChromeEarlGreyUI waitForAppToIdle]; |
| [SigninEarlGreyUI tapSettingsLink]; |
| } |
| [ChromeEarlGreyUI waitForAppToIdle]; |
| } |
| |
| // Starts the sign-in workflow, and simulates opening an URL from another app. |
| // |openSigninMethod| is the way to start the sign-in. |
| // |tapSettingsLink| if YES, the setting link is tapped before opening the URL. |
| - (void)assertOpenURLWhenSigninFromView:(OpenSigninMethod)openSigninMethod |
| tapSettingsLink:(BOOL)tapSettingsLink { |
| FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1]; |
| [SigninEarlGrey addFakeIdentity:fakeIdentity]; |
| [self openSigninFromView:openSigninMethod tapSettingsLink:tapSettingsLink]; |
| // Open the URL as if it was opened from another app. |
| [ChromeEarlGrey simulateExternalAppURLOpening]; |
| |
| // Check if the URL was opened. |
| const GURL expectedURL("http://www.example.com/"); |
| GREYAssertEqual(expectedURL, [ChromeEarlGrey webStateVisibleURL], |
| @"Didn't open new tab with example.com."); |
| |
| if (tapSettingsLink) { |
| // Should be signed in. |
| [SigninEarlGrey verifySignedInWithFakeIdentity:fakeIdentity]; |
| } else { |
| // Should be not signed in. |
| [SigninEarlGrey verifySignedOut]; |
| } |
| } |
| |
| // Checks that the fake SSO screen shown on adding an account is visible |
| // onscreen. |
| - (void)assertFakeSSOScreenIsVisible { |
| // Check for the fake SSO screen. |
| [ChromeEarlGrey |
| waitForMatcher:grey_accessibilityID(kFakeAddAccountViewIdentifier)]; |
| // Close the SSO view controller. |
| id<GREYMatcher> matcher = |
| grey_allOf(chrome_test_util::ButtonWithAccessibilityLabel(@"Cancel"), |
| grey_sufficientlyVisible(), nil); |
| [[EarlGrey selectElementWithMatcher:matcher] performAction:grey_tap()]; |
| // Make sure the SSO view controller is fully removed before ending the test. |
| // The tear down needs to remove other view controllers, and it cannot be done |
| // during the animation of the SSO view controler. |
| [ChromeEarlGreyUI waitForAppToIdle]; |
| } |
| |
| // Tests the "ADD ACCOUNT" button in the identity chooser view controller. |
| - (void)testAddAccountAutomatically { |
| [ChromeEarlGreyUI openSettingsMenu]; |
| [ChromeEarlGreyUI tapSettingsMenuButton:PrimarySignInButton()]; |
| [ChromeEarlGreyUI waitForAppToIdle]; |
| // Tap on "ADD ACCOUNT". |
| [SigninEarlGreyUI tapAddAccountButton]; |
| |
| [self assertFakeSSOScreenIsVisible]; |
| // Close sign-in screen and Settings. |
| [[EarlGrey selectElementWithMatcher: |
| ButtonWithAccessibilityLabelId( |
| IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_SKIP_BUTTON)] |
| performAction:grey_tap()]; |
| [ChromeEarlGreyUI waitForAppToIdle]; |
| } |
| |
| // Tests that an add account operation triggered from the web is handled. |
| // Regression test for crbug.com/1054861. |
| - (void)testSigninAddAccountFromWeb { |
| [ChromeEarlGrey simulateAddAccountFromWeb]; |
| |
| [self assertFakeSSOScreenIsVisible]; |
| } |
| |
| // Tests to remove the last identity in the identity chooser. |
| - (void)testRemoveLastAccount { |
| // Set up a fake identity. |
| FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1]; |
| [SigninEarlGrey addFakeIdentity:fakeIdentity]; |
| |
| // Open the identity chooser. |
| [ChromeEarlGreyUI openSettingsMenu]; |
| [ChromeEarlGreyUI tapSettingsMenuButton:SecondarySignInButton()]; |
| [ChromeEarlGrey waitForMatcher:identityChooserButtonMatcherWithEmail( |
| fakeIdentity.userEmail)]; |
| |
| // Remove the fake identity. |
| [SigninEarlGrey forgetFakeIdentity:fakeIdentity]; |
| |
| // Check that the identity has been removed. |
| [[EarlGrey selectElementWithMatcher:identityChooserButtonMatcherWithEmail( |
| fakeIdentity.userEmail)] |
| assertWithMatcher:grey_notVisible()]; |
| } |
| |
| // Opens the add account screen and then cancels it by opening a new tab. |
| // Ensures that the add account screen is correctly dismissed. crbug.com/462200 |
| - (void)testSignInCancelAddAccount { |
| // Add an identity to avoid arriving on the Add Account screen when opening |
| // sign-in. |
| FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1]; |
| [SigninEarlGrey addFakeIdentity:fakeIdentity]; |
| |
| [ChromeEarlGreyUI openSettingsMenu]; |
| [ChromeEarlGreyUI tapSettingsMenuButton:SecondarySignInButton()]; |
| |
| // Open Add Account screen. |
| id<GREYMatcher> add_account_matcher = |
| chrome_test_util::StaticTextWithAccessibilityLabelId( |
| IDS_IOS_ACCOUNT_IDENTITY_CHOOSER_ADD_ACCOUNT); |
| [[EarlGrey selectElementWithMatcher:add_account_matcher] |
| performAction:grey_tap()]; |
| [ChromeEarlGreyUI waitForAppToIdle]; |
| |
| // Open new tab to cancel sign-in. |
| [ChromeEarlGrey simulateExternalAppURLOpening]; |
| |
| // Re-open the sign-in screen. If it wasn't correctly dismissed previously, |
| // this will fail. |
| [ChromeEarlGreyUI openSettingsMenu]; |
| [ChromeEarlGreyUI tapSettingsMenuButton:SecondarySignInButton()]; |
| [SigninEarlGreyUI selectIdentityWithEmail:fakeIdentity.userEmail]; |
| |
| // Verifies that the Chrome sign-in view is visible. |
| id<GREYMatcher> signin_matcher = StaticTextWithAccessibilityLabelId( |
| IDS_IOS_ACCOUNT_UNIFIED_CONSENT_SYNC_SUBTITLE); |
| [[EarlGrey selectElementWithMatcher:signin_matcher] |
| assertWithMatcher:grey_sufficientlyVisible()]; |
| |
| // Close sign-in screen and Settings. |
| [[EarlGrey selectElementWithMatcher: |
| ButtonWithAccessibilityLabelId( |
| IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_SKIP_BUTTON)] |
| performAction:grey_tap()]; |
| [[EarlGrey selectElementWithMatcher:SettingsDoneButton()] |
| performAction:grey_tap()]; |
| } |
| |
| // Simulates a potential race condition in which the account is invalidated |
| // after the user taps the Settings button to navigate to the identity |
| // choosing UI. Depending on the timing, the account removal may occur after |
| // the UI has retrieved the list of valid accounts. The test ensures that in |
| // this case no account is presented to the user. |
| - (void)testAccountInvalidatedDuringSignin { |
| FakeChromeIdentity* fakeIdentity = [SigninEarlGrey fakeIdentity1]; |
| [SigninEarlGrey addFakeIdentity:fakeIdentity]; |
| |
| [ChromeEarlGreyUI openSettingsMenu]; |
| [ChromeEarlGreyUI tapSettingsMenuButton:SecondarySignInButton()]; |
| |
| // Invalidate account after menu generation. If the underlying code does not |
| // handle the race condition of removing an identity while showing menu is in |
| // progress this test will likely be flaky. |
| [SigninEarlGrey forgetFakeIdentity:fakeIdentity]; |
| // Check that the identity has been removed. |
| [[EarlGrey selectElementWithMatcher:identityChooserButtonMatcherWithEmail( |
| fakeIdentity.userEmail)] |
| assertWithMatcher:grey_notVisible()]; |
| } |
| |
| @end |