[iOS][Restore]Create an eg test for the restore promo

This test ensures that, if Chrome starts with an account, and we
simulate a post device restore, the promo to add back the account is
opened, and the continue button open the add account view.

This required a lot of preparation work. As far as I can see, promos
were generally not tested. I hope this CL will show to to proceed
to eg test them.


I also need to ensure to add a test switch whose behavior is the same
as the experimental flag to simulate post device restore. Indeed, we
want to test the same feature.

I need to sign-in at startup. Which currently most work after a restart and not the initial start.

Given that this alert is implemented as a promo, I also needed to
use `kEnableIPH` to allow this promo to be enabled. By default, they
all are disabled in eg tests.

To be more specific, they are all disabled by two switches.
I removed the second and redundant switch in crrev.com/c/6172453.


Change-Id: Ia4f8a35fcf226babfa1cda575a8e22a688c18a6a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6170430
Reviewed-by: Jérôme Lebel <jlebel@chromium.org>
Commit-Queue: Arthur Milchior <arthurmilchior@chromium.org>
Commit-Queue: Jérôme Lebel <jlebel@chromium.org>
Commit-Queue: David Roger <droger@chromium.org>
Auto-Submit: Arthur Milchior <arthurmilchior@chromium.org>
Reviewed-by: David Roger <droger@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1408636}
diff --git a/ios/chrome/app/perf_tests_hook.mm b/ios/chrome/app/perf_tests_hook.mm
index 03ef79f..8b3c913 100644
--- a/ios/chrome/app/perf_tests_hook.mm
+++ b/ios/chrome/app/perf_tests_hook.mm
@@ -67,6 +67,9 @@
 policy::ConfigurationPolicyProvider* GetOverriddenPlatformPolicyProvider() {
   return nullptr;
 }
+bool SimulatePostDeviceRestore() {
+  return false;
+}
 std::unique_ptr<SystemIdentityManager> CreateSystemIdentityManager() {
   return nullptr;
 }
diff --git a/ios/chrome/app/tests_fake_hook.mm b/ios/chrome/app/tests_fake_hook.mm
index 11bc671..ddbf9047 100644
--- a/ios/chrome/app/tests_fake_hook.mm
+++ b/ios/chrome/app/tests_fake_hook.mm
@@ -51,6 +51,9 @@
 policy::ConfigurationPolicyProvider* GetOverriddenPlatformPolicyProvider() {
   return nullptr;
 }
+bool SimulatePostDeviceRestore() {
+  return false;
+}
 std::unique_ptr<SystemIdentityManager> CreateSystemIdentityManager() {
   return nullptr;
 }
diff --git a/ios/chrome/app/tests_hook.h b/ios/chrome/app/tests_hook.h
index 4907beb..a6b5dcd 100644
--- a/ios/chrome/app/tests_hook.h
+++ b/ios/chrome/app/tests_hook.h
@@ -112,6 +112,11 @@
 // provider when testing. May return nullptr.
 policy::ConfigurationPolicyProvider* GetOverriddenPlatformPolicyProvider();
 
+// Whether a phone backup/restore state should be simulated for testing purpose.
+// Uses`experimental_flags::SimulatePostDeviceRestore()` to check whether this
+// feature should be enabled due to experimental feature.
+bool SimulatePostDeviceRestore();
+
 // Allows overriding the SystemIdentityManager factory. The real factory will
 // be used if this hook returns null.
 std::unique_ptr<SystemIdentityManager> CreateSystemIdentityManager();
diff --git a/ios/chrome/browser/post_restore_signin/ui_bundled/BUILD.gn b/ios/chrome/browser/post_restore_signin/ui_bundled/BUILD.gn
index 030771c..ac07be4 100644
--- a/ios/chrome/browser/post_restore_signin/ui_bundled/BUILD.gn
+++ b/ios/chrome/browser/post_restore_signin/ui_bundled/BUILD.gn
@@ -62,3 +62,22 @@
     "//ui/base",
   ]
 }
+
+source_set("eg2_tests") {
+  configs += [ "//build/config/ios:xctest_config" ]
+  testonly = true
+  sources = [ "post_restore_signin_egtest.mm" ]
+  deps = [
+    "//components/signin/public/base",
+    "//ios/chrome/app/strings",
+    "//ios/chrome/browser/authentication/ui_bundled:eg_test_support+eg2",
+    "//ios/chrome/browser/metrics/model:eg_test_support+eg2",
+    "//ios/chrome/browser/shared/public/features:system_flags",
+    "//ios/chrome/browser/signin/model:fake_system_identity",
+    "//ios/chrome/browser/signin/model:test_constants",
+    "//ios/chrome/test/earl_grey:eg_test_support+eg2",
+    "//ios/chrome/test/earl_grey:switches",
+    "//ios/testing/earl_grey:eg_test_support+eg2",
+    "//ui/base",
+  ]
+}
diff --git a/ios/chrome/browser/post_restore_signin/ui_bundled/post_restore_signin_egtest.mm b/ios/chrome/browser/post_restore_signin/ui_bundled/post_restore_signin_egtest.mm
new file mode 100644
index 0000000..2b65ab1
--- /dev/null
+++ b/ios/chrome/browser/post_restore_signin/ui_bundled/post_restore_signin_egtest.mm
@@ -0,0 +1,116 @@
+// Copyright 2025 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "components/signin/public/base/signin_metrics.h"
+#import "ios/chrome/browser/authentication/ui_bundled/expected_signin_histograms.h"
+#import "ios/chrome/browser/authentication/ui_bundled/signin_earl_grey.h"
+#import "ios/chrome/browser/metrics/model/metrics_app_interface.h"
+#import "ios/chrome/browser/shared/public/features/system_flags.h"
+#import "ios/chrome/browser/signin/model/fake_system_identity.h"
+#import "ios/chrome/browser/signin/model/test_constants.h"
+#import "ios/chrome/grit/ios_branded_strings.h"
+#import "ios/chrome/grit/ios_strings.h"
+#import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
+#import "ios/chrome/test/earl_grey/chrome_test_case.h"
+#import "ios/chrome/test/earl_grey/test_switches.h"
+#import "ios/testing/earl_grey/app_launch_manager.h"
+#import "ios/testing/earl_grey/earl_grey_test.h"
+#import "ui/base/l10n/l10n_util.h"
+
+namespace {
+
+// The primary identity.
+FakeSystemIdentity* const kPrimaryIdentity = [FakeSystemIdentity fakeIdentity1];
+
+}  // namespace
+
+@interface PostRestoreSigninTestCase : ChromeTestCase
+@end
+
+@implementation PostRestoreSigninTestCase
+
+- (void)setUp {
+  [super setUp];
+
+  [SigninEarlGrey signinWithFakeIdentity:kPrimaryIdentity];
+
+  // Create the config to relaunch Chrome.
+  AppLaunchConfiguration config;
+  config.relaunch_policy = ForceRelaunchByCleanShutdown;
+
+  // Add the switch to make sure that fakeIdentity1 is known at startup to avoid
+  // automatic sign out.
+  config.additional_args.push_back(
+      std::string("-") + test_switches::kAddFakeIdentitiesAtStartup + "=" +
+      [FakeSystemIdentity encodeIdentitiesToBase64:@[ kPrimaryIdentity ]]);
+  config.additional_args.push_back(std::string("-") +
+                                   test_switches::kSimulatePostDeviceRestore);
+  // The post-restore signin alert is a promo, and promo are implemented as IPH.
+  // All IPH are disabled by default in EGtests. This flag enable this
+  // particular IPH.
+  config.additional_args.push_back(std::string("-") +
+                                   test_switches::kEnableIPH +
+                                   "=IPH_iOSPromoPostRestore");
+
+  // Relaunch the app to take the configuration into account.
+  [[AppLaunchManager sharedManager] ensureAppLaunchedWithConfiguration:config];
+  chrome_test_util::GREYAssertErrorNil(
+      [MetricsAppInterface setupHistogramTester]);
+
+  [SigninEarlGrey verifySignedOut];
+  [[EarlGrey selectElementWithMatcher:
+                 grey_text(l10n_util::GetNSString(
+                     IDS_IOS_POST_RESTORE_SIGN_IN_ALERT_PROMO_TITLE))]
+      assertWithMatcher:grey_sufficientlyVisible()];
+}
+
+// Test that continue opens the add account view.
+- (void)testContinue {
+  // Tap on 'Continue' to present the add account view.
+  [[EarlGrey
+      selectElementWithMatcher:
+          grey_text(l10n_util::GetNSString(
+              IDS_IOS_POST_RESTORE_SIGN_IN_FULLSCREEN_PRIMARY_ACTION_SHORT))]
+      performAction:grey_tap()];
+
+  // Ensure the fake add-account menu is
+  // displayed. The existence of the "add
+  // account" accessibility button on screen verifies that the screen
+  // was shown.
+  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
+                                          kFakeAuthAddAccountButtonIdentifier)]
+      assertWithMatcher:grey_notNil()];
+
+  ExpectedSigninHistograms* expecteds = [[ExpectedSigninHistograms alloc]
+      initWithAccessPoint:signin_metrics::AccessPoint::
+                              ACCESS_POINT_POST_DEVICE_RESTORE_SIGNIN_PROMO];
+  // TODO(crbug.com/41493423): We should log that the signin was offered,
+  // and started.
+  [SigninEarlGrey assertExpectedSigninHistograms:expecteds];
+}
+
+// Test that cancel does not opens the add account view.
+- (void)testCancel {
+  // Tap on 'Cancel' to present the add account view.
+  [[EarlGrey selectElementWithMatcher:
+                 grey_text(l10n_util::GetNSString(
+                     IDS_IOS_POST_RESTORE_SIGN_IN_ALERT_PROMO_CANCEL_ACTION))]
+      performAction:grey_tap()];
+
+  // Ensure the fake add-account menu is
+  // not displayed. The absence of the "add
+  // account" accessibility button on screen verifies that the screen
+  // was not shown.
+  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
+                                          kFakeAuthCancelButtonIdentifier)]
+      assertWithMatcher:grey_nil()];
+
+  ExpectedSigninHistograms* expecteds = [[ExpectedSigninHistograms alloc]
+      initWithAccessPoint:signin_metrics::AccessPoint::
+                              ACCESS_POINT_POST_DEVICE_RESTORE_SIGNIN_PROMO];
+  // TODO(crbug.com/41493423): We should log that the signin was offered.
+  [SigninEarlGrey assertExpectedSigninHistograms:expecteds];
+}
+
+@end
diff --git a/ios/chrome/browser/shared/public/features/system_flags.h b/ios/chrome/browser/shared/public/features/system_flags.h
index b73ec054..c062095f 100644
--- a/ios/chrome/browser/shared/public/features/system_flags.h
+++ b/ios/chrome/browser/shared/public/features/system_flags.h
@@ -136,7 +136,9 @@
 // former takes precedence.
 std::string GetSegmentForForcedShopperExperience();
 
-// Whether a phone backup/restore state should be simulated.
+// Whether a phone backup/restore state should be simulated due to experimental
+// settings. Uses `tests_hook::SimulatePostDeviceRestore()` to check whether
+// this feature should be enabled for EG tests.
 bool SimulatePostDeviceRestore();
 
 // In production, the history sync opt-in isn't shown if it was declined too
diff --git a/ios/chrome/browser/signin/model/BUILD.gn b/ios/chrome/browser/signin/model/BUILD.gn
index 0b517e71..578e944 100644
--- a/ios/chrome/browser/signin/model/BUILD.gn
+++ b/ios/chrome/browser/signin/model/BUILD.gn
@@ -141,6 +141,7 @@
     "//components/sync/base",
     "//components/sync/service",
     "//google_apis",
+    "//ios/chrome/app:tests_hook",
     "//ios/chrome/browser/authentication/ui_bundled/signin:signin_headers",
     "//ios/chrome/browser/bookmarks/model:model_utils",
     "//ios/chrome/browser/crash_report/model",
@@ -192,10 +193,12 @@
     "//base",
     "//components/prefs",
     "//components/signin/public/identity_manager",
+    "//ios/chrome/app:tests_hook",
     "//ios/chrome/browser/shared/model/application_context",
     "//ios/chrome/browser/shared/model/prefs:pref_names",
     "//ios/chrome/browser/shared/public/features:system_flags",
     "//ios/public/provider/chrome/browser/signin:signin_error_api",
+    "//ios/public/provider/chrome/browser/signin:signin_identity_api",
   ]
 }
 
diff --git a/ios/chrome/browser/signin/model/authentication_service.mm b/ios/chrome/browser/signin/model/authentication_service.mm
index 0dbab83..15209aa 100644
--- a/ios/chrome/browser/signin/model/authentication_service.mm
+++ b/ios/chrome/browser/signin/model/authentication_service.mm
@@ -710,12 +710,12 @@
     return;
   }
 
-  // YES if the primary identity should be ignore to simulate a backup/restore
+  // YES if the primary identity should be ignored to simulate a backup/restore
   // of the device.
   bool simulate_identity_lost_for_restore =
-      device_restore && experimental_flags::SimulatePostDeviceRestore();
-  // If the restore shorty is needs to be simulated, the primary identity should
-  // not found.
+      device_restore && SimulatePostDeviceRestore();
+  // If the restore shorty needs to be simulated, the primary identity should
+  // not be found.
   id<SystemIdentity> authenticated_identity =
       simulate_identity_lost_for_restore
           ? nil
diff --git a/ios/chrome/browser/signin/model/signin_util.h b/ios/chrome/browser/signin/model/signin_util.h
index ef8ab3fd4..934db42 100644
--- a/ios/chrome/browser/signin/model/signin_util.h
+++ b/ios/chrome/browser/signin/model/signin_util.h
@@ -41,8 +41,8 @@
 // The value is cached. The result is cached for later calls.
 signin::Tribool IsFirstSessionAfterDeviceRestore();
 
-// Stores a user's account info and if history sync was enabled or not, when we
-// detect that it was forgotten during a device restore.
+// Stores a user's account info and whether history sync was enabled or not,
+// when we detect that it was forgotten during a device restore.
 void StorePreRestoreIdentity(PrefService* profile_pref,
                              AccountInfo account,
                              bool history_sync_enabled);
@@ -65,4 +65,8 @@
 // can be cached for later usage.
 void RunSystemCapabilitiesPrefetch(NSArray<id<SystemIdentity>>* identities);
 
+// Whether a phone backup/restore state should be simulated.
+// This can be triggered either by EG test flag or by Experimental settings.
+bool SimulatePostDeviceRestore();
+
 #endif  // IOS_CHROME_BROWSER_SIGNIN_MODEL_SIGNIN_UTIL_H_
diff --git a/ios/chrome/browser/signin/model/signin_util.mm b/ios/chrome/browser/signin/model/signin_util.mm
index e16753ab..d152905 100644
--- a/ios/chrome/browser/signin/model/signin_util.mm
+++ b/ios/chrome/browser/signin/model/signin_util.mm
@@ -15,6 +15,7 @@
 #import "google_apis/gaia/core_account_id.h"
 #import "google_apis/gaia/gaia_auth_util.h"
 #import "google_apis/gaia/gaia_id.h"
+#import "ios/chrome/app/tests_hook.h"
 #import "ios/chrome/browser/shared/model/application_context/application_context.h"
 #import "ios/chrome/browser/shared/model/prefs/pref_names.h"
 #import "ios/chrome/browser/shared/public/features/system_flags.h"
@@ -22,6 +23,7 @@
 #import "ios/chrome/browser/signin/model/system_identity.h"
 #import "ios/chrome/browser/signin/model/system_identity_manager.h"
 #import "ios/public/provider/chrome/browser/signin/signin_error_api.h"
+#import "ios/public/provider/chrome/browser/signin/signin_identity_api.h"
 
 namespace {
 
@@ -97,7 +99,7 @@
 }
 
 signin::Tribool IsFirstSessionAfterDeviceRestore() {
-  if (experimental_flags::SimulatePostDeviceRestore()) {
+  if (SimulatePostDeviceRestore()) {
     return signin::Tribool::kTrue;
   }
   static signin::Tribool is_first_session_after_device_restore =
@@ -161,3 +163,10 @@
         }));
   }
 }
+
+bool SimulatePostDeviceRestore() {
+  // We simulate post device restore if required either by experimental settings
+  // or test flag.
+  return tests_hook::SimulatePostDeviceRestore() ||
+         experimental_flags::SimulatePostDeviceRestore();
+}
diff --git a/ios/chrome/test/earl_grey/eg_tests_hook.mm b/ios/chrome/test/earl_grey/eg_tests_hook.mm
index c9599b1..62e3af01 100644
--- a/ios/chrome/test/earl_grey/eg_tests_hook.mm
+++ b/ios/chrome/test/earl_grey/eg_tests_hook.mm
@@ -43,6 +43,7 @@
 #import "ios/chrome/browser/signin/model/fake_system_identity.h"
 #import "ios/chrome/browser/signin/model/fake_system_identity_manager.h"
 #import "ios/chrome/browser/signin/model/identity_manager_factory.h"
+#import "ios/chrome/browser/signin/model/signin_util.h"
 #import "ios/chrome/browser/sync/model/data_type_store_service_factory.h"
 #import "ios/chrome/browser/sync/model/device_info_sync_service_factory.h"
 #import "ios/chrome/test/app/chrome_test_util.h"
@@ -137,6 +138,11 @@
   return GetTestPlatformPolicyProvider();
 }
 
+bool SimulatePostDeviceRestore() {
+  return base::CommandLine::ForCurrentProcess()->HasSwitch(
+      test_switches::kSimulatePostDeviceRestore);
+}
+
 std::unique_ptr<SystemIdentityManager> CreateSystemIdentityManager() {
   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
 
diff --git a/ios/chrome/test/earl_grey/test_switches.h b/ios/chrome/test/earl_grey/test_switches.h
index 4a6979f..dc859c133 100644
--- a/ios/chrome/test/earl_grey/test_switches.h
+++ b/ios/chrome/test/earl_grey/test_switches.h
@@ -25,6 +25,9 @@
 // Ignored if kForceRealSystemIdentityManager is used.
 extern const char kSignInAtStartup[];
 
+// Switch used to simulate a post device restore in EG tests.
+extern const char kSimulatePostDeviceRestore[];
+
 // Switch used to enable FakeTabGroupSyncService for testing. The feature
 // kTabGroupSync should be enabled as well.
 extern const char kEnableFakeTabGroupSyncService[];
diff --git a/ios/chrome/test/earl_grey/test_switches.mm b/ios/chrome/test/earl_grey/test_switches.mm
index 84bd6101..ee4e2c3 100644
--- a/ios/chrome/test/earl_grey/test_switches.mm
+++ b/ios/chrome/test/earl_grey/test_switches.mm
@@ -16,6 +16,9 @@
 // Sign in automatically at startup.
 const char kSignInAtStartup[] = "sign-in-at-startup";
 
+// Simulate post device restore.
+const char kSimulatePostDeviceRestore[] = "simulate-post-device-restore";
+
 // Enables FakeTabGroupSyncService.
 const char kEnableFakeTabGroupSyncService[] =
     "enable-fake-tab-group-sync-service";
diff --git a/ios/chrome/test/earl_grey2/BUILD.gn b/ios/chrome/test/earl_grey2/BUILD.gn
index c65f265..64868791 100644
--- a/ios/chrome/test/earl_grey2/BUILD.gn
+++ b/ios/chrome/test/earl_grey2/BUILD.gn
@@ -176,6 +176,7 @@
     "//ios/chrome/browser/authentication/ui_bundled/signin/forced_signin:eg2_tests",
     "//ios/chrome/browser/authentication/ui_bundled/signin/two_screens_signin:eg2_tests",
     "//ios/chrome/browser/authentication/ui_bundled/signout_action_sheet:eg2_tests",
+    "//ios/chrome/browser/post_restore_signin/ui_bundled:eg2_tests",
     "//ios/chrome/browser/signin/model:eg2_tests",
   ]
   data_deps = [ ":ios_chrome_eg2tests" ]
diff --git a/ios/chrome/test/wpt/cwt_tests_hook.mm b/ios/chrome/test/wpt/cwt_tests_hook.mm
index 93b3a21..7d0f2e1 100644
--- a/ios/chrome/test/wpt/cwt_tests_hook.mm
+++ b/ios/chrome/test/wpt/cwt_tests_hook.mm
@@ -54,6 +54,9 @@
 policy::ConfigurationPolicyProvider* GetOverriddenPlatformPolicyProvider() {
   return nullptr;
 }
+bool SimulatePostDeviceRestore() {
+  return false;
+}
 std::unique_ptr<SystemIdentityManager> CreateSystemIdentityManager() {
   return nullptr;
 }
diff --git a/ios/chrome/test/xcuitest/xcuitests_hook.mm b/ios/chrome/test/xcuitest/xcuitests_hook.mm
index 08f1d719..936da87b 100644
--- a/ios/chrome/test/xcuitest/xcuitests_hook.mm
+++ b/ios/chrome/test/xcuitest/xcuitests_hook.mm
@@ -63,6 +63,10 @@
   return nullptr;
 }
 
+bool SimulatePostDeviceRestore() {
+  return false;
+}
+
 std::unique_ptr<SystemIdentityManager> CreateSystemIdentityManager() {
   return nullptr;
 }