[iOS][Signin]Add utility method for histogram

EG test that deals with a sign-in flow should check that the sign-in is
offered, started, and potentially completed. It should also check that
histograms for this access points are not emitted if we don’t expect
them.

This extra object allows to check efficiently all sign-in histogram
for a specific access point.

I should note that the first usage I added here are only covering the
case where the Add Account is used. I added TODO when histograms are
missing. I must also note that it seems that resignin is tested
neither with unit test nor EG test currently.

Bug: 41493423
Change-Id: I9a809bd6c7527a172f86d2f4c01dab01fa276f25
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6157963
Reviewed-by: David Roger <droger@chromium.org>
Reviewed-by: Jérôme Lebel <jlebel@chromium.org>
Commit-Queue: Arthur Milchior <arthurmilchior@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1405990}
NOKEYCHECK=True
GitOrigin-RevId: fa7bb9a8fcf6e3b59cad82459070607eda116e7c
diff --git a/chrome/browser/authentication/ui_bundled/BUILD.gn b/chrome/browser/authentication/ui_bundled/BUILD.gn
index f0e2626..7579eb6 100644
--- a/chrome/browser/authentication/ui_bundled/BUILD.gn
+++ b/chrome/browser/authentication/ui_bundled/BUILD.gn
@@ -223,6 +223,8 @@
   configs += [ "//build/config/ios:xctest_config" ]
   testonly = true
   sources = [
+    "expected_signin_histograms.h",
+    "expected_signin_histograms.mm",
     "signin_earl_grey.h",
     "signin_earl_grey.mm",
     "signin_earl_grey_app_interface.h",
@@ -244,6 +246,7 @@
     "//ios/chrome/browser/authentication/ui_bundled/signin:constants",
     "//ios/chrome/browser/authentication/ui_bundled/views:views_constants",
     "//ios/chrome/browser/first_run/ui_bundled:constants",
+    "//ios/chrome/browser/metrics/model:eg_test_support+eg2",
     "//ios/chrome/browser/recent_tabs/ui_bundled:ui_constants",
     "//ios/chrome/browser/settings/ui_bundled:constants",
     "//ios/chrome/browser/settings/ui_bundled/google_services:constants",
diff --git a/chrome/browser/authentication/ui_bundled/DEPS b/chrome/browser/authentication/ui_bundled/DEPS
index edc8596..85b8389 100644
--- a/chrome/browser/authentication/ui_bundled/DEPS
+++ b/chrome/browser/authentication/ui_bundled/DEPS
@@ -26,6 +26,9 @@
   "signin_earl_grey_app_interface\.mm": [
     "+ios/chrome/browser/authentication/ui_bundled/signin_earl_grey_app_interface.h",
   ],
+  "signin_earl_grey\.mm": [
+  "+ios/chrome/browser/metrics/model/metrics_app_interface.h",
+  ],
   ".*_egtest\.mm": [
     "+components/signin/internal/identity_manager/account_capabilities_constants.h",
   ],
diff --git a/chrome/browser/authentication/ui_bundled/account_menu/BUILD.gn b/chrome/browser/authentication/ui_bundled/account_menu/BUILD.gn
index 0027cb2..e74c6e5 100644
--- a/chrome/browser/authentication/ui_bundled/account_menu/BUILD.gn
+++ b/chrome/browser/authentication/ui_bundled/account_menu/BUILD.gn
@@ -163,6 +163,7 @@
     "//ios/chrome/app/strings:ios_strings",
     "//ios/chrome/browser/authentication/ui_bundled:eg_test_support+eg2",
     "//ios/chrome/browser/bookmarks/ui_bundled:eg_test_support+eg2",
+    "//ios/chrome/browser/metrics/model:eg_test_support+eg2",
     "//ios/chrome/browser/ntp/ui_bundled:constants",
     "//ios/chrome/browser/ntp/ui_bundled:feature_flags",
     "//ios/chrome/browser/settings/ui_bundled/google_services:constants",
diff --git a/chrome/browser/authentication/ui_bundled/account_menu/account_menu_egtest.mm b/chrome/browser/authentication/ui_bundled/account_menu/account_menu_egtest.mm
index fb34166..e7e39cc 100644
--- a/chrome/browser/authentication/ui_bundled/account_menu/account_menu_egtest.mm
+++ b/chrome/browser/authentication/ui_bundled/account_menu/account_menu_egtest.mm
@@ -10,6 +10,7 @@
 #import "ios/chrome/browser/authentication/ui_bundled/signin_earl_grey.h"
 #import "ios/chrome/browser/authentication/ui_bundled/signin_earl_grey_ui_test_util.h"
 #import "ios/chrome/browser/bookmarks/ui_bundled/bookmark_earl_grey.h"
+#import "ios/chrome/browser/metrics/model/metrics_app_interface.h"
 #import "ios/chrome/browser/ntp/ui_bundled/new_tab_page_constants.h"
 #import "ios/chrome/browser/ntp/ui_bundled/new_tab_page_feature.h"
 #import "ios/chrome/browser/settings/ui_bundled/google_services/google_services_settings_constants.h"
@@ -328,6 +329,9 @@
   // The tear down needs to remove other view controllers, and it cannot be done
   // during the animation of the SSO view controler.
   [ChromeEarlGreyUI waitForAppToIdle];
+
+  // TODO(crbug.com/41493423): Check whether the Add Account or Account Menu
+  // should be logged as Signin started histogram.
 }
 
 // Tests the enter passphrase button.
diff --git a/chrome/browser/authentication/ui_bundled/expected_signin_histograms.h b/chrome/browser/authentication/ui_bundled/expected_signin_histograms.h
new file mode 100644
index 0000000..6282a17
--- /dev/null
+++ b/chrome/browser/authentication/ui_bundled/expected_signin_histograms.h
@@ -0,0 +1,56 @@
+// 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.
+
+#ifndef IOS_CHROME_BROWSER_AUTHENTICATION_UI_BUNDLED_EXPECTED_SIGNIN_HISTOGRAMS_H_
+#define IOS_CHROME_BROWSER_AUTHENTICATION_UI_BUNDLED_EXPECTED_SIGNIN_HISTOGRAMS_H_
+
+#import <Foundation/Foundation.h>
+
+namespace signin_metrics {
+enum class AccessPoint : int;
+}  // namespace signin_metrics
+
+// A data container for the expected signin histograms related to a specific
+// access point.
+@interface ExpectedSigninHistograms : NSObject
+
+@property(nonatomic, readonly) signin_metrics::AccessPoint accessPoint;
+
+// For each property p below, its value is the number of time we expect the
+// histogram p to be emitted. The string p is obtained from the histogram name
+// by lowering the first case and removing dots.
+
+@property(nonatomic, assign) int signinSignInOffered;
+@property(nonatomic, assign) int signinSignInOfferedWithdefault;
+@property(nonatomic, assign) int signinSignInOfferedNewAccountNoExistingAccount;
+
+@property(nonatomic, assign) int signinSigninStartedAccessPoint;
+@property(nonatomic, assign) int signinSigninStartedAccessPointWithDefault;
+@property(nonatomic, assign) int signinSigninStartedAccessPointNotDefault;
+@property(nonatomic, assign)
+    int signinSignStartedAccessPointNewAccountNoExistingAccount;
+@property(nonatomic, assign)
+    int signinSignStartedAccessPointNewAccountExistingAccount;
+
+@property(nonatomic, assign) int signinSigninCompletedAccessPoint;
+@property(nonatomic, assign) int signinSigninCompletedAccessPointWithDefault;
+@property(nonatomic, assign) int signinSigninCompletedAccessPointNotDefault;
+@property(nonatomic, assign)
+    int signinSigninCompletedAccessPointNewAccountNoExistingAccount;
+@property(nonatomic, assign)
+    int signinSigninCompletedAccessPointNewAccountExistingAccount;
+
+@property(nonatomic, assign) int signinSignInStarted;
+@property(nonatomic, assign) int signinSyncOptInStarted;
+@property(nonatomic, assign) int signinSyncOptInOpenedSyncSettings;
+
+- (instancetype)init NS_UNAVAILABLE;
+
+// This object will consider histogram emitted for `accessPoint`.
+- (instancetype)initWithAccessPoint:(signin_metrics::AccessPoint)accessPoint
+    NS_DESIGNATED_INITIALIZER;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_AUTHENTICATION_UI_BUNDLED_EXPECTED_SIGNIN_HISTOGRAMS_H_
diff --git a/chrome/browser/authentication/ui_bundled/expected_signin_histograms.mm b/chrome/browser/authentication/ui_bundled/expected_signin_histograms.mm
new file mode 100644
index 0000000..b0e706e
--- /dev/null
+++ b/chrome/browser/authentication/ui_bundled/expected_signin_histograms.mm
@@ -0,0 +1,17 @@
+// 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 "ios/chrome/browser/authentication/ui_bundled/expected_signin_histograms.h"
+
+@implementation ExpectedSigninHistograms
+
+- (instancetype)initWithAccessPoint:(signin_metrics::AccessPoint)accessPoint {
+  self = [super init];
+  if (self) {
+    _accessPoint = accessPoint;
+  }
+  return self;
+}
+
+@end
diff --git a/chrome/browser/authentication/ui_bundled/signin/forced_signin/BUILD.gn b/chrome/browser/authentication/ui_bundled/signin/forced_signin/BUILD.gn
index 0212671..1893d71 100644
--- a/chrome/browser/authentication/ui_bundled/signin/forced_signin/BUILD.gn
+++ b/chrome/browser/authentication/ui_bundled/signin/forced_signin/BUILD.gn
@@ -34,6 +34,7 @@
     "//components/policy:policy_code_generate",
     "//components/policy/core/common:common_constants",
     "//components/signin/ios/browser:features",
+    "//components/signin/public/base",
     "//components/sync/base:features",
     "//ios/chrome/app/strings",
     "//ios/chrome/browser/authentication/ui_bundled:eg_test_support+eg2",
@@ -42,6 +43,7 @@
     "//ios/chrome/browser/authentication/ui_bundled/views:views_constants",
     "//ios/chrome/browser/first_run/ui_bundled:constants",
     "//ios/chrome/browser/first_run/ui_bundled:eg_test_support+eg2",
+    "//ios/chrome/browser/metrics/model:eg_test_support+eg2",
     "//ios/chrome/browser/ntp/ui_bundled:constants",
     "//ios/chrome/browser/ntp/ui_bundled:feature_flags",
     "//ios/chrome/browser/policy/model:eg_test_support+eg2",
diff --git a/chrome/browser/authentication/ui_bundled/signin/forced_signin/forced_signin_egtest.mm b/chrome/browser/authentication/ui_bundled/signin/forced_signin/forced_signin_egtest.mm
index 9008ed0..487a4d7 100644
--- a/chrome/browser/authentication/ui_bundled/signin/forced_signin/forced_signin_egtest.mm
+++ b/chrome/browser/authentication/ui_bundled/signin/forced_signin/forced_signin_egtest.mm
@@ -11,13 +11,16 @@
 #import "components/policy/core/common/policy_loader_ios_constants.h"
 #import "components/policy/policy_constants.h"
 #import "components/signin/ios/browser/features.h"
+#import "components/signin/public/base/signin_metrics.h"
 #import "ios/chrome/browser/authentication/ui_bundled/account_menu/account_menu_constants.h"
+#import "ios/chrome/browser/authentication/ui_bundled/expected_signin_histograms.h"
 #import "ios/chrome/browser/authentication/ui_bundled/signin/signin_constants.h"
 #import "ios/chrome/browser/authentication/ui_bundled/signin_earl_grey.h"
 #import "ios/chrome/browser/authentication/ui_bundled/signin_earl_grey_ui_test_util.h"
 #import "ios/chrome/browser/authentication/ui_bundled/signin_matchers.h"
 #import "ios/chrome/browser/authentication/ui_bundled/views/views_constants.h"
 #import "ios/chrome/browser/first_run/ui_bundled/first_run_constants.h"
+#import "ios/chrome/browser/metrics/model/metrics_app_interface.h"
 #import "ios/chrome/browser/ntp/ui_bundled/new_tab_page_constants.h"
 #import "ios/chrome/browser/ntp/ui_bundled/new_tab_page_feature.h"
 #import "ios/chrome/browser/policy/model/policy_earl_grey_utils.h"
@@ -327,6 +330,8 @@
 // Tests the sign-in screen without accounts where an account has to be added
 // before signing in.
 - (void)testSignInScreenWithoutAccount {
+  chrome_test_util::GREYAssertErrorNil(
+      [MetricsAppInterface setupHistogramTester]);
   // Tap on the "Sign in" button.
   [[EarlGrey
       selectElementWithMatcher:grey_text(l10n_util::GetNSString(
@@ -365,6 +370,12 @@
       selectElementWithMatcher:grey_text(l10n_util::GetNSString(
                                    IDS_IOS_FIRST_RUN_SIGNIN_DONT_SIGN_IN))]
       assertWithMatcher:grey_nil()];
+  ExpectedSigninHistograms* expecteds = [[ExpectedSigninHistograms alloc]
+      initWithAccessPoint:signin_metrics::AccessPoint::
+                              ACCESS_POINT_FORCED_SIGNIN];
+  // TODO(crbug.com/41493423): We should log Signin is started. Maybe also that
+  // it’s offered.
+  [SigninEarlGrey assertExpectedSigninHistograms:expecteds];
 }
 
 // Tests that accounts can be switched and that there is the button add a new
diff --git a/chrome/browser/authentication/ui_bundled/signin/signin_coordinator_egtest.mm b/chrome/browser/authentication/ui_bundled/signin/signin_coordinator_egtest.mm
index 1c840d5..bc19a57 100644
--- a/chrome/browser/authentication/ui_bundled/signin/signin_coordinator_egtest.mm
+++ b/chrome/browser/authentication/ui_bundled/signin/signin_coordinator_egtest.mm
@@ -13,6 +13,7 @@
 #import "components/signin/public/base/signin_switches.h"
 #import "components/strings/grit/components_strings.h"
 #import "components/sync/base/user_selectable_type.h"
+#import "ios/chrome/browser/authentication/ui_bundled/expected_signin_histograms.h"
 #import "ios/chrome/browser/authentication/ui_bundled/signin/signin_constants.h"
 #import "ios/chrome/browser/authentication/ui_bundled/signin_earl_grey.h"
 #import "ios/chrome/browser/authentication/ui_bundled/signin_earl_grey_ui_test_util.h"
@@ -542,6 +543,13 @@
 
   [self assertFakeSSOScreenIsVisible];
   [ChromeEarlGreyUI waitForAppToIdle];
+
+  ExpectedSigninHistograms* expecteds = [[ExpectedSigninHistograms alloc]
+      initWithAccessPoint:signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS];
+  // TODO(crbug.com/41493423): We should log Signin offered and
+  // Signin.SigninStartedAccessPoint.
+  expecteds.signinSignInStarted = 1;
+  [SigninEarlGrey assertExpectedSigninHistograms:expecteds];
 }
 
 // Tests that an add account operation triggered from the web is handled.
@@ -550,6 +558,12 @@
   [ChromeEarlGrey simulateAddAccountFromWeb];
 
   [self assertFakeSSOScreenIsVisible];
+
+  // TODO(crbug.com/41493423): We should log signin started. Ideally that signin
+  // was offered, but this is probably not possible on the web.
+  ExpectedSigninHistograms* expecteds = [[ExpectedSigninHistograms alloc]
+      initWithAccessPoint:signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN];
+  [SigninEarlGrey assertExpectedSigninHistograms:expecteds];
 }
 
 // Tests to remove the last identity in the identity chooser.
@@ -726,7 +740,7 @@
       assertWithMatcher:grey_sufficientlyVisible()];
 }
 
-// Tests that a signed-in user can open "Settings" screen from the NTP.
+// Tests that a signed-in user can open "Add Account" screen from the NTP.
 - (void)testOpenManageAddAccountFromNTPWhenSyncDisabledByPolicy {
   // Disable sync by policy.
   policy_test_utils::SetPolicy(true, policy::key::kSyncDisabled);
@@ -899,6 +913,12 @@
   [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
                                           kFakeAuthActivityViewIdentifier)]
       assertWithMatcher:grey_sufficientlyVisible()];
+
+  ExpectedSigninHistograms* expecteds = [[ExpectedSigninHistograms alloc]
+      initWithAccessPoint:signin_metrics::AccessPoint::
+                              ACCESS_POINT_NTP_SIGNED_OUT_ICON];
+  expecteds.signinSignInStarted = 1;
+  [SigninEarlGrey assertExpectedSigninHistograms:expecteds];
 }
 
 // Tests that a signed-out user with the SyncDisabled policy can still open the
diff --git a/chrome/browser/authentication/ui_bundled/signin_earl_grey.h b/chrome/browser/authentication/ui_bundled/signin_earl_grey.h
index 2f29da1..18aaafc 100644
--- a/chrome/browser/authentication/ui_bundled/signin_earl_grey.h
+++ b/chrome/browser/authentication/ui_bundled/signin_earl_grey.h
@@ -10,6 +10,8 @@
 #import "components/sync/base/user_selectable_type.h"
 #import "ios/testing/earl_grey/base_eg_test_helper_impl.h"
 
+@class ExpectedSigninHistograms;
+
 @protocol GREYMatcher;
 @class FakeSystemIdentity;
 
@@ -17,6 +19,10 @@
 enum class ConsentLevel;
 }
 
+namespace signin_metrics {
+enum class AccessPoint : int;
+}  // namespace signin_metrics
+
 class GURL;
 
 #define SigninEarlGrey \
@@ -126,6 +132,10 @@
 // Returns if the data type is enabled for the sync service.
 - (BOOL)isSelectedTypeEnabled:(syncer::UserSelectableType)type;
 
+// Checks that fore each histogram listed above as properties, it’s emitted the
+// number of time indicated in the property for `accessPoint`.
+- (void)assertExpectedSigninHistograms:(ExpectedSigninHistograms*)expecteds;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_AUTHENTICATION_UI_BUNDLED_SIGNIN_EARL_GREY_H_
diff --git a/chrome/browser/authentication/ui_bundled/signin_earl_grey.mm b/chrome/browser/authentication/ui_bundled/signin_earl_grey.mm
index 2806fc4..061f503 100644
--- a/chrome/browser/authentication/ui_bundled/signin_earl_grey.mm
+++ b/chrome/browser/authentication/ui_bundled/signin_earl_grey.mm
@@ -6,10 +6,14 @@
 
 #import "base/test/ios/wait_util.h"
 #import "components/signin/public/base/consent_level.h"
+#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_app_interface.h"
+#import "ios/chrome/browser/metrics/model/metrics_app_interface.h"
 #import "ios/chrome/browser/settings/ui_bundled/settings_table_view_controller_constants.h"
 #import "ios/chrome/browser/signin/model/fake_system_identity.h"
 #import "ios/chrome/grit/ios_strings.h"
+#import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
 #import "ios/testing/earl_grey/earl_grey_test.h"
 #import "net/base/apple/url_conversions.h"
 #import "ui/base/l10n/l10n_util_mac.h"
@@ -153,9 +157,9 @@
 }
 
 - (void)verifySignedOut {
-  // Required to avoid any problem since the following test is not dependant to
-  // UI, and the previous action has to be totally finished before going through
-  // the assert.
+  // Required to avoid any problem since the following test is not dependant
+  // to UI, and the previous action has to be totally finished before going
+  // through the assert.
   GREYWaitForAppToIdle(@"App failed to idle");
 
   ConditionBlock condition = ^bool {
@@ -201,4 +205,51 @@
   return [SigninEarlGreyAppInterface isSelectedTypeEnabled:type];
 }
 
+- (void)assertExpectedSigninHistograms:(ExpectedSigninHistograms*)expecteds {
+  std::vector<std::pair<NSString*, int>> array = {
+      {@"Signin.SignIn.Offered", expecteds.signinSignInOffered},
+      {@"Signin.SignIn.Offered.WithDefault",
+       expecteds.signinSignInOfferedWithdefault},
+      {@"Signin.SignIn.Offered.NewAccountNoExistingAccount",
+       expecteds.signinSignInOfferedNewAccountNoExistingAccount},
+
+      {@"Signin.SigninStartedAccessPoint",
+       expecteds.signinSigninStartedAccessPoint},
+      {@"Signin.SigninStartedAccessPoint.WithDefault",
+       expecteds.signinSigninStartedAccessPointWithDefault},
+      {@"Signin.SigninStartedAccessPoint.NotDefault",
+       expecteds.signinSigninStartedAccessPointNotDefault},
+      {@"Signin.SigninStartedAccessPoint.NewAccountNoExistingAccount",
+       expecteds.signinSignStartedAccessPointNewAccountNoExistingAccount},
+      {@"Signin.SigninStartedAccessPoint.NewAccountExistingAccount",
+       expecteds.signinSignStartedAccessPointNewAccountExistingAccount},
+
+      {@"Signin.SigninCompletedAccessPoint",
+       expecteds.signinSigninCompletedAccessPoint},
+      {@"Signin.SigninCompletedAccessPoint.WithDefault",
+       expecteds.signinSigninCompletedAccessPointWithDefault},
+      {@"Signin.SigninCompletedAccessPoint.NotDefault",
+       expecteds.signinSigninCompletedAccessPointNotDefault},
+      {@"Signin.SigninCompletedAccessPoint.NewAccountNoExistingAccount",
+       expecteds.signinSigninCompletedAccessPointNewAccountNoExistingAccount},
+      {@"Signin.SigninCompletedAccessPoint.NewAccountExistingAccount",
+       expecteds.signinSigninCompletedAccessPointNewAccountExistingAccount},
+
+      {@"Signin.SignIn.Started", expecteds.signinSignInStarted},
+      {@"Signin.SyncOptIn.Started", expecteds.signinSyncOptInStarted},
+      {@"Signin.SyncOptIn.OpenedSyncSettings",
+       expecteds.signinSyncOptInOpenedSyncSettings},
+  };
+  signin_metrics::AccessPoint accessPoint = expecteds.accessPoint;
+  for (const std::pair<NSString*, int>& expected : array) {
+    NSString* histogram = expected.first;
+    int count = expected.second;
+    NSError* error =
+        [MetricsAppInterface expectCount:count
+                               forBucket:static_cast<int>(accessPoint)
+                            forHistogram:histogram];
+    chrome_test_util::GREYAssertErrorNil(error);
+  }
+}
+
 @end
diff --git a/chrome/browser/authentication/ui_bundled/signout_action_sheet/BUILD.gn b/chrome/browser/authentication/ui_bundled/signout_action_sheet/BUILD.gn
index 97a42d1..d00cbb9 100644
--- a/chrome/browser/authentication/ui_bundled/signout_action_sheet/BUILD.gn
+++ b/chrome/browser/authentication/ui_bundled/signout_action_sheet/BUILD.gn
@@ -80,6 +80,7 @@
     "//base/test:test_support",
     "//build:branding_buildflags",
     "//components/policy/core/common:common_constants",
+    "//components/signin/public/base",
     "//components/sync/base:features",
     "//ios/chrome/app/strings",
     "//ios/chrome/browser/authentication/ui_bundled:eg_test_support+eg2",
diff --git a/chrome/browser/bookmarks/ui_bundled/home/bookmarks_promo_egtest.mm b/chrome/browser/bookmarks/ui_bundled/home/bookmarks_promo_egtest.mm
index 1d73862..cc56033 100644
--- a/chrome/browser/bookmarks/ui_bundled/home/bookmarks_promo_egtest.mm
+++ b/chrome/browser/bookmarks/ui_bundled/home/bookmarks_promo_egtest.mm
@@ -10,8 +10,10 @@
 #import "components/bookmarks/common/bookmark_features.h"
 #import "components/policy/core/common/policy_loader_ios_constants.h"
 #import "components/policy/policy_constants.h"
+#import "components/signin/public/base/signin_metrics.h"
 #import "components/sync/base/user_selectable_type.h"
 #import "ios/chrome/browser/authentication/ui_bundled/authentication_constants.h"
+#import "ios/chrome/browser/authentication/ui_bundled/expected_signin_histograms.h"
 #import "ios/chrome/browser/authentication/ui_bundled/signin/signin_constants.h"
 #import "ios/chrome/browser/authentication/ui_bundled/signin_earl_grey.h"
 #import "ios/chrome/browser/authentication/ui_bundled/signin_earl_grey_ui_test_util.h"
@@ -20,6 +22,7 @@
 #import "ios/chrome/browser/bookmarks/ui_bundled/bookmark_earl_grey.h"
 #import "ios/chrome/browser/bookmarks/ui_bundled/bookmark_earl_grey_ui.h"
 #import "ios/chrome/browser/bookmarks/ui_bundled/bookmark_ui_constants.h"
+#import "ios/chrome/browser/metrics/model/metrics_app_interface.h"
 #import "ios/chrome/browser/policy/model/policy_app_interface.h"
 #import "ios/chrome/browser/policy/model/policy_earl_grey_utils.h"
 #import "ios/chrome/browser/settings/ui_bundled/google_services/manage_sync_settings_constants.h"
@@ -258,6 +261,8 @@
 // Tests that users with no device-level account see a promo that leads to an
 // SSO Auth flow on tap. Concluding the auth successfully hides the promo.
 - (void)testSigninOnlyPromoWithoutAccount {
+  chrome_test_util::GREYAssertErrorNil(
+      [MetricsAppInterface setupHistogramTester]);
   [BookmarkEarlGrey
       setupStandardBookmarksInStorage:BookmarkStorageType::kLocalOrSyncable];
   [BookmarkEarlGreyUI openBookmarks];
@@ -284,6 +289,14 @@
   // Verify the user got signed in and the promo hidden.
   [SigninEarlGrey verifySignedInWithFakeIdentity:fakeIdentity];
   [SigninEarlGreyUI verifySigninPromoNotVisible];
+
+  // TODO(crbug.com/41493423): There should be log for SigninStartedAccessPoint,
+  // Signin.SignIn.Offered and Signin.SigninCompletedAccessPoint.NotDefault
+  ExpectedSigninHistograms* expecteds = [[ExpectedSigninHistograms alloc]
+      initWithAccessPoint:signin_metrics::AccessPoint::
+                              ACCESS_POINT_BOOKMARK_MANAGER];
+  expecteds.signinSignInStarted = 1;
+  [SigninEarlGrey assertExpectedSigninHistograms:expecteds];
 }
 
 // Tests that the sign-in promo should not be shown after been shown 19 times.
diff --git a/chrome/browser/first_run/ui_bundled/first_run_without_search_engine_choice_egtest.mm b/chrome/browser/first_run/ui_bundled/first_run_without_search_engine_choice_egtest.mm
index 10509a2..3a0a2bd 100644
--- a/chrome/browser/first_run/ui_bundled/first_run_without_search_engine_choice_egtest.mm
+++ b/chrome/browser/first_run/ui_bundled/first_run_without_search_engine_choice_egtest.mm
@@ -14,6 +14,7 @@
 #import "components/strings/grit/components_strings.h"
 #import "components/sync/base/user_selectable_type.h"
 #import "components/unified_consent/pref_names.h"
+#import "ios/chrome/browser/authentication/ui_bundled/expected_signin_histograms.h"
 #import "ios/chrome/browser/authentication/ui_bundled/signin/signin_constants.h"
 #import "ios/chrome/browser/authentication/ui_bundled/signin_earl_grey.h"
 #import "ios/chrome/browser/authentication/ui_bundled/signin_earl_grey_ui_test_util.h"
@@ -989,6 +990,13 @@
       assertWithMatcher:grey_sufficientlyVisible()];
   // Check signed in.
   [SigninEarlGrey verifySignedInWithFakeIdentity:fakeIdentity];
+
+  ExpectedSigninHistograms* expecteds = [[ExpectedSigninHistograms alloc]
+      initWithAccessPoint:signin_metrics::AccessPoint::ACCESS_POINT_START_PAGE];
+  // TODO(crbug.com/41493423): We should log Signin is started. Maybe also that
+  // it’s offered.
+  expecteds.signinSigninCompletedAccessPoint = 1;
+  [SigninEarlGrey assertExpectedSigninHistograms:expecteds];
 }
 
 // Tests if the user skip the Sign-in step, the History Sync Opt-in screen is
diff --git a/chrome/browser/recent_tabs/ui_bundled/BUILD.gn b/chrome/browser/recent_tabs/ui_bundled/BUILD.gn
index ba5c5d7..da7ed85 100644
--- a/chrome/browser/recent_tabs/ui_bundled/BUILD.gn
+++ b/chrome/browser/recent_tabs/ui_bundled/BUILD.gn
@@ -228,6 +228,7 @@
     "//ios/chrome/browser/authentication/ui_bundled/cells:constants",
     "//ios/chrome/browser/authentication/ui_bundled/signin:constants",
     "//ios/chrome/browser/history/ui_bundled:constants",
+    "//ios/chrome/browser/metrics/model:eg_test_support+eg2",
     "//ios/chrome/browser/policy/model:eg_test_support+eg2",
     "//ios/chrome/browser/policy/model:policy_util",
     "//ios/chrome/browser/shared/public/features",
diff --git a/chrome/browser/recent_tabs/ui_bundled/recent_tabs_egtest.mm b/chrome/browser/recent_tabs/ui_bundled/recent_tabs_egtest.mm
index 0531ee1..ff2bfa4 100644
--- a/chrome/browser/recent_tabs/ui_bundled/recent_tabs_egtest.mm
+++ b/chrome/browser/recent_tabs/ui_bundled/recent_tabs_egtest.mm
@@ -10,16 +10,19 @@
 #import "build/branding_buildflags.h"
 #import "components/policy/core/common/policy_loader_ios_constants.h"
 #import "components/policy/policy_constants.h"
+#import "components/signin/public/base/signin_metrics.h"
 #import "components/strings/grit/components_strings.h"
 #import "components/sync/base/user_selectable_type.h"
 #import "components/sync/service/sync_prefs.h"
 #import "components/unified_consent/pref_names.h"
 #import "ios/chrome/browser/authentication/ui_bundled/cells/signin_promo_view_constants.h"
+#import "ios/chrome/browser/authentication/ui_bundled/expected_signin_histograms.h"
 #import "ios/chrome/browser/authentication/ui_bundled/signin/signin_constants.h"
 #import "ios/chrome/browser/authentication/ui_bundled/signin_earl_grey.h"
 #import "ios/chrome/browser/authentication/ui_bundled/signin_earl_grey_ui_test_util.h"
 #import "ios/chrome/browser/authentication/ui_bundled/signin_matchers.h"
 #import "ios/chrome/browser/history/ui_bundled/history_ui_constants.h"
+#import "ios/chrome/browser/metrics/model/metrics_app_interface.h"
 #import "ios/chrome/browser/policy/model/policy_app_interface.h"
 #import "ios/chrome/browser/policy/model/policy_earl_grey_utils.h"
 #import "ios/chrome/browser/policy/model/policy_util.h"
@@ -279,6 +282,8 @@
 // Tests that a promo to sign in is shown to a signed out user without device
 // accounts. Tapping the promo shows the auth activity then the history opt-in.
 - (void)testShowPromoIfSignedOutAndNoAccounts {
+  chrome_test_util::GREYAssertErrorNil(
+      [MetricsAppInterface setupHistogramTester]);
   OpenRecentTabsPanel();
   [[EarlGrey
       selectElementWithMatcher:grey_allOf(RecentTabsTable(),
@@ -305,6 +310,13 @@
       selectElementWithMatcher:grey_accessibilityID(
                                    kHistorySyncViewAccessibilityIdentifier)]
       assertWithMatcher:grey_sufficientlyVisible()];
+  ExpectedSigninHistograms* expecteds = [[ExpectedSigninHistograms alloc]
+      initWithAccessPoint:signin_metrics::AccessPoint::
+                              ACCESS_POINT_RECENT_TABS];
+  // TODO(crbug.com/41493423) Should log Signin.SignIn.Offered, and
+  // Signin.SigninStartedAccessPoint
+  expecteds.signinSignInStarted = 1;
+  [SigninEarlGrey assertExpectedSigninHistograms:expecteds];
 }
 
 // Tests that a promo to sign in is shown to a signed out user who has device
diff --git a/chrome/browser/settings/ui_bundled/BUILD.gn b/chrome/browser/settings/ui_bundled/BUILD.gn
index 9b272ac..00118e8 100644
--- a/chrome/browser/settings/ui_bundled/BUILD.gn
+++ b/chrome/browser/settings/ui_bundled/BUILD.gn
@@ -489,6 +489,7 @@
     "//ios/chrome/browser/authentication/ui_bundled/cells:constants",
     "//ios/chrome/browser/authentication/ui_bundled/history_sync:pref_names",
     "//ios/chrome/browser/authentication/ui_bundled/signin:constants",
+    "//ios/chrome/browser/metrics/model:eg_test_support+eg2",
     "//ios/chrome/browser/policy/model:eg_test_support+eg2",
     "//ios/chrome/browser/policy/model:policy_util",
     "//ios/chrome/browser/search_engine_choice/ui_bundled:earl_grey_ui_test_util",
diff --git a/chrome/browser/settings/ui_bundled/google_services/manage_accounts/BUILD.gn b/chrome/browser/settings/ui_bundled/google_services/manage_accounts/BUILD.gn
index 1960295..71764d8 100644
--- a/chrome/browser/settings/ui_bundled/google_services/manage_accounts/BUILD.gn
+++ b/chrome/browser/settings/ui_bundled/google_services/manage_accounts/BUILD.gn
@@ -148,6 +148,7 @@
     "//ios/chrome/browser/authentication/ui_bundled/views:views_constants",
     "//ios/chrome/browser/bookmarks/model:bookmark_storage_type",
     "//ios/chrome/browser/bookmarks/ui_bundled:eg_test_support+eg2",
+    "//ios/chrome/browser/metrics/model:eg_test_support+eg2",
     "//ios/chrome/browser/ntp/ui_bundled:feature_flags",
     "//ios/chrome/browser/policy/model:constants",
     "//ios/chrome/browser/settings/ui_bundled/google_services:constants",
diff --git a/chrome/browser/settings/ui_bundled/google_services/manage_accounts/manage_accounts_table_egtest.mm b/chrome/browser/settings/ui_bundled/google_services/manage_accounts/manage_accounts_table_egtest.mm
index 5ebedf4..79a5917 100644
--- a/chrome/browser/settings/ui_bundled/google_services/manage_accounts/manage_accounts_table_egtest.mm
+++ b/chrome/browser/settings/ui_bundled/google_services/manage_accounts/manage_accounts_table_egtest.mm
@@ -8,6 +8,7 @@
 #import "ios/chrome/browser/authentication/ui_bundled/signin_earl_grey.h"
 #import "ios/chrome/browser/authentication/ui_bundled/signin_earl_grey_ui_test_util.h"
 #import "ios/chrome/browser/authentication/ui_bundled/signin_matchers.h"
+#import "ios/chrome/browser/metrics/model/metrics_app_interface.h"
 #import "ios/chrome/browser/ntp/ui_bundled/new_tab_page_feature.h"
 #import "ios/chrome/browser/settings/ui_bundled/google_services/manage_accounts/manage_accounts_table_view_controller_constants.h"
 #import "ios/chrome/browser/settings/ui_bundled/google_services/manage_sync_settings_constants.h"
@@ -219,6 +220,8 @@
 
 // Tests add account flow.
 - (void)testAddAccount {
+  chrome_test_util::GREYAssertErrorNil(
+      [MetricsAppInterface setupHistogramTester]);
   FakeSystemIdentity* fakeIdentity = [FakeSystemIdentity fakeIdentity1];
 
   // Sign In identity, then open the Sync Settings.
diff --git a/chrome/browser/settings/ui_bundled/signin_settings_egtest.mm b/chrome/browser/settings/ui_bundled/signin_settings_egtest.mm
index 1cb55cb..313f16d 100644
--- a/chrome/browser/settings/ui_bundled/signin_settings_egtest.mm
+++ b/chrome/browser/settings/ui_bundled/signin_settings_egtest.mm
@@ -3,12 +3,15 @@
 // found in the LICENSE file.
 
 #import "components/policy/policy_constants.h"
+#import "components/signin/public/base/signin_metrics.h"
 #import "components/sync/base/user_selectable_type.h"
+#import "ios/chrome/browser/authentication/ui_bundled/expected_signin_histograms.h"
 #import "ios/chrome/browser/authentication/ui_bundled/history_sync/pref_names.h"
 #import "ios/chrome/browser/authentication/ui_bundled/signin/signin_constants.h"
 #import "ios/chrome/browser/authentication/ui_bundled/signin_earl_grey.h"
 #import "ios/chrome/browser/authentication/ui_bundled/signin_earl_grey_ui_test_util.h"
 #import "ios/chrome/browser/authentication/ui_bundled/signin_matchers.h"
+#import "ios/chrome/browser/metrics/model/metrics_app_interface.h"
 #import "ios/chrome/browser/policy/model/policy_app_interface.h"
 #import "ios/chrome/browser/policy/model/policy_earl_grey_utils.h"
 #import "ios/chrome/browser/policy/model/policy_util.h"
@@ -283,6 +286,8 @@
 // Tests sign-in and accept history sync opt-in from the settings when having
 // no account on the device.
 - (void)testSigninWithNoAccountOnDevice {
+  chrome_test_util::GREYAssertErrorNil(
+      [MetricsAppInterface setupHistogramTester]);
   [ChromeEarlGreyUI openSettingsMenu];
   // Tap on sign-in cell.
   [[EarlGrey selectElementWithMatcher:SettingsSignInRowMatcher()]
@@ -330,12 +335,21 @@
   GREYAssertTrue(
       [SigninEarlGrey isSelectedTypeEnabled:syncer::UserSelectableType::kTabs],
       @"Tabs sync should be enabled.");
+
+  ExpectedSigninHistograms* expecteds = [[ExpectedSigninHistograms alloc]
+      initWithAccessPoint:signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS];
+  // TODO(crbug.com/41493423): We should log that the signin was offered,
+  // completed and Signin.SigninStartedAccessPoint.
+  expecteds.signinSignInStarted = 1;
+  [SigninEarlGrey assertExpectedSigninHistograms:expecteds];
 }
 
 // Tests sign-in and accept history sync opt-in from the settings when having
 // no account on the device. Capabilities are not set to simulate unsuccessful
 // capabilities fetches.
 - (void)testSigninWithNoAccountOnDeviceWithUnknownCapabilities {
+  chrome_test_util::GREYAssertErrorNil(
+      [MetricsAppInterface setupHistogramTester]);
   [ChromeEarlGreyUI openSettingsMenu];
   // Tap on sign-in cell.
   [[EarlGrey selectElementWithMatcher:SettingsSignInRowMatcher()]
@@ -392,6 +406,13 @@
   GREYAssertTrue(
       [SigninEarlGrey isSelectedTypeEnabled:syncer::UserSelectableType::kTabs],
       @"Tabs sync should be enabled.");
+
+  ExpectedSigninHistograms* expecteds = [[ExpectedSigninHistograms alloc]
+      initWithAccessPoint:signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS];
+  // TODO(crbug.com/41493423): We should log that the signin was offered,
+  // completed and Signin.SigninStartedAccessPoint.
+  expecteds.signinSignInStarted = 1;
+  [SigninEarlGrey assertExpectedSigninHistograms:expecteds];
 }
 
 // For a signed out user with device accounts, tests that the sign-in row is
@@ -419,6 +440,8 @@
 // For a signed out user with no device accounts, tests that the sign-in row is
 // shown with the correct strings and opens the auth activity on tap.
 - (void)testSigninRowOpensAuthActivityIfSignedOutAndNoDeviceAccounts {
+  chrome_test_util::GREYAssertErrorNil(
+      [MetricsAppInterface setupHistogramTester]);
   [ChromeEarlGreyUI openSettingsMenu];
 
   [[EarlGrey
@@ -432,6 +455,13 @@
   [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
                                           kFakeAuthActivityViewIdentifier)]
       assertWithMatcher:grey_sufficientlyVisible()];
+
+  ExpectedSigninHistograms* expecteds = [[ExpectedSigninHistograms alloc]
+      initWithAccessPoint:signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS];
+  // TODO(crbug.com/41493423): We should log that the signin was offered,
+  // completed and Signin.SigninStartedAccessPoint.
+  expecteds.signinSignInStarted = 1;
+  [SigninEarlGrey assertExpectedSigninHistograms:expecteds];
 }
 
 // For a signed out user with the SyncDisabled policy, tests that the sign-in