Index: components/autofill/core/browser/autofill_metrics_unittest.cc |
diff --git a/components/autofill/core/browser/autofill_metrics_unittest.cc b/components/autofill/core/browser/autofill_metrics_unittest.cc |
index c9fd25a046a0fc56ec6e47151179f525531f1c81..6a8abe92a884dcd1cba355f336a1695c22648509 100644 |
--- a/components/autofill/core/browser/autofill_metrics_unittest.cc |
+++ b/components/autofill/core/browser/autofill_metrics_unittest.cc |
@@ -7,6 +7,7 @@ |
#include <stddef.h> |
#include <memory> |
+#include <utility> |
#include <vector> |
#include "base/feature_list.h" |
@@ -54,7 +55,8 @@ using base::Bucket; |
using base::TimeTicks; |
using rappor::TestRapporServiceImpl; |
using ::testing::ElementsAre; |
-using ::testing::UnorderedElementsAre; |
+using ::testing::Matcher; |
+using ::testing::Pointwise; |
namespace autofill { |
namespace { |
@@ -264,6 +266,9 @@ class TestAutofillManager : public AutofillManager { |
base::MakeUnique<TestFormStructure>(empty_form); |
form_structure->SetFieldTypes(heuristic_types, server_types); |
form_structures()->push_back(std::move(form_structure)); |
+ |
+ form_interactions_ukm_logger()->set_url(form.origin); |
+ form_interactions_ukm_logger()->set_form_loaded_timestamp(TimeTicks::Now()); |
} |
// Calls AutofillManager::OnWillSubmitForm and waits for it to complete. |
@@ -288,9 +293,9 @@ class TestAutofillManager : public AutofillManager { |
void RunRunLoop() { run_loop_->Run(); } |
void UploadFormDataAsyncCallback(const FormStructure* submitted_form, |
- const base::TimeTicks& load_time, |
- const base::TimeTicks& interaction_time, |
- const base::TimeTicks& submission_time, |
+ const TimeTicks& load_time, |
+ const TimeTicks& interaction_time, |
+ const TimeTicks& submission_time, |
bool observed_submission) override { |
run_loop_->Quit(); |
@@ -317,6 +322,94 @@ const ukm::Entry_Metric* FindMetric( |
return nullptr; |
} |
+MATCHER(CompareMetrics, "") { |
+ const ukm::Entry_Metric& lhs = ::testing::get<0>(arg); |
+ const std::pair<const char*, int64_t>& rhs = ::testing::get<1>(arg); |
+ return lhs.metric_hash() == base::HashMetricName(rhs.first) && |
+ lhs.value() == rhs.second; |
+} |
+ |
+void VerifyDeveloperEngagementUkm( |
+ const FormData& form, |
+ const ukm::TestUkmService* ukm_service, |
+ const std::vector<int64_t>& expected_metric_values) { |
+ const ukm::UkmEntry* entry = ukm_service->GetEntryForEntryName( |
+ internal::kUKMDeveloperEngagementEntryName); |
+ ASSERT_NE(nullptr, entry); |
+ ukm::Entry entry_proto; |
+ entry->PopulateProto(&entry_proto); |
+ |
+ const ukm::UkmSource* source = |
+ ukm_service->GetSourceForSourceId(entry_proto.source_id()); |
+ ASSERT_NE(nullptr, source); |
+ EXPECT_EQ(form.origin, source->url()); |
+ |
+ std::vector<std::pair<const char*, int64_t>> expected_metrics; |
+ for (const auto it : expected_metric_values) |
+ expected_metrics.push_back( |
+ {internal::kUKMDeveloperEngagementMetricName, it}); |
+ |
+ EXPECT_THAT(entry_proto.metrics(), |
+ Pointwise(CompareMetrics(), expected_metrics)); |
+} |
+ |
+void VerifyFormInteractionsUkm( |
+ const FormData& form, |
+ const ukm::TestUkmService* ukm_service, |
+ const std::vector<std::pair<const char*, int64_t>>& expected_events) { |
+ int entry_num = 0; |
+ // Skip |DeveloperEngagement| entries. |
+ ASSERT_GT(ukm_service->entries_count(), static_cast<size_t>(0)); |
+ while (ukm_service->GetEntry(entry_num)->event_hash() == |
+ base::HashMetricName(internal::kUKMDeveloperEngagementEntryName)) |
+ entry_num++; |
+ |
+ for (const auto& it : expected_events) { |
+ const ukm::UkmEntry* entry = ukm_service->GetEntry(entry_num++); |
+ ASSERT_NE(nullptr, entry); |
+ ukm::Entry entry_proto; |
+ entry->PopulateProto(&entry_proto); |
+ |
+ const ukm::UkmSource* source = |
+ ukm_service->GetSourceForSourceId(entry_proto.source_id()); |
+ ASSERT_NE(nullptr, source); |
+ EXPECT_EQ(form.origin, source->url()); |
+ |
+ ASSERT_EQ(2, entry_proto.metrics().size()); |
+ EXPECT_EQ(base::HashMetricName(it.first), |
+ entry_proto.metrics().Get(0).metric_hash()); |
+ EXPECT_EQ(it.second, entry_proto.metrics().Get(0).value()); |
+ |
+ EXPECT_EQ(base::HashMetricName( |
+ internal::kUKMMillisecondsSinceFormLoadedMetricName), |
+ entry_proto.metrics().Get(1).metric_hash()); |
+ } |
+} |
+ |
+void VerifyUniqueFormInteractionEventUkm(const FormData& form, |
+ const ukm::TestUkmService* ukm_service, |
+ const char* event_name, |
+ int expected_metric_value) { |
+ const ukm::UkmEntry* entry = ukm_service->GetEntryForEntryName(event_name); |
+ ASSERT_NE(nullptr, entry); |
+ ukm::Entry entry_proto; |
+ entry->PopulateProto(&entry_proto); |
+ |
+ const ukm::UkmSource* source = |
+ ukm_service->GetSourceForSourceId(entry_proto.source_id()); |
+ ASSERT_NE(nullptr, source); |
+ EXPECT_EQ(form.origin, source->url()); |
+ |
+ ASSERT_EQ(2, entry_proto.metrics().size()); |
+ EXPECT_EQ(base::HashMetricName(event_name), |
+ entry_proto.metrics().Get(0).metric_hash()); |
+ EXPECT_EQ(expected_metric_value, entry_proto.metrics().Get(0).value()); |
+ |
+ EXPECT_EQ( |
+ base::HashMetricName(internal::kUKMMillisecondsSinceFormLoadedMetricName), |
+ entry_proto.metrics().Get(1).metric_hash()); |
+} |
+ |
} // namespace |
// This is defined in the autofill_metrics.cc implementation file. |
@@ -394,6 +487,7 @@ void AutofillMetricsTest::TearDown() { |
account_tracker_.reset(); |
signin_client_.reset(); |
test::ReenableSystemServices(); |
+ autofill_client_.GetTestUkmService()->Purge(); |
} |
void AutofillMetricsTest::EnableWalletSync() { |
@@ -571,7 +665,7 @@ TEST_F(AutofillMetricsTest, TimingMetrics) { |
// Simulate a OnFormsSeen() call that should trigger the recording. |
std::vector<FormData> forms; |
forms.push_back(form); |
- autofill_manager_->OnFormsSeen(forms, base::TimeTicks::Now()); |
+ autofill_manager_->OnFormsSeen(forms, TimeTicks::Now()); |
// Because these metrics are related to timing, it is not possible to know in |
// advance which bucket the sample will fall into, so we just need to make |
@@ -1381,6 +1475,11 @@ TEST_F(AutofillMetricsTest, NumberOfEditedAutofilledFields) { |
// fields is logged. |
histogram_tester.ExpectUniqueSample( |
"Autofill.NumberOfEditedAutofilledFieldsAtSubmission", 2, 1); |
+ |
+ // UKM must not be logged unless enabled. |
+ ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService(); |
+ EXPECT_EQ(0U, ukm_service->sources_count()); |
+ EXPECT_EQ(0U, ukm_service->entries_count()); |
} |
// Verify that when resetting the autofill manager (such as during a |
@@ -1557,7 +1656,7 @@ TEST_F(AutofillMetricsTest, |
// Ensure no metrics are logged when loading a non-fillable form. |
{ |
- autofill_manager_->OnFormsSeen(forms, TimeTicks()); |
+ autofill_manager_->OnFormsSeen(forms, TimeTicks::Now()); |
autofill_manager_->Reset(); |
EXPECT_EQ(0U, ukm_service->sources_count()); |
@@ -1568,30 +1667,22 @@ TEST_F(AutofillMetricsTest, |
test::CreateTestFormField("Phone", "phone", "", "text", &field); |
forms.back().fields.push_back(field); |
- // Expect the "form parsed without field type hints" metric to be logged. |
+ // Expect the "form parsed without field type hints" metric and the |
+ // "form loaded" form interaction event to be logged. |
{ |
- autofill_manager_->OnFormsSeen(forms, TimeTicks()); |
+ autofill_manager_->OnFormsSeen(forms, TimeTicks::Now()); |
autofill_manager_->Reset(); |
- ASSERT_EQ(1U, ukm_service->sources_count()); |
- const ukm::UkmSource* source = |
- ukm_service->GetSourceForUrl(form.origin.spec().c_str()); |
- ASSERT_NE(nullptr, source); |
- |
- ASSERT_EQ(1U, ukm_service->entries_count()); |
- const ukm::UkmEntry* entry = ukm_service->GetEntry(0); |
- EXPECT_EQ(source->id(), entry->source_id()); |
- |
- ukm::Entry entry_proto; |
- entry->PopulateProto(&entry_proto); |
- EXPECT_EQ(source->id(), entry_proto.source_id()); |
- EXPECT_EQ(base::HashMetricName(internal::kUKMDeveloperEngagementEntryName), |
- entry_proto.event_hash()); |
- const ukm::Entry_Metric* metric = FindMetric( |
- internal::kUKMDeveloperEngagementMetricName, entry_proto.metrics()); |
- ASSERT_NE(nullptr, metric); |
- EXPECT_EQ(AutofillMetrics::FILLABLE_FORM_PARSED_WITHOUT_TYPE_HINTS, |
- metric->value()); |
+ // Expect an entry for |kUKMDeveloperEngagementEntryName| and another entry |
+ // for |kUKMUserHappinessMetricName|. Both entries are for the same URL. |
+ ASSERT_EQ(2U, ukm_service->entries_count()); |
+ ASSERT_EQ(2U, ukm_service->sources_count()); |
+ VerifyDeveloperEngagementUkm( |
+ form, ukm_service, |
+ {AutofillMetrics::FILLABLE_FORM_PARSED_WITHOUT_TYPE_HINTS}); |
+ VerifyUniqueFormInteractionEventUkm(form, ukm_service, |
+ internal::kUKMUserHappinessMetricName, |
+ AutofillMetrics::FORMS_LOADED); |
} |
} |
@@ -1634,30 +1725,22 @@ TEST_F(AutofillMetricsTest, |
field.autocomplete_attribute = "address-line1"; |
forms.back().fields.push_back(field); |
- // Expect the "form parsed with field type hints" metric to be logged. |
+ // Expect the "form parsed without field type hints" metric and the |
+ // "form loaded" form interaction event to be logged. |
{ |
- autofill_manager_->OnFormsSeen(forms, TimeTicks()); |
+ autofill_manager_->OnFormsSeen(forms, TimeTicks::Now()); |
autofill_manager_->Reset(); |
- ASSERT_EQ(1U, ukm_service->sources_count()); |
- const ukm::UkmSource* source = |
- ukm_service->GetSourceForUrl(form.origin.spec().c_str()); |
- ASSERT_NE(nullptr, source); |
- |
- ASSERT_EQ(1U, ukm_service->entries_count()); |
- const ukm::UkmEntry* entry = ukm_service->GetEntry(0); |
- EXPECT_EQ(source->id(), entry->source_id()); |
- |
- ukm::Entry entry_proto; |
- entry->PopulateProto(&entry_proto); |
- EXPECT_EQ(source->id(), entry_proto.source_id()); |
- EXPECT_EQ(base::HashMetricName(internal::kUKMDeveloperEngagementEntryName), |
- entry_proto.event_hash()); |
- const ukm::Entry_Metric* metric = FindMetric( |
- internal::kUKMDeveloperEngagementMetricName, entry_proto.metrics()); |
- ASSERT_NE(nullptr, metric); |
- EXPECT_EQ(AutofillMetrics::FILLABLE_FORM_PARSED_WITH_TYPE_HINTS, |
- metric->value()); |
+ // Expect an entry for |kUKMDeveloperEngagementEntryName| and another entry |
+ // for |kUKMUserHappinessMetricName|. Both entries are for the same URL. |
+ ASSERT_EQ(2U, ukm_service->entries_count()); |
+ ASSERT_EQ(2U, ukm_service->sources_count()); |
+ VerifyDeveloperEngagementUkm( |
+ form, ukm_service, |
+ {AutofillMetrics::FILLABLE_FORM_PARSED_WITH_TYPE_HINTS}); |
+ VerifyUniqueFormInteractionEventUkm(form, ukm_service, |
+ internal::kUKMUserHappinessMetricName, |
+ AutofillMetrics::FORMS_LOADED); |
} |
} |
@@ -1683,29 +1766,36 @@ TEST_F(AutofillMetricsTest, UkmDeveloperEngagement_LogUpiVpaTypeHint) { |
std::vector<FormData> forms(1, form); |
- // Expect the "upi-vpa hint" metric to be logged. |
+ // Expect the "upi-vpa hint" metric to be logged and the "form loaded" form |
+ // interaction event to be logged. |
{ |
- autofill_manager_->OnFormsSeen(forms, TimeTicks()); |
+ autofill_manager_->OnFormsSeen(forms, TimeTicks::Now()); |
autofill_manager_->Reset(); |
- ASSERT_EQ(1U, ukm_service->sources_count()); |
- const ukm::UkmSource* source = |
- ukm_service->GetSourceForUrl(form.origin.spec().c_str()); |
- ASSERT_NE(nullptr, source); |
+ ASSERT_EQ(2U, ukm_service->entries_count()); |
+ ASSERT_EQ(2U, ukm_service->sources_count()); |
+ VerifyDeveloperEngagementUkm(form, ukm_service, |
+ {AutofillMetrics::FORM_CONTAINS_UPI_VPA_HINT}); |
+ VerifyUniqueFormInteractionEventUkm(form, ukm_service, |
+ internal::kUKMUserHappinessMetricName, |
+ AutofillMetrics::FORMS_LOADED); |
- ASSERT_EQ(1U, ukm_service->entries_count()); |
- const ukm::UkmEntry* entry = ukm_service->GetEntry(0); |
- EXPECT_EQ(source->id(), entry->source_id()); |
+ ukm_service->Purge(); |
+ } |
- ukm::Entry entry_proto; |
- entry->PopulateProto(&entry_proto); |
- EXPECT_EQ(source->id(), entry_proto.source_id()); |
- EXPECT_EQ(base::HashMetricName(internal::kUKMDeveloperEngagementEntryName), |
- entry_proto.event_hash()); |
- const ukm::Entry_Metric* metric = FindMetric( |
- internal::kUKMDeveloperEngagementMetricName, entry_proto.metrics()); |
- ASSERT_NE(nullptr, metric); |
- EXPECT_EQ(AutofillMetrics::FORM_CONTAINS_UPI_VPA_HINT, metric->value()); |
+ // Add another field with an author-specified field type to the form. |
+ test::CreateTestFormField("", "", "", "text", &field); |
+ field.autocomplete_attribute = "address-line1"; |
+ forms.back().fields.push_back(field); |
+ |
+ { |
+ autofill_manager_->OnFormsSeen(forms, TimeTicks::Now()); |
+ autofill_manager_->Reset(); |
+ |
+ VerifyDeveloperEngagementUkm( |
+ form, ukm_service, |
+ {AutofillMetrics::FILLABLE_FORM_PARSED_WITH_TYPE_HINTS, |
+ AutofillMetrics::FORM_CONTAINS_UPI_VPA_HINT}); |
} |
} |
@@ -1888,6 +1978,9 @@ TEST_F(AutofillMetricsTest, AddressSuggestionsCount) { |
// Test that the credit card checkout flow user actions are correctly logged. |
TEST_F(AutofillMetricsTest, CreditCardCheckoutFlowUserActions) { |
+ EnableUkmLogging(); |
+ ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService(); |
+ |
personal_data_->RecreateCreditCards( |
true /* include_local_credit_card */, |
false /* include_masked_server_credit_card */, |
@@ -1963,10 +2056,31 @@ TEST_F(AutofillMetricsTest, CreditCardCheckoutFlowUserActions) { |
EXPECT_EQ(1, user_action_tester.GetActionCount( |
"Autofill_FormSubmitted_NonFillable")); |
} |
+ |
+ // Expect 2 |FORM_EVENT_LOCAL_SUGGESTION_FILLED| events. First, from |
+ // call to |external_delegate_->DidAcceptSuggestion|. Second, from call to |
+ // |autofill_manager_->FillOrPreviewForm|. |
+ // Expect |NON_FILLABLE_FORM_OR_NEW_DATA| in |AutofillFormSubmittedState| |
+ // because |field.value| is empty in |DeterminePossibleFieldTypesForUpload|. |
+ ASSERT_EQ(4U, ukm_service->entries_count()); |
+ ASSERT_EQ(1U, ukm_service->sources_count()); |
+ VerifyFormInteractionsUkm( |
+ form, ukm_service, |
+ {{internal::kUKMCreditCardFormEventName, |
+ AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN}, |
+ {internal::kUKMCreditCardFormEventName, |
+ AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED}, |
+ {internal::kUKMCreditCardFormEventName, |
+ AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED}, |
+ {internal::kUKMAutofillFormSubmittedStateName, |
+ AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA}}); |
} |
// Test that the profile checkout flow user actions are correctly logged. |
TEST_F(AutofillMetricsTest, ProfileCheckoutFlowUserActions) { |
+ EnableUkmLogging(); |
+ ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService(); |
+ |
// Create a profile. |
personal_data_->RecreateProfile(); |
@@ -2014,7 +2128,7 @@ TEST_F(AutofillMetricsTest, ProfileCheckoutFlowUserActions) { |
std::string guid("00000000-0000-0000-0000-000000000001"); // local profile. |
external_delegate_->DidAcceptSuggestion( |
ASCIIToUTF16("Test"), |
- autofill_manager_->MakeFrontendID(guid, std::string()), 0); |
+ autofill_manager_->MakeFrontendID(std::string(), guid), 0); |
EXPECT_EQ(1, |
user_action_tester.GetActionCount("Autofill_SelectedSuggestion")); |
} |
@@ -2040,6 +2154,24 @@ TEST_F(AutofillMetricsTest, ProfileCheckoutFlowUserActions) { |
EXPECT_EQ(1, user_action_tester.GetActionCount( |
"Autofill_FormSubmitted_NonFillable")); |
} |
+ |
+ // Expect 2 |FORM_EVENT_LOCAL_SUGGESTION_FILLED| events. First, from |
+ // call to |external_delegate_->DidAcceptSuggestion|. Second, from call to |
+ // |autofill_manager_->FillOrPreviewForm|. |
+ // Expect |NON_FILLABLE_FORM_OR_NEW_DATA| in |AutofillFormSubmittedState| |
+ // because |field.value| is empty in |DeterminePossibleFieldTypesForUpload|. |
+ VerifyFormInteractionsUkm( |
+ form, ukm_service, |
+ {{internal::kUKMAddressFormEventName, |
+ AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN}, |
+ {internal::kUKMAddressFormEventName, |
+ AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED}, |
+ {internal::kUKMAddressFormEventName, |
+ AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED}, |
+ {internal::kUKMAutofillFormSubmittedStateName, |
+ AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA}}); |
+ ASSERT_EQ(4U, ukm_service->entries_count()); |
+ ASSERT_EQ(1U, ukm_service->sources_count()); |
} |
// Tests that the Autofill_PolledCreditCardSuggestions user action is only |
@@ -2329,6 +2461,11 @@ TEST_F(AutofillMetricsTest, CreditCardShownFormEvents) { |
"Autofill.FormEvents.CreditCard", |
AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 0); |
} |
+ |
+ // UKM must not be logged unless enabled. |
+ ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService(); |
+ EXPECT_EQ(0U, ukm_service->sources_count()); |
+ EXPECT_EQ(0U, ukm_service->entries_count()); |
} |
// Test that we log selected form event for credit cards. |
@@ -2594,6 +2731,9 @@ TEST_F(AutofillMetricsTest, CreditCardGetRealPanDuration) { |
// Test that we log submitted form events for credit cards. |
TEST_F(AutofillMetricsTest, CreditCardSubmittedFormEvents) { |
+ EnableUkmLogging(); |
+ ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService(); |
+ |
EnableWalletSync(); |
// Creating all kinds of cards. |
personal_data_->RecreateCreditCards( |
@@ -2633,6 +2773,14 @@ TEST_F(AutofillMetricsTest, CreditCardSubmittedFormEvents) { |
histogram_tester.ExpectBucketCount( |
"Autofill.FormEvents.CreditCard", |
AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1); |
+ |
+ ASSERT_EQ(1U, ukm_service->entries_count()); |
+ ASSERT_EQ(1U, ukm_service->sources_count()); |
+ VerifyFormInteractionsUkm( |
+ form, ukm_service, |
+ {{internal::kUKMAutofillFormSubmittedStateName, |
+ AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA}}); |
+ ukm_service->Purge(); |
} |
// Reset the autofill manager state. |
@@ -2651,6 +2799,16 @@ TEST_F(AutofillMetricsTest, CreditCardSubmittedFormEvents) { |
histogram_tester.ExpectBucketCount( |
"Autofill.FormEvents.CreditCard", |
AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1); |
+ |
+ ASSERT_EQ(2U, ukm_service->entries_count()); |
+ ASSERT_EQ(1U, ukm_service->sources_count()); |
+ VerifyFormInteractionsUkm( |
+ form, ukm_service, |
+ {{internal::kUKMCreditCardFormEventName, |
+ AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN}, |
+ {internal::kUKMAutofillFormSubmittedStateName, |
+ AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA}}); |
+ ukm_service->Purge(); |
} |
// Reset the autofill manager state. |
@@ -2672,6 +2830,16 @@ TEST_F(AutofillMetricsTest, CreditCardSubmittedFormEvents) { |
histogram_tester.ExpectBucketCount( |
"Autofill.FormEvents.CreditCard", |
AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1); |
+ |
+ ASSERT_EQ(2U, ukm_service->entries_count()); |
+ ASSERT_EQ(1U, ukm_service->sources_count()); |
+ VerifyFormInteractionsUkm( |
+ form, ukm_service, |
+ {{internal::kUKMCreditCardFormEventName, |
+ AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED}, |
+ {internal::kUKMAutofillFormSubmittedStateName, |
+ AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA}}); |
+ ukm_service->Purge(); |
} |
// Reset the autofill manager state. |
@@ -2694,6 +2862,16 @@ TEST_F(AutofillMetricsTest, CreditCardSubmittedFormEvents) { |
histogram_tester.ExpectBucketCount( |
"Autofill.FormEvents.CreditCard", |
AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 1); |
+ |
+ ASSERT_EQ(2U, ukm_service->entries_count()); |
+ ASSERT_EQ(1U, ukm_service->sources_count()); |
+ VerifyFormInteractionsUkm( |
+ form, ukm_service, |
+ {{internal::kUKMCreditCardFormEventName, |
+ AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED}, |
+ {internal::kUKMAutofillFormSubmittedStateName, |
+ AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA}}); |
+ ukm_service->Purge(); |
} |
// Reset the autofill manager state. |
@@ -2710,6 +2888,7 @@ TEST_F(AutofillMetricsTest, CreditCardSubmittedFormEvents) { |
autofill_manager_->MakeFrontendID(guid, std::string())); |
autofill_manager_->OnDidGetRealPan(AutofillClient::SUCCESS, |
"6011000990139424"); |
+ autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
histogram_tester.ExpectBucketCount( |
"Autofill.FormEvents.CreditCard", |
AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1); |
@@ -2717,8 +2896,25 @@ TEST_F(AutofillMetricsTest, CreditCardSubmittedFormEvents) { |
"Autofill.FormEvents.CreditCard", |
AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE, |
1); |
+ |
+ ASSERT_EQ(4U, ukm_service->entries_count()); |
+ ASSERT_EQ(1U, ukm_service->sources_count()); |
+ VerifyFormInteractionsUkm( |
+ form, ukm_service, |
+ {{internal::kUKMUnmaskPromptEventName, |
+ AutofillMetrics::UNMASK_PROMPT_SHOWN}, |
+ {internal::kUKMCreditCardFormEventName, |
+ AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED}, |
+ {internal::kUKMCreditCardFormEventName, |
+ AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED}, |
+ {internal::kUKMAutofillFormSubmittedStateName, |
+ AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA}}); |
+ ukm_service->Purge(); |
} |
+ // Reset the autofill manager state. |
+ autofill_manager_->Reset(); |
+ |
// Recreating cards as the previous test should have upgraded the masked |
// card to a full card. |
personal_data_->RecreateCreditCards( |
@@ -2726,8 +2922,6 @@ TEST_F(AutofillMetricsTest, CreditCardSubmittedFormEvents) { |
true /* include_masked_server_credit_card */, |
true /* include_full_server_credit_card */); |
- // Reset the autofill manager state. |
- autofill_manager_->Reset(); |
autofill_manager_->AddSeenForm(form, field_types, field_types); |
{ |
@@ -2735,7 +2929,27 @@ TEST_F(AutofillMetricsTest, CreditCardSubmittedFormEvents) { |
base::HistogramTester histogram_tester; |
autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
+ |
+ ASSERT_EQ(1U, ukm_service->entries_count()); |
+ ASSERT_EQ(1U, ukm_service->sources_count()); |
+ VerifyFormInteractionsUkm( |
+ form, ukm_service, |
+ {{internal::kUKMAutofillFormSubmittedStateName, |
+ AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA}}); |
+ ukm_service->Purge(); |
+ |
+ autofill_manager_->form_interactions_ukm_logger() |
+ ->set_form_loaded_timestamp(TimeTicks::Now()); |
autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
+ |
+ ASSERT_EQ(1U, ukm_service->entries_count()); |
+ ASSERT_EQ(1U, ukm_service->sources_count()); |
+ VerifyFormInteractionsUkm( |
+ form, ukm_service, |
+ {{internal::kUKMAutofillFormSubmittedStateName, |
+ AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA}}); |
+ ukm_service->Purge(); |
+ |
histogram_tester.ExpectBucketCount( |
"Autofill.FormEvents.CreditCard", |
AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1); |
@@ -2816,6 +3030,16 @@ TEST_F(AutofillMetricsTest, CreditCardSubmittedFormEvents) { |
AutofillMetrics:: |
FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE, |
0); |
+ |
+ ASSERT_EQ(2U, ukm_service->entries_count()); |
+ ASSERT_EQ(1U, ukm_service->sources_count()); |
+ VerifyFormInteractionsUkm( |
+ form, ukm_service, |
+ {{internal::kUKMCreditCardFormEventName, |
+ AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN}, |
+ {internal::kUKMAutofillFormSubmittedStateName, |
+ AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA}}); |
+ ukm_service->Purge(); |
} |
} |
@@ -3237,6 +3461,9 @@ TEST_F(AutofillMetricsTest, AddressFilledFormEvents) { |
// Test that we log submitted form events for address. |
TEST_F(AutofillMetricsTest, AddressSubmittedFormEvents) { |
+ EnableUkmLogging(); |
+ ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService(); |
+ |
EnableWalletSync(); |
// Create a profile. |
personal_data_->RecreateProfile(); |
@@ -3273,6 +3500,14 @@ TEST_F(AutofillMetricsTest, AddressSubmittedFormEvents) { |
histogram_tester.ExpectBucketCount( |
"Autofill.FormEvents.Address", |
AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1); |
+ |
+ ASSERT_EQ(1U, ukm_service->entries_count()); |
+ ASSERT_EQ(1U, ukm_service->sources_count()); |
+ VerifyFormInteractionsUkm( |
+ form, ukm_service, |
+ {{internal::kUKMAutofillFormSubmittedStateName, |
+ AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA}}); |
+ ukm_service->Purge(); |
} |
// Reset the autofill manager state. |
@@ -3323,7 +3558,11 @@ TEST_F(AutofillMetricsTest, AddressSubmittedFormEvents) { |
base::HistogramTester histogram_tester; |
autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
+ |
+ autofill_manager_->form_interactions_ukm_logger() |
+ ->set_form_loaded_timestamp(TimeTicks::Now()); |
autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
+ |
histogram_tester.ExpectBucketCount( |
"Autofill.FormEvents.Address", |
AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1); |
@@ -3360,6 +3599,7 @@ TEST_F(AutofillMetricsTest, AddressSubmittedFormEvents) { |
base::HistogramTester histogram_tester; |
autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field); |
autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
+ |
histogram_tester.ExpectBucketCount( |
"Autofill.FormEvents.Address", |
AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0); |
@@ -3730,7 +3970,6 @@ TEST_F(AutofillMetricsTest, AddressFormEventsAreSegmented) { |
} |
} |
- |
// Test that we log that Autofill is enabled when filling a form. |
TEST_F(AutofillMetricsTest, AutofillIsEnabledAtPageLoad) { |
base::HistogramTester histogram_tester; |
@@ -3769,6 +4008,9 @@ TEST_F(AutofillMetricsTest, DaysSinceLastUse_Profile) { |
// Verify that we correctly log the submitted form's state. |
TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) { |
+ EnableUkmLogging(); |
+ ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService(); |
+ |
// Start with a form with insufficiently many fields. |
FormData form; |
form.name = ASCIIToUTF16("TestForm"); |
@@ -3789,7 +4031,7 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) { |
// Expect no notifications when the form is first seen. |
{ |
base::HistogramTester histogram_tester; |
- autofill_manager_->OnFormsSeen(forms, TimeTicks()); |
+ autofill_manager_->OnFormsSeen(forms, TimeTicks::Now()); |
histogram_tester.ExpectTotalCount("Autofill.FormSubmittedState", 0); |
} |
@@ -3803,6 +4045,21 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) { |
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA, 1); |
EXPECT_EQ(1, user_action_tester.GetActionCount( |
"Autofill_FormSubmitted_NonFillable")); |
+ |
+ // Expect an entry for |DeveloperEngagement| and 2 entries for form |
+ // interactions. All 3 entries are for the same URL. |
+ ASSERT_EQ(3U, ukm_service->entries_count()); |
+ ASSERT_EQ(2U, ukm_service->sources_count()); |
+ VerifyDeveloperEngagementUkm( |
+ form, ukm_service, |
+ {AutofillMetrics::FILLABLE_FORM_PARSED_WITHOUT_TYPE_HINTS}); |
+ VerifyUniqueFormInteractionEventUkm(form, ukm_service, |
+ internal::kUKMUserHappinessMetricName, |
+ AutofillMetrics::FORMS_LOADED); |
+ VerifyUniqueFormInteractionEventUkm( |
+ form, ukm_service, internal::kUKMAutofillFormSubmittedStateName, |
+ AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA); |
+ ukm_service->Purge(); |
} |
// Non fillable form. |
@@ -3813,12 +4070,22 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) { |
{ |
base::HistogramTester histogram_tester; |
base::UserActionTester user_action_tester; |
+ autofill_manager_->form_interactions_ukm_logger() |
+ ->set_form_loaded_timestamp(TimeTicks::Now()); |
autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
histogram_tester.ExpectUniqueSample( |
"Autofill.FormSubmittedState", |
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA, 1); |
EXPECT_EQ(1, user_action_tester.GetActionCount( |
"Autofill_FormSubmitted_NonFillable")); |
+ |
+ ASSERT_EQ(1U, ukm_service->entries_count()); |
+ ASSERT_EQ(1U, ukm_service->sources_count()); |
+ VerifyFormInteractionsUkm( |
+ form, ukm_service, |
+ {{internal::kUKMAutofillFormSubmittedStateName, |
+ AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA}}); |
+ ukm_service->Purge(); |
} |
// Fill in the third field. |
@@ -3829,6 +4096,8 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) { |
{ |
base::HistogramTester histogram_tester; |
base::UserActionTester user_action_tester; |
+ autofill_manager_->form_interactions_ukm_logger() |
+ ->set_form_loaded_timestamp(TimeTicks::Now()); |
autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
histogram_tester.ExpectUniqueSample( |
"Autofill.FormSubmittedState", |
@@ -3836,9 +4105,20 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) { |
1); |
EXPECT_EQ(1, user_action_tester.GetActionCount( |
"Autofill_FormSubmitted_FilledNone_SuggestionsNotShown")); |
+ |
+ ASSERT_EQ(1U, ukm_service->entries_count()); |
+ ASSERT_EQ(1U, ukm_service->sources_count()); |
+ VerifyFormInteractionsUkm( |
+ form, ukm_service, |
+ {{internal::kUKMAutofillFormSubmittedStateName, |
+ AutofillMetrics:: |
+ FILLABLE_FORM_AUTOFILLED_NONE_DID_NOT_SHOW_SUGGESTIONS}}); |
+ ukm_service->Purge(); |
} |
// Autofilled none with suggestions shown. |
+ autofill_manager_->form_interactions_ukm_logger()->set_form_loaded_timestamp( |
+ TimeTicks::Now()); |
autofill_manager_->DidShowSuggestions(true, form, form.fields[2]); |
{ |
base::HistogramTester histogram_tester; |
@@ -3849,6 +4129,17 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) { |
AutofillMetrics::FILLABLE_FORM_AUTOFILLED_NONE_DID_SHOW_SUGGESTIONS, 1); |
EXPECT_EQ(1, user_action_tester.GetActionCount( |
"Autofill_FormSubmitted_FilledNone_SuggestionsShown")); |
+ |
+ ASSERT_EQ(2U, ukm_service->entries_count()); |
+ ASSERT_EQ(1U, ukm_service->sources_count()); |
+ VerifyFormInteractionsUkm( |
+ form, ukm_service, |
+ {{internal::kUKMAddressFormEventName, |
+ AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN}, |
+ {internal::kUKMAutofillFormSubmittedStateName, |
+ AutofillMetrics:: |
+ FILLABLE_FORM_AUTOFILLED_NONE_DID_SHOW_SUGGESTIONS}}); |
+ ukm_service->Purge(); |
} |
// Mark one of the fields as autofilled. |
@@ -3859,12 +4150,22 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) { |
{ |
base::HistogramTester histogram_tester; |
base::UserActionTester user_action_tester; |
+ autofill_manager_->form_interactions_ukm_logger() |
+ ->set_form_loaded_timestamp(TimeTicks::Now()); |
autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
histogram_tester.ExpectUniqueSample( |
"Autofill.FormSubmittedState", |
AutofillMetrics::FILLABLE_FORM_AUTOFILLED_SOME, 1); |
EXPECT_EQ(1, user_action_tester.GetActionCount( |
"Autofill_FormSubmitted_FilledSome")); |
+ |
+ ASSERT_EQ(1U, ukm_service->entries_count()); |
+ ASSERT_EQ(1U, ukm_service->sources_count()); |
+ VerifyFormInteractionsUkm( |
+ form, ukm_service, |
+ {{internal::kUKMAutofillFormSubmittedStateName, |
+ AutofillMetrics::FILLABLE_FORM_AUTOFILLED_SOME}}); |
+ ukm_service->Purge(); |
} |
// Mark all of the fillable fields as autofilled. |
@@ -3876,12 +4177,22 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) { |
{ |
base::HistogramTester histogram_tester; |
base::UserActionTester user_action_tester; |
+ autofill_manager_->form_interactions_ukm_logger() |
+ ->set_form_loaded_timestamp(TimeTicks::Now()); |
autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
histogram_tester.ExpectUniqueSample( |
"Autofill.FormSubmittedState", |
AutofillMetrics::FILLABLE_FORM_AUTOFILLED_ALL, 1); |
EXPECT_EQ(1, user_action_tester.GetActionCount( |
"Autofill_FormSubmitted_FilledAll")); |
+ |
+ ASSERT_EQ(1U, ukm_service->entries_count()); |
+ ASSERT_EQ(1U, ukm_service->sources_count()); |
+ VerifyFormInteractionsUkm( |
+ form, ukm_service, |
+ {{internal::kUKMAutofillFormSubmittedStateName, |
+ AutofillMetrics::FILLABLE_FORM_AUTOFILLED_ALL}}); |
+ ukm_service->Purge(); |
} |
// Clear out the third field's value. |
@@ -3892,18 +4203,31 @@ TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) { |
{ |
base::HistogramTester histogram_tester; |
base::UserActionTester user_action_tester; |
+ autofill_manager_->form_interactions_ukm_logger() |
+ ->set_form_loaded_timestamp(TimeTicks::Now()); |
autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
histogram_tester.ExpectUniqueSample( |
"Autofill.FormSubmittedState", |
AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA, 1); |
EXPECT_EQ(1, user_action_tester.GetActionCount( |
"Autofill_FormSubmitted_NonFillable")); |
+ |
+ ASSERT_EQ(1U, ukm_service->entries_count()); |
+ ASSERT_EQ(1U, ukm_service->sources_count()); |
+ VerifyFormInteractionsUkm( |
+ form, ukm_service, |
+ {{internal::kUKMAutofillFormSubmittedStateName, |
+ AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA}}); |
+ ukm_service->Purge(); |
} |
} |
// Verify that we correctly log user happiness metrics dealing with form |
// interaction. |
TEST_F(AutofillMetricsTest, UserHappinessFormInteraction) { |
+ EnableUkmLogging(); |
+ ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService(); |
+ |
// Load a fillable form. |
FormData form; |
form.name = ASCIIToUTF16("TestForm"); |
@@ -4003,6 +4327,28 @@ TEST_F(AutofillMetricsTest, UserHappinessFormInteraction) { |
"Autofill.UserHappiness", |
AutofillMetrics::USER_DID_EDIT_AUTOFILLED_FIELD, 1); |
} |
+ |
+ autofill_manager_->Reset(); |
+ |
+ // Verify UKM logs. |
+ VerifyFormInteractionsUkm( |
+ form, ukm_service, |
+ {{internal::kUKMUserHappinessMetricName, AutofillMetrics::FORMS_LOADED}, |
+ {internal::kUKMUserHappinessMetricName, AutofillMetrics::USER_DID_TYPE}, |
+ {internal::kUKMAddressFormEventName, |
+ AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN}, |
+ {internal::kUKMAddressFormEventName, |
+ AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN}, |
+ {internal::kUKMUserHappinessMetricName, |
+ AutofillMetrics::USER_DID_AUTOFILL}, |
+ {internal::kUKMAddressFormEventName, |
+ AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED}, |
+ {internal::kUKMUserHappinessMetricName, |
+ AutofillMetrics::USER_DID_EDIT_AUTOFILLED_FIELD}, |
+ {internal::kUKMUserHappinessMetricName, |
+ AutofillMetrics::USER_DID_AUTOFILL}, |
+ {internal::kUKMUserHappinessMetricName, |
+ AutofillMetrics::USER_DID_EDIT_AUTOFILLED_FIELD}}); |
} |
// Verify that we correctly log metrics tracking the duration of form fill. |
@@ -4580,7 +4926,7 @@ TEST_F(AutofillMetricsTest, RecordCardUploadDecisionMetric) { |
ukm::UkmServiceTestingHarness ukm_service_test_harness; |
GURL url("https://www.google.com"); |
int upload_decision = 1; |
- std::map<std::string, int> metrics = { |
+ std::vector<std::pair<const char*, int>> metrics = { |
{internal::kUKMCardUploadDecisionMetricName, upload_decision}}; |
EXPECT_TRUE(AutofillMetrics::LogUkm( |
@@ -4621,7 +4967,7 @@ TEST_F(AutofillMetricsTest, RecordDeveloperEngagementMetric) { |
ukm::UkmServiceTestingHarness ukm_service_test_harness; |
GURL url("https://www.google.com"); |
int form_structure_metric = 1; |
- std::map<std::string, int> metrics = { |
+ std::vector<std::pair<const char*, int>> metrics = { |
{internal::kUKMDeveloperEngagementMetricName, form_structure_metric}}; |
EXPECT_TRUE(AutofillMetrics::LogUkm( |
@@ -4661,7 +5007,7 @@ TEST_F(AutofillMetricsTest, RecordCardUploadDecisionMetric_InvalidUrl) { |
EnableUkmLogging(); |
ukm::UkmServiceTestingHarness ukm_service_test_harness; |
GURL url(""); |
- std::map<std::string, int> metrics = {{"metric", 1}}; |
+ std::vector<std::pair<const char*, int>> metrics = {{"metric", 1}}; |
EXPECT_FALSE(AutofillMetrics::LogUkm( |
ukm_service_test_harness.test_ukm_service(), url, "test_ukm", metrics)); |
@@ -4673,7 +5019,7 @@ TEST_F(AutofillMetricsTest, RecordCardUploadDecisionMetric_NoMetrics) { |
EnableUkmLogging(); |
ukm::UkmServiceTestingHarness ukm_service_test_harness; |
GURL url("https://www.google.com"); |
- std::map<std::string, int> metrics; |
+ std::vector<std::pair<const char*, int>> metrics; |
EXPECT_FALSE(AutofillMetrics::LogUkm( |
ukm_service_test_harness.test_ukm_service(), url, "test_ukm", metrics)); |
@@ -4685,7 +5031,7 @@ TEST_F(AutofillMetricsTest, RecordCardUploadDecisionMetric_NoUkmService) { |
EnableUkmLogging(); |
ukm::UkmServiceTestingHarness ukm_service_test_harness; |
GURL url("https://www.google.com"); |
- std::map<std::string, int> metrics = {{"metric", 1}}; |
+ std::vector<std::pair<const char*, int>> metrics = {{"metric", 1}}; |
EXPECT_FALSE(AutofillMetrics::LogUkm(nullptr, url, "test_ukm", metrics)); |
ASSERT_EQ(0U, ukm_service_test_harness.test_ukm_service()->sources_count()); |
@@ -4695,7 +5041,7 @@ TEST_F(AutofillMetricsTest, RecordCardUploadDecisionMetric_NoUkmService) { |
TEST_F(AutofillMetricsTest, RecordCardUploadDecisionMetric_FeatureDisabled) { |
ukm::UkmServiceTestingHarness ukm_service_test_harness; |
GURL url("https://www.google.com"); |
- std::map<std::string, int> metrics = {{"metric", 1}}; |
+ std::vector<std::pair<const char*, int>> metrics = {{"metric", 1}}; |
EXPECT_FALSE(AutofillMetrics::LogUkm( |
ukm_service_test_harness.test_ukm_service(), url, "test_ukm", metrics)); |