| // Copyright 2013 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. |
| |
| #include "components/autofill/core/browser/autofill_metrics.h" |
| |
| #include <stddef.h> |
| |
| #include <memory> |
| #include <vector> |
| |
| #include "base/feature_list.h" |
| #include "base/macros.h" |
| #include "base/memory/ptr_util.h" |
| #include "base/metrics/metrics_hashes.h" |
| #include "base/run_loop.h" |
| #include "base/strings/string16.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/test/histogram_tester.h" |
| #include "base/test/scoped_feature_list.h" |
| #include "base/test/scoped_task_environment.h" |
| #include "base/test/user_action_tester.h" |
| #include "base/time/time.h" |
| #include "components/autofill/core/browser/autofill_experiments.h" |
| #include "components/autofill/core/browser/autofill_external_delegate.h" |
| #include "components/autofill/core/browser/autofill_manager.h" |
| #include "components/autofill/core/browser/autofill_test_utils.h" |
| #include "components/autofill/core/browser/payments/payments_client.h" |
| #include "components/autofill/core/browser/personal_data_manager.h" |
| #include "components/autofill/core/browser/popup_item_ids.h" |
| #include "components/autofill/core/browser/test_autofill_client.h" |
| #include "components/autofill/core/browser/test_autofill_driver.h" |
| #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" |
| #include "components/autofill/core/common/form_data.h" |
| #include "components/autofill/core/common/form_field_data.h" |
| #include "components/metrics/proto/ukm/entry.pb.h" |
| #include "components/prefs/pref_service.h" |
| #include "components/rappor/test_rappor_service.h" |
| #include "components/signin/core/browser/account_tracker_service.h" |
| #include "components/signin/core/browser/fake_signin_manager.h" |
| #include "components/signin/core/browser/test_signin_client.h" |
| #include "components/signin/core/common/signin_pref_names.h" |
| #include "components/ukm/test_ukm_service.h" |
| #include "components/ukm/ukm_entry.h" |
| #include "components/ukm/ukm_source.h" |
| #include "components/webdata/common/web_data_results.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "ui/gfx/geometry/rect.h" |
| #include "url/gurl.h" |
| |
| using base::ASCIIToUTF16; |
| using base::Bucket; |
| using base::TimeTicks; |
| using rappor::TestRapporServiceImpl; |
| using ::testing::ElementsAre; |
| using ::testing::UnorderedElementsAre; |
| |
| namespace autofill { |
| namespace { |
| |
| class TestPersonalDataManager : public PersonalDataManager { |
| public: |
| TestPersonalDataManager() |
| : PersonalDataManager("en-US"), |
| autofill_enabled_(true) { |
| CreateTestAutofillProfiles(&web_profiles_); |
| } |
| |
| using PersonalDataManager::set_account_tracker; |
| using PersonalDataManager::set_signin_manager; |
| using PersonalDataManager::set_database; |
| using PersonalDataManager::SetPrefService; |
| |
| // Overridden to avoid a trip to the database. This should be a no-op except |
| // for the side-effect of logging the profile count. |
| void LoadProfiles() override { |
| { |
| std::vector<std::unique_ptr<AutofillProfile>> profiles; |
| web_profiles_.swap(profiles); |
| std::unique_ptr<WDTypedResult> result = base::MakeUnique< |
| WDResult<std::vector<std::unique_ptr<AutofillProfile>>>>( |
| AUTOFILL_PROFILES_RESULT, std::move(profiles)); |
| pending_profiles_query_ = 123; |
| OnWebDataServiceRequestDone(pending_profiles_query_, std::move(result)); |
| } |
| { |
| std::vector<std::unique_ptr<AutofillProfile>> profiles; |
| server_profiles_.swap(profiles); |
| std::unique_ptr<WDTypedResult> result = base::MakeUnique< |
| WDResult<std::vector<std::unique_ptr<AutofillProfile>>>>( |
| AUTOFILL_PROFILES_RESULT, std::move(profiles)); |
| pending_server_profiles_query_ = 124; |
| OnWebDataServiceRequestDone(pending_server_profiles_query_, |
| std::move(result)); |
| } |
| } |
| |
| // Overridden to avoid a trip to the database. |
| void LoadCreditCards() override { |
| { |
| std::vector<std::unique_ptr<CreditCard>> credit_cards; |
| local_credit_cards_.swap(credit_cards); |
| std::unique_ptr<WDTypedResult> result = |
| base::MakeUnique<WDResult<std::vector<std::unique_ptr<CreditCard>>>>( |
| AUTOFILL_CREDITCARDS_RESULT, std::move(credit_cards)); |
| pending_creditcards_query_ = 125; |
| OnWebDataServiceRequestDone(pending_creditcards_query_, |
| std::move(result)); |
| } |
| { |
| std::vector<std::unique_ptr<CreditCard>> credit_cards; |
| server_credit_cards_.swap(credit_cards); |
| std::unique_ptr<WDTypedResult> result = |
| base::MakeUnique<WDResult<std::vector<std::unique_ptr<CreditCard>>>>( |
| AUTOFILL_CREDITCARDS_RESULT, std::move(credit_cards)); |
| pending_server_creditcards_query_ = 126; |
| OnWebDataServiceRequestDone(pending_server_creditcards_query_, |
| std::move(result)); |
| } |
| } |
| |
| // Overridden to add potential new profiles to the |web_profiles_|. Since |
| // there is no database set for the test, the original method would do |
| // nothing. |
| void SetProfiles(std::vector<AutofillProfile>* profiles) override { |
| // Only need to copy all the profiles. This adds any new profiles created at |
| // form submission. |
| web_profiles_.clear(); |
| for (const auto& profile : *profiles) |
| web_profiles_.push_back(base::MakeUnique<AutofillProfile>(profile)); |
| } |
| |
| void set_autofill_enabled(bool autofill_enabled) { |
| autofill_enabled_ = autofill_enabled; |
| } |
| |
| // Removes all existing profiles |
| void ClearProfiles() { |
| web_profiles_.clear(); |
| Refresh(); |
| } |
| |
| // Removes all existing profiles and creates one profile. |
| void RecreateProfile() { |
| web_profiles_.clear(); |
| |
| std::unique_ptr<AutofillProfile> profile = |
| base::MakeUnique<AutofillProfile>(); |
| test::SetProfileInfo(profile.get(), "Elvis", "Aaron", "Presley", |
| "theking@gmail.com", "RCA", "3734 Elvis Presley Blvd.", |
| "Apt. 10", "Memphis", "Tennessee", "38116", "US", |
| "12345678901"); |
| profile->set_guid("00000000-0000-0000-0000-000000000001"); |
| web_profiles_.push_back(std::move(profile)); |
| |
| Refresh(); |
| } |
| |
| // Removes all existing credit cards and creates 0 or 1 local profiles and |
| // 0 or 1 server profile according to the parameters. |
| void RecreateCreditCards(bool include_local_credit_card, |
| bool include_masked_server_credit_card, |
| bool include_full_server_credit_card) { |
| local_credit_cards_.clear(); |
| server_credit_cards_.clear(); |
| if (include_local_credit_card) { |
| std::unique_ptr<CreditCard> credit_card = base::MakeUnique<CreditCard>( |
| "10000000-0000-0000-0000-000000000001", std::string()); |
| test::SetCreditCardInfo(credit_card.get(), nullptr, "4111111111111111", |
| "12", "24"); |
| local_credit_cards_.push_back(std::move(credit_card)); |
| } |
| if (include_masked_server_credit_card) { |
| std::unique_ptr<CreditCard> credit_card = base::MakeUnique<CreditCard>( |
| CreditCard::MASKED_SERVER_CARD, "server_id"); |
| credit_card->set_guid("10000000-0000-0000-0000-000000000002"); |
| credit_card->SetTypeForMaskedCard(kDiscoverCard); |
| server_credit_cards_.push_back(std::move(credit_card)); |
| } |
| if (include_full_server_credit_card) { |
| std::unique_ptr<CreditCard> credit_card = base::MakeUnique<CreditCard>( |
| CreditCard::FULL_SERVER_CARD, "server_id"); |
| credit_card->set_guid("10000000-0000-0000-0000-000000000003"); |
| server_credit_cards_.push_back(std::move(credit_card)); |
| } |
| Refresh(); |
| } |
| |
| bool IsAutofillEnabled() const override { return autofill_enabled_; } |
| |
| private: |
| void CreateTestAutofillProfiles( |
| std::vector<std::unique_ptr<AutofillProfile>>* profiles) { |
| std::unique_ptr<AutofillProfile> profile = |
| base::MakeUnique<AutofillProfile>(); |
| test::SetProfileInfo(profile.get(), "Elvis", "Aaron", "Presley", |
| "theking@gmail.com", "RCA", "3734 Elvis Presley Blvd.", |
| "Apt. 10", "Memphis", "Tennessee", "38116", "US", |
| "12345678901"); |
| profile->set_guid("00000000-0000-0000-0000-000000000001"); |
| profiles->push_back(std::move(profile)); |
| profile = base::MakeUnique<AutofillProfile>(); |
| test::SetProfileInfo(profile.get(), "Charles", "Hardin", "Holley", |
| "buddy@gmail.com", "Decca", "123 Apple St.", "unit 6", |
| "Lubbock", "Texas", "79401", "US", "2345678901"); |
| profile->set_guid("00000000-0000-0000-0000-000000000002"); |
| profiles->push_back(std::move(profile)); |
| } |
| |
| bool autofill_enabled_; |
| |
| DISALLOW_COPY_AND_ASSIGN(TestPersonalDataManager); |
| }; |
| |
| class TestFormStructure : public FormStructure { |
| public: |
| explicit TestFormStructure(const FormData& form) : FormStructure(form) {} |
| ~TestFormStructure() override {} |
| |
| void SetFieldTypes(const std::vector<ServerFieldType>& heuristic_types, |
| const std::vector<ServerFieldType>& server_types) { |
| ASSERT_EQ(field_count(), heuristic_types.size()); |
| ASSERT_EQ(field_count(), server_types.size()); |
| |
| for (size_t i = 0; i < field_count(); ++i) { |
| AutofillField* form_field = field(i); |
| ASSERT_TRUE(form_field); |
| form_field->set_heuristic_type(heuristic_types[i]); |
| form_field->set_server_type(server_types[i]); |
| } |
| |
| UpdateAutofillCount(); |
| } |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(TestFormStructure); |
| }; |
| |
| class TestAutofillManager : public AutofillManager { |
| public: |
| TestAutofillManager(AutofillDriver* driver, |
| AutofillClient* autofill_client, |
| TestPersonalDataManager* personal_manager) |
| : AutofillManager(driver, autofill_client, personal_manager), |
| autofill_enabled_(true) {} |
| ~TestAutofillManager() override {} |
| |
| bool IsAutofillEnabled() const override { return autofill_enabled_; } |
| |
| void set_autofill_enabled(bool autofill_enabled) { |
| autofill_enabled_ = autofill_enabled; |
| } |
| |
| void AddSeenForm(const FormData& form, |
| const std::vector<ServerFieldType>& heuristic_types, |
| const std::vector<ServerFieldType>& server_types) { |
| FormData empty_form = form; |
| for (size_t i = 0; i < empty_form.fields.size(); ++i) { |
| empty_form.fields[i].value = base::string16(); |
| } |
| |
| std::unique_ptr<TestFormStructure> form_structure = |
| base::MakeUnique<TestFormStructure>(empty_form); |
| form_structure->SetFieldTypes(heuristic_types, server_types); |
| form_structures()->push_back(std::move(form_structure)); |
| } |
| |
| // Calls AutofillManager::OnWillSubmitForm and waits for it to complete. |
| void WillSubmitForm(const FormData& form, const TimeTicks& timestamp) { |
| ResetRunLoop(); |
| if (!OnWillSubmitForm(form, timestamp)) |
| return; |
| |
| // Wait for the asynchronous OnWillSubmitForm() call to complete. |
| RunRunLoop(); |
| } |
| |
| // Calls both AutofillManager::OnWillSubmitForm and |
| // AutofillManager::OnFormSubmitted. |
| void SubmitForm(const FormData& form, const TimeTicks& timestamp) { |
| WillSubmitForm(form, timestamp); |
| OnFormSubmitted(form); |
| } |
| |
| // Control the run loop from within tests. |
| void ResetRunLoop() { run_loop_.reset(new base::RunLoop()); } |
| 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, |
| bool observed_submission) override { |
| run_loop_->Quit(); |
| |
| AutofillManager::UploadFormDataAsyncCallback( |
| submitted_form, load_time, interaction_time, submission_time, |
| observed_submission); |
| } |
| |
| private: |
| bool autofill_enabled_; |
| std::unique_ptr<base::RunLoop> run_loop_; |
| |
| DISALLOW_COPY_AND_ASSIGN(TestAutofillManager); |
| }; |
| |
| // Finds the specified UKM metric by |name| in the specified UKM |metrics|. |
| const ukm::Entry_Metric* FindMetric( |
| const char* name, |
| const google::protobuf::RepeatedPtrField<ukm::Entry_Metric>& metrics) { |
| for (const auto& metric : metrics) { |
| if (metric.metric_hash() == base::HashMetricName(name)) |
| return &metric; |
| } |
| return nullptr; |
| } |
| |
| } // namespace |
| |
| // This is defined in the autofill_metrics.cc implementation file. |
| int GetFieldTypeGroupMetric(ServerFieldType field_type, |
| AutofillMetrics::FieldTypeQualityMetric metric); |
| |
| class AutofillMetricsTest : public testing::Test { |
| public: |
| ~AutofillMetricsTest() override; |
| |
| void SetUp() override; |
| void TearDown() override; |
| |
| protected: |
| void EnableWalletSync(); |
| void EnableUkmLogging(); |
| |
| base::test::ScopedTaskEnvironment scoped_task_environment_; |
| TestAutofillClient autofill_client_; |
| std::unique_ptr<AccountTrackerService> account_tracker_; |
| std::unique_ptr<FakeSigninManagerBase> signin_manager_; |
| std::unique_ptr<TestSigninClient> signin_client_; |
| std::unique_ptr<TestAutofillDriver> autofill_driver_; |
| std::unique_ptr<TestAutofillManager> autofill_manager_; |
| std::unique_ptr<TestPersonalDataManager> personal_data_; |
| std::unique_ptr<AutofillExternalDelegate> external_delegate_; |
| base::test::ScopedFeatureList scoped_feature_list_; |
| }; |
| |
| AutofillMetricsTest::~AutofillMetricsTest() { |
| // Order of destruction is important as AutofillManager relies on |
| // PersonalDataManager to be around when it gets destroyed. |
| autofill_manager_.reset(); |
| } |
| |
| void AutofillMetricsTest::SetUp() { |
| autofill_client_.SetPrefs(test::PrefServiceForTesting()); |
| |
| // Ensure Mac OS X does not pop up a modal dialog for the Address Book. |
| test::DisableSystemServices(autofill_client_.GetPrefs()); |
| |
| // Setup identity services. |
| signin_client_.reset(new TestSigninClient(autofill_client_.GetPrefs())); |
| account_tracker_.reset(new AccountTrackerService()); |
| account_tracker_->Initialize(signin_client_.get()); |
| |
| signin_manager_.reset(new FakeSigninManagerBase(signin_client_.get(), |
| account_tracker_.get())); |
| signin_manager_->Initialize(autofill_client_.GetPrefs()); |
| |
| personal_data_.reset(new TestPersonalDataManager()); |
| personal_data_->set_database(autofill_client_.GetDatabase()); |
| personal_data_->SetPrefService(autofill_client_.GetPrefs()); |
| personal_data_->set_account_tracker(account_tracker_.get()); |
| personal_data_->set_signin_manager(signin_manager_.get()); |
| autofill_driver_.reset(new TestAutofillDriver()); |
| autofill_manager_.reset(new TestAutofillManager( |
| autofill_driver_.get(), &autofill_client_, personal_data_.get())); |
| |
| external_delegate_.reset(new AutofillExternalDelegate( |
| autofill_manager_.get(), |
| autofill_driver_.get())); |
| autofill_manager_->SetExternalDelegate(external_delegate_.get()); |
| } |
| |
| void AutofillMetricsTest::TearDown() { |
| // Order of destruction is important as AutofillManager relies on |
| // PersonalDataManager to be around when it gets destroyed. |
| autofill_manager_.reset(); |
| autofill_driver_.reset(); |
| personal_data_.reset(); |
| signin_manager_->Shutdown(); |
| signin_manager_.reset(); |
| account_tracker_->Shutdown(); |
| account_tracker_.reset(); |
| signin_client_.reset(); |
| test::ReenableSystemServices(); |
| } |
| |
| void AutofillMetricsTest::EnableWalletSync() { |
| signin_manager_->SetAuthenticatedAccountInfo("12345", "syncuser@example.com"); |
| } |
| |
| void AutofillMetricsTest::EnableUkmLogging() { |
| scoped_feature_list_.InitAndEnableFeature(kAutofillUkmLogging); |
| } |
| |
| // Test that we log quality metrics appropriately. |
| TEST_F(AutofillMetricsTest, QualityMetrics) { |
| // Set up our form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| std::vector<ServerFieldType> heuristic_types, server_types; |
| FormFieldData field; |
| |
| test::CreateTestFormField( |
| "Autofilled", "autofilled", "Elvis Aaron Presley", "text", &field); |
| field.is_autofilled = true; |
| form.fields.push_back(field); |
| heuristic_types.push_back(NAME_FULL); |
| server_types.push_back(NAME_FIRST); |
| |
| test::CreateTestFormField( |
| "Autofill Failed", "autofillfailed", "buddy@gmail.com", "text", &field); |
| field.is_autofilled = false; |
| form.fields.push_back(field); |
| heuristic_types.push_back(PHONE_HOME_NUMBER); |
| server_types.push_back(EMAIL_ADDRESS); |
| |
| test::CreateTestFormField("Empty", "empty", "", "text", &field); |
| field.is_autofilled = false; |
| form.fields.push_back(field); |
| heuristic_types.push_back(NAME_FULL); |
| server_types.push_back(NAME_FIRST); |
| |
| test::CreateTestFormField("Unknown", "unknown", "garbage", "text", &field); |
| field.is_autofilled = false; |
| form.fields.push_back(field); |
| heuristic_types.push_back(PHONE_HOME_NUMBER); |
| server_types.push_back(EMAIL_ADDRESS); |
| |
| test::CreateTestFormField("Select", "select", "USA", "select-one", &field); |
| field.is_autofilled = false; |
| form.fields.push_back(field); |
| heuristic_types.push_back(UNKNOWN_TYPE); |
| server_types.push_back(NO_SERVER_DATA); |
| |
| test::CreateTestFormField("Phone", "phone", "2345678901", "tel", &field); |
| field.is_autofilled = true; |
| form.fields.push_back(field); |
| heuristic_types.push_back(PHONE_HOME_CITY_AND_NUMBER); |
| server_types.push_back(PHONE_HOME_CITY_AND_NUMBER); |
| |
| // Simulate having seen this form on page load. |
| autofill_manager_->AddSeenForm(form, heuristic_types, server_types); |
| |
| // Simulate form submission. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| |
| // Heuristic predictions. |
| // Unknown: |
| histogram_tester.ExpectBucketCount("Autofill.Quality.HeuristicType", |
| AutofillMetrics::TYPE_UNKNOWN, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.HeuristicType.ByFieldType", |
| GetFieldTypeGroupMetric(ADDRESS_HOME_COUNTRY, |
| AutofillMetrics::TYPE_UNKNOWN), |
| 1); |
| // Match: |
| histogram_tester.ExpectBucketCount("Autofill.Quality.HeuristicType", |
| AutofillMetrics::TYPE_MATCH, 2); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.HeuristicType.ByFieldType", |
| GetFieldTypeGroupMetric(NAME_FULL, AutofillMetrics::TYPE_MATCH), 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.HeuristicType.ByFieldType", |
| GetFieldTypeGroupMetric(PHONE_HOME_CITY_AND_NUMBER, |
| AutofillMetrics::TYPE_MATCH), |
| 1); |
| // Mismatch: |
| histogram_tester.ExpectBucketCount("Autofill.Quality.HeuristicType", |
| AutofillMetrics::TYPE_MISMATCH, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.HeuristicType.ByFieldType", |
| GetFieldTypeGroupMetric(EMAIL_ADDRESS, AutofillMetrics::TYPE_MISMATCH), |
| 1); |
| |
| // Server predictions: |
| // Unknown: |
| histogram_tester.ExpectBucketCount("Autofill.Quality.ServerType", |
| AutofillMetrics::TYPE_UNKNOWN, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.ServerType.ByFieldType", |
| GetFieldTypeGroupMetric(ADDRESS_HOME_COUNTRY, |
| AutofillMetrics::TYPE_UNKNOWN), |
| 1); |
| // Match: |
| histogram_tester.ExpectBucketCount("Autofill.Quality.ServerType", |
| AutofillMetrics::TYPE_MATCH, 2); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.ServerType.ByFieldType", |
| GetFieldTypeGroupMetric(EMAIL_ADDRESS, AutofillMetrics::TYPE_MATCH), 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.ServerType.ByFieldType", |
| GetFieldTypeGroupMetric(PHONE_HOME_WHOLE_NUMBER, |
| AutofillMetrics::TYPE_MATCH), |
| 1); |
| // Mismatch: |
| histogram_tester.ExpectBucketCount("Autofill.Quality.ServerType", |
| AutofillMetrics::TYPE_MISMATCH, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.ServerType.ByFieldType", |
| GetFieldTypeGroupMetric(NAME_FULL, AutofillMetrics::TYPE_MISMATCH), 1); |
| |
| // Overall predictions: |
| // Unknown: |
| histogram_tester.ExpectBucketCount("Autofill.Quality.PredictedType", |
| AutofillMetrics::TYPE_UNKNOWN, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.PredictedType.ByFieldType", |
| GetFieldTypeGroupMetric(ADDRESS_HOME_COUNTRY, |
| AutofillMetrics::TYPE_UNKNOWN), |
| 1); |
| // Match: |
| histogram_tester.ExpectBucketCount("Autofill.Quality.PredictedType", |
| AutofillMetrics::TYPE_MATCH, 2); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.PredictedType.ByFieldType", |
| GetFieldTypeGroupMetric(EMAIL_ADDRESS, AutofillMetrics::TYPE_MATCH), 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.PredictedType.ByFieldType", |
| GetFieldTypeGroupMetric(PHONE_HOME_WHOLE_NUMBER, |
| AutofillMetrics::TYPE_MATCH), |
| 1); |
| // Mismatch: |
| histogram_tester.ExpectBucketCount("Autofill.Quality.PredictedType", |
| AutofillMetrics::TYPE_MISMATCH, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.PredictedType.ByFieldType", |
| GetFieldTypeGroupMetric(NAME_FULL, AutofillMetrics::TYPE_MISMATCH), 1); |
| } |
| |
| // Ensures that metrics that measure timing some important Autofill functions |
| // actually are recorded and retrieved. |
| TEST_F(AutofillMetricsTest, TimingMetrics) { |
| base::HistogramTester histogram_tester; |
| |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field; |
| test::CreateTestFormField( |
| "Autofilled", "autofilled", "Elvis Aaron Presley", "text", &field); |
| field.is_autofilled = true; |
| form.fields.push_back(field); |
| |
| test::CreateTestFormField( |
| "Autofill Failed", "autofillfailed", "buddy@gmail.com", "text", &field); |
| field.is_autofilled = false; |
| form.fields.push_back(field); |
| |
| test::CreateTestFormField("Phone", "phone", "2345678901", "tel", &field); |
| field.is_autofilled = false; |
| form.fields.push_back(field); |
| |
| // Simulate a OnFormsSeen() call that should trigger the recording. |
| std::vector<FormData> forms; |
| forms.push_back(form); |
| autofill_manager_->OnFormsSeen(forms, base::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 |
| // sure we have valid samples. |
| EXPECT_FALSE( |
| histogram_tester.GetAllSamples("Autofill.Timing.DetermineHeuristicTypes") |
| .empty()); |
| EXPECT_FALSE( |
| histogram_tester.GetAllSamples("Autofill.Timing.ParseForm").empty()); |
| } |
| |
| // Test that we log quality metrics appropriately when an upload is triggered |
| // but no submission event is sent. |
| TEST_F(AutofillMetricsTest, QualityMetrics_NoSubmission) { |
| // Set up our form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| std::vector<ServerFieldType> heuristic_types, server_types; |
| FormFieldData field; |
| |
| test::CreateTestFormField("Autofilled", "autofilled", "Elvis Aaron Presley", |
| "text", &field); |
| field.is_autofilled = true; |
| form.fields.push_back(field); |
| heuristic_types.push_back(NAME_FULL); |
| server_types.push_back(NAME_FIRST); |
| |
| test::CreateTestFormField("Autofill Failed", "autofillfailed", |
| "buddy@gmail.com", "text", &field); |
| field.is_autofilled = false; |
| form.fields.push_back(field); |
| heuristic_types.push_back(PHONE_HOME_NUMBER); |
| server_types.push_back(EMAIL_ADDRESS); |
| |
| test::CreateTestFormField("Empty", "empty", "", "text", &field); |
| field.is_autofilled = false; |
| form.fields.push_back(field); |
| heuristic_types.push_back(NAME_FULL); |
| server_types.push_back(NAME_FIRST); |
| |
| test::CreateTestFormField("Unknown", "unknown", "garbage", "text", &field); |
| field.is_autofilled = false; |
| form.fields.push_back(field); |
| heuristic_types.push_back(PHONE_HOME_NUMBER); |
| server_types.push_back(EMAIL_ADDRESS); |
| |
| test::CreateTestFormField("Select", "select", "USA", "select-one", &field); |
| field.is_autofilled = false; |
| form.fields.push_back(field); |
| heuristic_types.push_back(UNKNOWN_TYPE); |
| server_types.push_back(NO_SERVER_DATA); |
| |
| test::CreateTestFormField("Phone", "phone", "2345678901", "tel", &field); |
| field.is_autofilled = true; |
| form.fields.push_back(field); |
| heuristic_types.push_back(PHONE_HOME_CITY_AND_NUMBER); |
| server_types.push_back(PHONE_HOME_CITY_AND_NUMBER); |
| |
| // Simulate having seen this form on page load. |
| autofill_manager_->AddSeenForm(form, heuristic_types, server_types); |
| |
| // Simulate text input on one of the fields. |
| autofill_manager_->OnTextFieldDidChange(form, form.fields[0], TimeTicks()); |
| |
| // Trigger a form upload and metrics by Resetting the manager. |
| base::HistogramTester histogram_tester; |
| |
| autofill_manager_->ResetRunLoop(); |
| autofill_manager_->Reset(); |
| autofill_manager_->RunRunLoop(); |
| |
| // Heuristic predictions. |
| // Unknown: |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.HeuristicType.NoSubmission", |
| AutofillMetrics::TYPE_UNKNOWN, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.HeuristicType.ByFieldType.NoSubmission", |
| GetFieldTypeGroupMetric(ADDRESS_HOME_COUNTRY, |
| AutofillMetrics::TYPE_UNKNOWN), |
| 1); |
| // Match: |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.HeuristicType.NoSubmission", |
| AutofillMetrics::TYPE_MATCH, 2); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.HeuristicType.ByFieldType.NoSubmission", |
| GetFieldTypeGroupMetric(NAME_FULL, AutofillMetrics::TYPE_MATCH), 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.HeuristicType.ByFieldType.NoSubmission", |
| GetFieldTypeGroupMetric(PHONE_HOME_WHOLE_NUMBER, |
| AutofillMetrics::TYPE_MATCH), |
| 1); |
| // Mismatch: |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.HeuristicType.NoSubmission", |
| AutofillMetrics::TYPE_MISMATCH, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.HeuristicType.ByFieldType.NoSubmission", |
| GetFieldTypeGroupMetric(EMAIL_ADDRESS, AutofillMetrics::TYPE_MISMATCH), |
| 1); |
| |
| // Server predictions: |
| // Unknown: |
| histogram_tester.ExpectBucketCount("Autofill.Quality.ServerType.NoSubmission", |
| AutofillMetrics::TYPE_UNKNOWN, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.ServerType.ByFieldType.NoSubmission", |
| GetFieldTypeGroupMetric(ADDRESS_HOME_COUNTRY, |
| AutofillMetrics::TYPE_UNKNOWN), |
| 1); |
| // Match: |
| histogram_tester.ExpectBucketCount("Autofill.Quality.ServerType.NoSubmission", |
| AutofillMetrics::TYPE_MATCH, 2); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.ServerType.ByFieldType.NoSubmission", |
| GetFieldTypeGroupMetric(EMAIL_ADDRESS, AutofillMetrics::TYPE_MATCH), 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.ServerType.ByFieldType.NoSubmission", |
| GetFieldTypeGroupMetric(PHONE_HOME_WHOLE_NUMBER, |
| AutofillMetrics::TYPE_MATCH), |
| 1); |
| // Mismatch: |
| histogram_tester.ExpectBucketCount("Autofill.Quality.ServerType.NoSubmission", |
| AutofillMetrics::TYPE_MISMATCH, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.ServerType.ByFieldType.NoSubmission", |
| GetFieldTypeGroupMetric(NAME_FULL, AutofillMetrics::TYPE_MISMATCH), 1); |
| |
| // Overall predictions: |
| // Unknown: |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.PredictedType.NoSubmission", |
| AutofillMetrics::TYPE_UNKNOWN, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.PredictedType.ByFieldType.NoSubmission", |
| GetFieldTypeGroupMetric(ADDRESS_HOME_COUNTRY, |
| AutofillMetrics::TYPE_UNKNOWN), |
| 1); |
| // Match: |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.PredictedType.NoSubmission", |
| AutofillMetrics::TYPE_MATCH, 2); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.PredictedType.ByFieldType.NoSubmission", |
| GetFieldTypeGroupMetric(EMAIL_ADDRESS, AutofillMetrics::TYPE_MATCH), 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.PredictedType.ByFieldType.NoSubmission", |
| GetFieldTypeGroupMetric(PHONE_HOME_WHOLE_NUMBER, |
| AutofillMetrics::TYPE_MATCH), |
| 1); |
| // Mismatch: |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.PredictedType.NoSubmission", |
| AutofillMetrics::TYPE_MISMATCH, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.PredictedType.ByFieldType.NoSubmission", |
| GetFieldTypeGroupMetric(NAME_FULL, AutofillMetrics::TYPE_MISMATCH), 1); |
| } |
| |
| // Test that we log quality metrics for heuristics and server predictions based |
| // on autocomplete attributes present on the fields. |
| TEST_F(AutofillMetricsTest, QualityMetrics_BasedOnAutocomplete) { |
| FormData form; |
| form.name = ASCIIToUTF16("MyForm"); |
| form.origin = GURL("http://myform.com/form.html"); |
| form.action = GURL("http://myform.com/submit.html"); |
| |
| FormFieldData field; |
| // Heuristic value will match with Autocomplete attribute. |
| test::CreateTestFormField("Last Name", "lastname", "", "text", &field); |
| field.autocomplete_attribute = "family-name"; |
| form.fields.push_back(field); |
| |
| // Heuristic value will NOT match with Autocomplete attribute. |
| test::CreateTestFormField("First Name", "firstname", "", "text", &field); |
| field.autocomplete_attribute = "additional-name"; |
| form.fields.push_back(field); |
| |
| // Heuristic value will be unknown. |
| test::CreateTestFormField("Garbage label", "garbage", "", "text", &field); |
| field.autocomplete_attribute = "postal-code"; |
| form.fields.push_back(field); |
| |
| // No autocomplete attribute. No metric logged. |
| test::CreateTestFormField("Address", "address", "", "text", &field); |
| field.autocomplete_attribute = ""; |
| form.fields.push_back(field); |
| |
| std::unique_ptr<TestFormStructure> form_structure = |
| base::MakeUnique<TestFormStructure>(form); |
| TestFormStructure* form_structure_ptr = form_structure.get(); |
| form_structure->DetermineHeuristicTypes(nullptr /* ukm_service */); |
| autofill_manager_->form_structures()->push_back(std::move(form_structure)); |
| |
| AutofillQueryResponseContents response; |
| // Server response will match with autocomplete. |
| response.add_field()->set_autofill_type(NAME_LAST); |
| // Server response will NOT match with autocomplete. |
| response.add_field()->set_autofill_type(NAME_FIRST); |
| // Server response will have no data. |
| response.add_field()->set_autofill_type(NO_SERVER_DATA); |
| // Not logged. |
| response.add_field()->set_autofill_type(NAME_MIDDLE); |
| |
| std::string response_string; |
| ASSERT_TRUE(response.SerializeToString(&response_string)); |
| |
| std::vector<std::string> signatures; |
| signatures.push_back(form_structure_ptr->FormSignatureAsStr()); |
| |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnLoadedServerPredictions(response_string, signatures); |
| |
| // Verify that FormStructure::ParseQueryResponse was called (here and below). |
| histogram_tester.ExpectBucketCount("Autofill.ServerQueryResponse", |
| AutofillMetrics::QUERY_RESPONSE_RECEIVED, |
| 1); |
| histogram_tester.ExpectBucketCount("Autofill.ServerQueryResponse", |
| AutofillMetrics::QUERY_RESPONSE_PARSED, 1); |
| |
| // Autocomplete-derived types are eventually what's inferred. |
| EXPECT_EQ(NAME_LAST, form_structure_ptr->field(0)->Type().GetStorableType()); |
| EXPECT_EQ(NAME_MIDDLE, |
| form_structure_ptr->field(1)->Type().GetStorableType()); |
| EXPECT_EQ(ADDRESS_HOME_ZIP, |
| form_structure_ptr->field(2)->Type().GetStorableType()); |
| |
| // Heuristic predictions. |
| // Unknown: |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.HeuristicType.BasedOnAutocomplete", |
| AutofillMetrics::TYPE_UNKNOWN, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.HeuristicType.ByFieldType.BasedOnAutocomplete", |
| GetFieldTypeGroupMetric(ADDRESS_HOME_ZIP, AutofillMetrics::TYPE_UNKNOWN), |
| 1); |
| // Match: |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.HeuristicType.BasedOnAutocomplete", |
| AutofillMetrics::TYPE_MATCH, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.HeuristicType.ByFieldType.BasedOnAutocomplete", |
| GetFieldTypeGroupMetric(NAME_LAST, AutofillMetrics::TYPE_MATCH), 1); |
| // Mismatch: |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.HeuristicType.BasedOnAutocomplete", |
| AutofillMetrics::TYPE_MISMATCH, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.HeuristicType.ByFieldType.BasedOnAutocomplete", |
| GetFieldTypeGroupMetric(NAME_MIDDLE, AutofillMetrics::TYPE_MISMATCH), 1); |
| |
| // Server predictions. |
| // Unknown: |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.ServerType.BasedOnAutocomplete", |
| AutofillMetrics::TYPE_UNKNOWN, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.ServerType.ByFieldType.BasedOnAutocomplete", |
| GetFieldTypeGroupMetric(ADDRESS_HOME_ZIP, AutofillMetrics::TYPE_UNKNOWN), |
| 1); |
| // Match: |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.ServerType.BasedOnAutocomplete", |
| AutofillMetrics::TYPE_MATCH, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.ServerType.ByFieldType.BasedOnAutocomplete", |
| GetFieldTypeGroupMetric(NAME_LAST, AutofillMetrics::TYPE_MATCH), 1); |
| // Mismatch: |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.ServerType.BasedOnAutocomplete", |
| AutofillMetrics::TYPE_MISMATCH, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.ServerType.ByFieldType.BasedOnAutocomplete", |
| GetFieldTypeGroupMetric(NAME_MIDDLE, AutofillMetrics::TYPE_MISMATCH), 1); |
| } |
| |
| // Test that we do not log RAPPOR metrics when the number of mismatches is not |
| // high enough. |
| TEST_F(AutofillMetricsTest, Rappor_LowMismatchRate_NoMetricsReported) { |
| // Set up our form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| std::vector<ServerFieldType> heuristic_types, server_types; |
| FormFieldData field; |
| |
| test::CreateTestFormField("Autofilled", "autofilled", "Elvis Aaron Presley", |
| "text", &field); |
| field.is_autofilled = true; |
| form.fields.push_back(field); |
| heuristic_types.push_back(NAME_FULL); |
| server_types.push_back(NAME_FULL); |
| |
| test::CreateTestFormField("Autofill Failed", "autofillfailed", |
| "buddy@gmail.com", "text", &field); |
| field.is_autofilled = false; |
| form.fields.push_back(field); |
| heuristic_types.push_back(EMAIL_ADDRESS); |
| server_types.push_back(NAME_LAST); |
| |
| test::CreateTestFormField("Phone", "phone", "2345678901", "tel", &field); |
| field.is_autofilled = true; |
| form.fields.push_back(field); |
| heuristic_types.push_back(PHONE_HOME_CITY_AND_NUMBER); |
| server_types.push_back(EMAIL_ADDRESS); |
| |
| // Simulate having seen this form on page load. |
| autofill_manager_->AddSeenForm(form, heuristic_types, server_types); |
| |
| // Simulate form submission. |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| |
| // The number of mismatches did not trigger the RAPPOR metric logging. |
| EXPECT_EQ(0, autofill_client_.test_rappor_service()->GetReportsCount()); |
| } |
| |
| // Test that we don't log RAPPOR metrics in the case heuristics and/or server |
| // have no data. |
| TEST_F(AutofillMetricsTest, Rappor_NoDataServerAndHeuristic_NoMetricsReported) { |
| // Set up our form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| std::vector<ServerFieldType> heuristic_types, server_types; |
| FormFieldData field; |
| |
| test::CreateTestFormField("Autofilled", "autofilled", "Elvis Aaron Presley", |
| "text", &field); |
| field.is_autofilled = true; |
| form.fields.push_back(field); |
| heuristic_types.push_back(UNKNOWN_TYPE); |
| server_types.push_back(NO_SERVER_DATA); |
| |
| test::CreateTestFormField("Autofill Failed", "autofillfailed", |
| "buddy@gmail.com", "text", &field); |
| field.is_autofilled = false; |
| form.fields.push_back(field); |
| heuristic_types.push_back(UNKNOWN_TYPE); |
| server_types.push_back(NO_SERVER_DATA); |
| |
| test::CreateTestFormField("Phone", "phone", "2345678901", "tel", &field); |
| field.is_autofilled = true; |
| form.fields.push_back(field); |
| heuristic_types.push_back(UNKNOWN_TYPE); |
| server_types.push_back(NO_SERVER_DATA); |
| |
| // Simulate having seen this form on page load. |
| autofill_manager_->AddSeenForm(form, heuristic_types, server_types); |
| |
| // Simulate form submission. |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| |
| // No RAPPOR metrics are logged in the case of multiple UNKNOWN_TYPE and |
| // NO_SERVER_DATA for heuristics and server predictions, respectively. |
| EXPECT_EQ(0, autofill_client_.test_rappor_service()->GetReportsCount()); |
| } |
| |
| // Test that we log high number of mismatches for the server prediction. |
| TEST_F(AutofillMetricsTest, Rappor_HighServerMismatchRate_MetricsReported) { |
| // Set up our form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| std::vector<ServerFieldType> heuristic_types, server_types; |
| FormFieldData field; |
| |
| test::CreateTestFormField("Autofilled", "autofilled", "Elvis Aaron Presley", |
| "text", &field); |
| field.is_autofilled = true; |
| form.fields.push_back(field); |
| heuristic_types.push_back(NAME_FULL); |
| server_types.push_back(NAME_FIRST); |
| |
| test::CreateTestFormField("Autofill Failed", "autofillfailed", |
| "buddy@gmail.com", "text", &field); |
| field.is_autofilled = false; |
| form.fields.push_back(field); |
| heuristic_types.push_back(PHONE_HOME_NUMBER); |
| server_types.push_back(NAME_LAST); |
| |
| test::CreateTestFormField("Phone", "phone", "2345678901", "tel", &field); |
| field.is_autofilled = true; |
| form.fields.push_back(field); |
| heuristic_types.push_back(PHONE_HOME_CITY_AND_NUMBER); |
| server_types.push_back(EMAIL_ADDRESS); |
| |
| // Simulate having seen this form on page load. |
| autofill_manager_->AddSeenForm(form, heuristic_types, server_types); |
| |
| // Simulate form submission. |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| |
| // The number of mismatches did trigger the RAPPOR metric logging for server |
| // predictions. |
| EXPECT_EQ(1, autofill_client_.test_rappor_service()->GetReportsCount()); |
| std::string sample; |
| rappor::RapporType type; |
| EXPECT_FALSE( |
| autofill_client_.test_rappor_service()->GetRecordedSampleForMetric( |
| "Autofill.HighNumberOfHeuristicMismatches", &sample, &type)); |
| EXPECT_TRUE( |
| autofill_client_.test_rappor_service()->GetRecordedSampleForMetric( |
| "Autofill.HighNumberOfServerMismatches", &sample, &type)); |
| EXPECT_EQ("example.com", sample); |
| EXPECT_EQ(rappor::ETLD_PLUS_ONE_RAPPOR_TYPE, type); |
| } |
| |
| // Test that we log high number of mismatches for the heuristic predictions. |
| TEST_F(AutofillMetricsTest, Rappor_HighHeuristicMismatchRate_MetricsReported) { |
| // Set up our form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| std::vector<ServerFieldType> heuristic_types, server_types; |
| FormFieldData field; |
| |
| test::CreateTestFormField("Autofilled", "autofilled", "Elvis Aaron Presley", |
| "text", &field); |
| field.is_autofilled = true; |
| form.fields.push_back(field); |
| heuristic_types.push_back(NAME_FIRST); |
| server_types.push_back(NAME_FULL); |
| |
| test::CreateTestFormField("Autofill Failed", "autofillfailed", |
| "buddy@gmail.com", "text", &field); |
| field.is_autofilled = false; |
| form.fields.push_back(field); |
| heuristic_types.push_back(PHONE_HOME_NUMBER); |
| server_types.push_back(NAME_LAST); |
| |
| test::CreateTestFormField("Phone", "phone", "2345678901", "tel", &field); |
| field.is_autofilled = true; |
| form.fields.push_back(field); |
| heuristic_types.push_back(EMAIL_ADDRESS); |
| server_types.push_back(PHONE_HOME_WHOLE_NUMBER); |
| |
| // Simulate having seen this form on page load. |
| autofill_manager_->AddSeenForm(form, heuristic_types, server_types); |
| |
| // Simulate form submission. |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| |
| // The number of mismatches did trigger the RAPPOR metric logging for |
| // heuristic predictions. |
| EXPECT_EQ(1, autofill_client_.test_rappor_service()->GetReportsCount()); |
| std::string sample; |
| rappor::RapporType type; |
| EXPECT_FALSE( |
| autofill_client_.test_rappor_service()->GetRecordedSampleForMetric( |
| "Autofill.HighNumberOfServerMismatches", &sample, &type)); |
| EXPECT_TRUE( |
| autofill_client_.test_rappor_service()->GetRecordedSampleForMetric( |
| "Autofill.HighNumberOfHeuristicMismatches", &sample, &type)); |
| EXPECT_EQ("example.com", sample); |
| EXPECT_EQ(rappor::ETLD_PLUS_ONE_RAPPOR_TYPE, type); |
| } |
| |
| // Verify that when a field is annotated with the autocomplete attribute, its |
| // predicted type is remembered when quality metrics are logged. |
| TEST_F(AutofillMetricsTest, PredictedMetricsWithAutocomplete) { |
| // Set up our form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field1; |
| test::CreateTestFormField("Select", "select", "USA", "select-one", &field1); |
| field1.autocomplete_attribute = "country"; |
| form.fields.push_back(field1); |
| |
| // Two other fields to have the minimum of 3 to be parsed by autofill. Note |
| // that they have default values not found in the user profiles. They will be |
| // changed between the time the form is seen/parsed, and the time it is |
| // submitted. |
| FormFieldData field2; |
| test::CreateTestFormField("Unknown", "Unknown", "", "text", &field2); |
| form.fields.push_back(field2); |
| FormFieldData field3; |
| test::CreateTestFormField("Phone", "phone", "", "tel", &field3); |
| form.fields.push_back(field3); |
| |
| std::vector<FormData> forms(1, form); |
| |
| { |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnFormsSeen(forms, TimeTicks()); |
| // We change the value of the text fields to change the default/seen values |
| // (hence the values are not cleared in UpdateFromCache). The new values |
| // match what is in the test profile. |
| form.fields[1].value = base::ASCIIToUTF16("79401"); |
| form.fields[2].value = base::ASCIIToUTF16("2345678901"); |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| |
| // First verify that country was not predicted by client or server. |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.ServerType.ByFieldType", |
| GetFieldTypeGroupMetric(ADDRESS_HOME_COUNTRY, |
| AutofillMetrics::TYPE_UNKNOWN), |
| 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.HeuristicType.ByFieldType", |
| GetFieldTypeGroupMetric(ADDRESS_HOME_COUNTRY, |
| AutofillMetrics::TYPE_UNKNOWN), |
| 1); |
| // We expect a match for country because it had |autocomplete_attribute|. |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.PredictedType.ByFieldType", |
| GetFieldTypeGroupMetric(ADDRESS_HOME_COUNTRY, |
| AutofillMetrics::TYPE_MATCH), |
| 1); |
| |
| // We did not predict zip code or phone number, because they did not have |
| // |autocomplete_attribute|, nor client or server predictions. |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.ServerType.ByFieldType", |
| GetFieldTypeGroupMetric(ADDRESS_HOME_ZIP, |
| AutofillMetrics::TYPE_UNKNOWN), |
| 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.HeuristicType.ByFieldType", |
| GetFieldTypeGroupMetric(ADDRESS_HOME_ZIP, |
| AutofillMetrics::TYPE_UNKNOWN), |
| 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.PredictedType.ByFieldType", |
| GetFieldTypeGroupMetric(ADDRESS_HOME_ZIP, |
| AutofillMetrics::TYPE_UNKNOWN), |
| 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.ServerType.ByFieldType", |
| GetFieldTypeGroupMetric(PHONE_HOME_WHOLE_NUMBER, |
| AutofillMetrics::TYPE_UNKNOWN), |
| 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.HeuristicType.ByFieldType", |
| GetFieldTypeGroupMetric(PHONE_HOME_WHOLE_NUMBER, |
| AutofillMetrics::TYPE_UNKNOWN), |
| 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.PredictedType.ByFieldType", |
| GetFieldTypeGroupMetric(PHONE_HOME_WHOLE_NUMBER, |
| AutofillMetrics::TYPE_UNKNOWN), |
| 1); |
| |
| // Sanity check. |
| histogram_tester.ExpectTotalCount("Autofill.Quality.PredictedType", 3); |
| } |
| } |
| |
| // Test that we behave sanely when the cached form differs from the submitted |
| // one. |
| TEST_F(AutofillMetricsTest, SaneMetricsWithCacheMismatch) { |
| // Set up our form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| std::vector<ServerFieldType> heuristic_types, server_types; |
| |
| FormFieldData field; |
| test::CreateTestFormField( |
| "Both match", "match", "Elvis Aaron Presley", "text", &field); |
| field.is_autofilled = true; |
| form.fields.push_back(field); |
| heuristic_types.push_back(NAME_FULL); |
| server_types.push_back(NAME_FULL); |
| test::CreateTestFormField( |
| "Both mismatch", "mismatch", "buddy@gmail.com", "text", &field); |
| field.is_autofilled = false; |
| form.fields.push_back(field); |
| heuristic_types.push_back(PHONE_HOME_NUMBER); |
| server_types.push_back(PHONE_HOME_NUMBER); |
| test::CreateTestFormField( |
| "Only heuristics match", "mixed", "Memphis", "text", &field); |
| field.is_autofilled = false; |
| form.fields.push_back(field); |
| heuristic_types.push_back(ADDRESS_HOME_CITY); |
| server_types.push_back(PHONE_HOME_NUMBER); |
| test::CreateTestFormField("Unknown", "unknown", "garbage", "text", &field); |
| field.is_autofilled = false; |
| form.fields.push_back(field); |
| heuristic_types.push_back(UNKNOWN_TYPE); |
| server_types.push_back(UNKNOWN_TYPE); |
| |
| // Simulate having seen this form with the desired heuristic and server types. |
| // |form_structure| will be owned by |autofill_manager_|. |
| autofill_manager_->AddSeenForm(form, heuristic_types, server_types); |
| |
| |
| // Add a field and re-arrange the remaining form fields before submitting. |
| std::vector<FormFieldData> cached_fields = form.fields; |
| form.fields.clear(); |
| test::CreateTestFormField( |
| "New field", "new field", "Tennessee", "text", &field); |
| form.fields.push_back(field); |
| form.fields.push_back(cached_fields[2]); |
| form.fields.push_back(cached_fields[1]); |
| form.fields.push_back(cached_fields[3]); |
| form.fields.push_back(cached_fields[0]); |
| |
| // Simulate form submission. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| |
| // Heuristic predictions. |
| // Unknown: |
| histogram_tester.ExpectBucketCount("Autofill.Quality.HeuristicType", |
| AutofillMetrics::TYPE_UNKNOWN, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.HeuristicType.ByFieldType", |
| GetFieldTypeGroupMetric(ADDRESS_HOME_STATE, |
| AutofillMetrics::TYPE_UNKNOWN), |
| 1); |
| // Match: |
| histogram_tester.ExpectBucketCount("Autofill.Quality.HeuristicType", |
| AutofillMetrics::TYPE_MATCH, 2); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.HeuristicType.ByFieldType", |
| GetFieldTypeGroupMetric(ADDRESS_HOME_CITY, AutofillMetrics::TYPE_MATCH), |
| 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.HeuristicType.ByFieldType", |
| GetFieldTypeGroupMetric(NAME_FULL, AutofillMetrics::TYPE_MATCH), 1); |
| // Mismatch: |
| histogram_tester.ExpectBucketCount("Autofill.Quality.HeuristicType", |
| AutofillMetrics::TYPE_MISMATCH, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.HeuristicType.ByFieldType", |
| GetFieldTypeGroupMetric(EMAIL_ADDRESS, AutofillMetrics::TYPE_MISMATCH), |
| 1); |
| |
| // Server predictions: |
| // Unknown: |
| histogram_tester.ExpectBucketCount("Autofill.Quality.ServerType", |
| AutofillMetrics::TYPE_UNKNOWN, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.ServerType.ByFieldType", |
| GetFieldTypeGroupMetric(ADDRESS_HOME_STATE, |
| AutofillMetrics::TYPE_UNKNOWN), |
| 1); |
| // Match: |
| histogram_tester.ExpectBucketCount("Autofill.Quality.ServerType", |
| AutofillMetrics::TYPE_MATCH, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.ServerType.ByFieldType", |
| GetFieldTypeGroupMetric(NAME_FULL, AutofillMetrics::TYPE_MATCH), 1); |
| // Mismatch: |
| histogram_tester.ExpectBucketCount("Autofill.Quality.ServerType", |
| AutofillMetrics::TYPE_MISMATCH, 2); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.ServerType.ByFieldType", |
| GetFieldTypeGroupMetric(ADDRESS_HOME_CITY, |
| AutofillMetrics::TYPE_MISMATCH), |
| 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.ServerType.ByFieldType", |
| GetFieldTypeGroupMetric(EMAIL_ADDRESS, AutofillMetrics::TYPE_MISMATCH), |
| 1); |
| |
| // Overall predictions: |
| // Unknown: |
| histogram_tester.ExpectBucketCount("Autofill.Quality.PredictedType", |
| AutofillMetrics::TYPE_UNKNOWN, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.PredictedType.ByFieldType", |
| GetFieldTypeGroupMetric(ADDRESS_HOME_STATE, |
| AutofillMetrics::TYPE_UNKNOWN), |
| 1); |
| // Match: |
| histogram_tester.ExpectBucketCount("Autofill.Quality.PredictedType", |
| AutofillMetrics::TYPE_MATCH, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.PredictedType.ByFieldType", |
| GetFieldTypeGroupMetric(NAME_FULL, AutofillMetrics::TYPE_MATCH), 1); |
| // Mismatch: |
| histogram_tester.ExpectBucketCount("Autofill.Quality.PredictedType", |
| AutofillMetrics::TYPE_MISMATCH, 2); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.PredictedType.ByFieldType", |
| GetFieldTypeGroupMetric(ADDRESS_HOME_CITY, |
| AutofillMetrics::TYPE_MISMATCH), |
| 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.Quality.PredictedType.ByFieldType", |
| GetFieldTypeGroupMetric(EMAIL_ADDRESS, AutofillMetrics::TYPE_MISMATCH), |
| 1); |
| } |
| |
| // Verify that when submitting an autofillable form, the stored profile metric |
| // is logged. |
| TEST_F(AutofillMetricsTest, StoredProfileCountAutofillableFormSubmission) { |
| // Construct a fillable form. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| // Three fields is enough to make it an autofillable form. |
| FormFieldData field; |
| test::CreateTestFormField("Name", "name", "", "text", &field); |
| form.fields.push_back(field); |
| test::CreateTestFormField("Email", "email", "", "text", &field); |
| form.fields.push_back(field); |
| test::CreateTestFormField("Phone", "phone", "", "text", &field); |
| form.fields.push_back(field); |
| |
| std::vector<FormData> forms(1, form); |
| |
| // Simulate form submission. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnFormsSeen(forms, TimeTicks()); |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| |
| // An autofillable form was submitted, and the number of stored profiles is |
| // logged. |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.StoredProfileCountAtAutofillableFormSubmission", 2, 1); |
| } |
| |
| // Verify that when submitting a non-autofillable form, the stored profile |
| // metric is not logged. |
| TEST_F(AutofillMetricsTest, StoredProfileCountNonAutofillableFormSubmission) { |
| // Construct a non-fillable form. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| // Two fields is not enough to make it an autofillable form. |
| FormFieldData field; |
| test::CreateTestFormField("Name", "name", "", "text", &field); |
| form.fields.push_back(field); |
| test::CreateTestFormField("Email", "email", "", "text", &field); |
| form.fields.push_back(field); |
| |
| std::vector<FormData> forms(1, form); |
| |
| // Simulate form submission. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnFormsSeen(forms, TimeTicks()); |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| |
| // A non-autofillable form was submitted, and number of stored profiles is NOT |
| // logged. |
| histogram_tester.ExpectTotalCount( |
| "Autofill.StoredProfileCountAtAutofillableFormSubmission", 0); |
| } |
| |
| // Verify that when submitting an autofillable form, the proper number of edited |
| // fields is logged. |
| TEST_F(AutofillMetricsTest, NumberOfEditedAutofilledFields) { |
| // Construct a fillable form. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| std::vector<ServerFieldType> heuristic_types, server_types; |
| |
| // Three fields is enough to make it an autofillable form. |
| FormFieldData field; |
| test::CreateTestFormField("Autofilled", "autofilled", "Elvis Aaron Presley", |
| "text", &field); |
| field.is_autofilled = true; |
| form.fields.push_back(field); |
| heuristic_types.push_back(NAME_FULL); |
| server_types.push_back(NAME_FULL); |
| |
| test::CreateTestFormField("Autofill Failed", "autofillfailed", |
| "buddy@gmail.com", "text", &field); |
| field.is_autofilled = true; |
| form.fields.push_back(field); |
| heuristic_types.push_back(EMAIL_ADDRESS); |
| server_types.push_back(EMAIL_ADDRESS); |
| |
| test::CreateTestFormField("Phone", "phone", "2345678901", "tel", &field); |
| field.is_autofilled = true; |
| form.fields.push_back(field); |
| heuristic_types.push_back(PHONE_HOME_CITY_AND_NUMBER); |
| server_types.push_back(PHONE_HOME_CITY_AND_NUMBER); |
| |
| autofill_manager_->AddSeenForm(form, heuristic_types, server_types); |
| |
| base::HistogramTester histogram_tester; |
| // Simulate text input in the first and second fields. |
| autofill_manager_->OnTextFieldDidChange(form, form.fields[0], TimeTicks()); |
| autofill_manager_->OnTextFieldDidChange(form, form.fields[1], TimeTicks()); |
| |
| // Simulate form submission. |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| |
| // An autofillable form was submitted, and the number of edited autofilled |
| // fields is logged. |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.NumberOfEditedAutofilledFieldsAtSubmission", 2, 1); |
| } |
| |
| // Verify that when resetting the autofill manager (such as during a |
| // navigation), the proper number of edited fields is logged. |
| TEST_F(AutofillMetricsTest, NumberOfEditedAutofilledFields_NoSubmission) { |
| // Construct a fillable form. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| std::vector<ServerFieldType> heuristic_types, server_types; |
| |
| // Three fields is enough to make it an autofillable form. |
| FormFieldData field; |
| test::CreateTestFormField("Autofilled", "autofilled", "Elvis Aaron Presley", |
| "text", &field); |
| field.is_autofilled = true; |
| form.fields.push_back(field); |
| heuristic_types.push_back(NAME_FULL); |
| server_types.push_back(NAME_FULL); |
| |
| test::CreateTestFormField("Autofill Failed", "autofillfailed", |
| "buddy@gmail.com", "text", &field); |
| field.is_autofilled = true; |
| form.fields.push_back(field); |
| heuristic_types.push_back(EMAIL_ADDRESS); |
| server_types.push_back(EMAIL_ADDRESS); |
| |
| test::CreateTestFormField("Phone", "phone", "2345678901", "tel", &field); |
| field.is_autofilled = true; |
| form.fields.push_back(field); |
| heuristic_types.push_back(PHONE_HOME_CITY_AND_NUMBER); |
| server_types.push_back(PHONE_HOME_CITY_AND_NUMBER); |
| |
| autofill_manager_->AddSeenForm(form, heuristic_types, server_types); |
| |
| base::HistogramTester histogram_tester; |
| // Simulate text input in the first field. |
| autofill_manager_->OnTextFieldDidChange(form, form.fields[0], TimeTicks()); |
| |
| // We expect metrics to be logged when the manager is reset. |
| autofill_manager_->ResetRunLoop(); |
| autofill_manager_->Reset(); |
| autofill_manager_->RunRunLoop(); |
| |
| // An autofillable form was uploaded, and the number of edited autofilled |
| // fields is logged. |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.NumberOfEditedAutofilledFieldsAtSubmission.NoSubmission", 1, 1); |
| } |
| |
| // Verify that we correctly log metrics regarding developer engagement. |
| TEST_F(AutofillMetricsTest, DeveloperEngagement) { |
| ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService(); |
| |
| // Start with a non-fillable form. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field; |
| test::CreateTestFormField("Name", "name", "", "text", &field); |
| form.fields.push_back(field); |
| test::CreateTestFormField("Email", "email", "", "text", &field); |
| form.fields.push_back(field); |
| |
| std::vector<FormData> forms(1, form); |
| |
| // Ensure no metrics are logged when loading a non-fillable form. |
| { |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnFormsSeen(forms, TimeTicks()); |
| autofill_manager_->Reset(); |
| histogram_tester.ExpectTotalCount("Autofill.DeveloperEngagement", 0); |
| |
| // UKM must not be logged unless enabled. |
| EXPECT_EQ(0U, ukm_service->sources_count()); |
| EXPECT_EQ(0U, ukm_service->entries_count()); |
| } |
| |
| // Add another field to the form, so that it becomes fillable. |
| test::CreateTestFormField("Phone", "phone", "", "text", &field); |
| forms.back().fields.push_back(field); |
| |
| // Expect the "form parsed without hints" metric to be logged. |
| { |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnFormsSeen(forms, TimeTicks()); |
| autofill_manager_->Reset(); |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.DeveloperEngagement", |
| AutofillMetrics::FILLABLE_FORM_PARSED_WITHOUT_TYPE_HINTS, 1); |
| |
| // UKM must not be logged unless enabled. |
| EXPECT_EQ(0U, ukm_service->sources_count()); |
| EXPECT_EQ(0U, ukm_service->entries_count()); |
| } |
| |
| // Add some fields with an author-specified field type to the form. |
| // We need to add at least three fields, because a form must have at least |
| // three fillable fields to be considered to be autofillable; and if at least |
| // one field specifies an explicit type hint, we don't apply any of our usual |
| // local heuristics to detect field types in the rest of the form. |
| test::CreateTestFormField("", "", "", "text", &field); |
| field.autocomplete_attribute = "given-name"; |
| forms.back().fields.push_back(field); |
| test::CreateTestFormField("", "", "", "text", &field); |
| field.autocomplete_attribute = "email"; |
| forms.back().fields.push_back(field); |
| test::CreateTestFormField("", "", "", "text", &field); |
| field.autocomplete_attribute = "address-line1"; |
| forms.back().fields.push_back(field); |
| |
| // Expect the "form parsed with field type hints" metric to be logged. |
| { |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnFormsSeen(forms, TimeTicks()); |
| autofill_manager_->Reset(); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.DeveloperEngagement", |
| AutofillMetrics::FILLABLE_FORM_PARSED_WITH_TYPE_HINTS, 1); |
| |
| // UKM must not be logged unless enabled. |
| EXPECT_EQ(0U, ukm_service->sources_count()); |
| EXPECT_EQ(0U, ukm_service->entries_count()); |
| |
| histogram_tester.ExpectBucketCount( |
| "Autofill.DeveloperEngagement", |
| AutofillMetrics::FORM_CONTAINS_UPI_VPA_HINT, 0); |
| } |
| |
| // Add a field with an author-specified UPI-VPA field type in the form. |
| test::CreateTestFormField("", "", "", "text", &field); |
| field.autocomplete_attribute = "upi-vpa"; |
| forms.back().fields.push_back(field); |
| |
| // Expect the "form parsed with type hints" metric, and the |
| // "author-specified upi-vpa type" metric to be logged. |
| { |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnFormsSeen(forms, TimeTicks()); |
| autofill_manager_->Reset(); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.DeveloperEngagement", |
| AutofillMetrics::FILLABLE_FORM_PARSED_WITH_TYPE_HINTS, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.DeveloperEngagement", |
| AutofillMetrics::FORM_CONTAINS_UPI_VPA_HINT, 1); |
| } |
| } |
| |
| // Verify that we correctly log UKM for form parsed without type hints regarding |
| // developer engagement. |
| TEST_F(AutofillMetricsTest, |
| UkmDeveloperEngagement_LogFillableFormParsedWithoutTypeHints) { |
| EnableUkmLogging(); |
| ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService(); |
| |
| // Start with a non-fillable form. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field; |
| test::CreateTestFormField("Name", "name", "", "text", &field); |
| form.fields.push_back(field); |
| test::CreateTestFormField("Email", "email", "", "text", &field); |
| form.fields.push_back(field); |
| |
| std::vector<FormData> forms(1, form); |
| |
| // Ensure no metrics are logged when loading a non-fillable form. |
| { |
| autofill_manager_->OnFormsSeen(forms, TimeTicks()); |
| autofill_manager_->Reset(); |
| |
| EXPECT_EQ(0U, ukm_service->sources_count()); |
| EXPECT_EQ(0U, ukm_service->entries_count()); |
| } |
| |
| // Add another field to the form, so that it becomes fillable. |
| test::CreateTestFormField("Phone", "phone", "", "text", &field); |
| forms.back().fields.push_back(field); |
| |
| // Expect the "form parsed without field type hints" metric to be logged. |
| { |
| autofill_manager_->OnFormsSeen(forms, TimeTicks()); |
| 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()); |
| } |
| } |
| |
| // Verify that we correctly log UKM for form parsed with type hints regarding |
| // developer engagement. |
| TEST_F(AutofillMetricsTest, |
| UkmDeveloperEngagement_LogFillableFormParsedWithTypeHints) { |
| EnableUkmLogging(); |
| ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService(); |
| |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field; |
| test::CreateTestFormField("Name", "name", "", "text", &field); |
| form.fields.push_back(field); |
| test::CreateTestFormField("Email", "email", "", "text", &field); |
| form.fields.push_back(field); |
| |
| std::vector<FormData> forms(1, form); |
| |
| // Add another field to the form, so that it becomes fillable. |
| test::CreateTestFormField("Phone", "phone", "", "text", &field); |
| forms.back().fields.push_back(field); |
| |
| // Add some fields with an author-specified field type to the form. |
| // We need to add at least three fields, because a form must have at least |
| // three fillable fields to be considered to be autofillable; and if at least |
| // one field specifies an explicit type hint, we don't apply any of our usual |
| // local heuristics to detect field types in the rest of the form. |
| test::CreateTestFormField("", "", "", "text", &field); |
| field.autocomplete_attribute = "given-name"; |
| forms.back().fields.push_back(field); |
| test::CreateTestFormField("", "", "", "text", &field); |
| field.autocomplete_attribute = "email"; |
| forms.back().fields.push_back(field); |
| test::CreateTestFormField("", "", "", "text", &field); |
| field.autocomplete_attribute = "address-line1"; |
| forms.back().fields.push_back(field); |
| |
| // Expect the "form parsed with field type hints" metric to be logged. |
| { |
| autofill_manager_->OnFormsSeen(forms, TimeTicks()); |
| 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()); |
| } |
| } |
| |
| // Verify that we correctly log UKM for form parsed with type hints regarding |
| // developer engagement. |
| TEST_F(AutofillMetricsTest, UkmDeveloperEngagement_LogUpiVpaTypeHint) { |
| EnableUkmLogging(); |
| ukm::TestUkmService* ukm_service = autofill_client_.GetTestUkmService(); |
| |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field; |
| test::CreateTestFormField("Name", "name", "", "text", &field); |
| form.fields.push_back(field); |
| test::CreateTestFormField("Email", "email", "", "text", &field); |
| form.fields.push_back(field); |
| test::CreateTestFormField("Payment", "payment", "", "text", &field); |
| field.autocomplete_attribute = "upi-vpa"; |
| form.fields.push_back(field); |
| |
| std::vector<FormData> forms(1, form); |
| |
| // Expect the "upi-vpa hint" metric to be logged. |
| { |
| autofill_manager_->OnFormsSeen(forms, TimeTicks()); |
| 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::FORM_CONTAINS_UPI_VPA_HINT, metric->value()); |
| } |
| } |
| |
| // Test that the profile count is logged correctly. |
| TEST_F(AutofillMetricsTest, StoredProfileCount) { |
| // The metric should be logged when the profiles are first loaded. |
| { |
| base::HistogramTester histogram_tester; |
| personal_data_->LoadProfiles(); |
| histogram_tester.ExpectUniqueSample("Autofill.StoredProfileCount", 2, 1); |
| } |
| |
| // The metric should only be logged once. |
| { |
| base::HistogramTester histogram_tester; |
| personal_data_->LoadProfiles(); |
| histogram_tester.ExpectTotalCount("Autofill.StoredProfileCount", 0); |
| } |
| } |
| |
| // Test that the local credit card count is logged correctly. |
| TEST_F(AutofillMetricsTest, StoredLocalCreditCardCount) { |
| // The metric should be logged when the credit cards are first loaded. |
| { |
| base::HistogramTester histogram_tester; |
| personal_data_->RecreateCreditCards( |
| true /* include_local_credit_card */, |
| false /* include_masked_server_credit_card */, |
| false /* include_full_server_credit_card */); |
| histogram_tester.ExpectUniqueSample("Autofill.StoredLocalCreditCardCount", |
| 1, 1); |
| } |
| |
| // The metric should only be logged once. |
| { |
| base::HistogramTester histogram_tester; |
| personal_data_->RecreateCreditCards( |
| true /* include_local_credit_card */, |
| false /* include_masked_server_credit_card */, |
| false /* include_full_server_credit_card */); |
| histogram_tester.ExpectTotalCount("Autofill.StoredLocalCreditCardCount", 0); |
| } |
| } |
| |
| // Test that the masked server credit card counts are logged correctly. |
| TEST_F(AutofillMetricsTest, StoredServerCreditCardCounts_Masked) { |
| // The metrics should be logged when the credit cards are first loaded. |
| { |
| base::HistogramTester histogram_tester; |
| personal_data_->RecreateCreditCards( |
| false /* include_local_credit_card */, |
| true /* include_masked_server_credit_card */, |
| false /* include_full_server_credit_card */); |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.StoredServerCreditCardCount.Masked", 1, 1); |
| } |
| |
| // The metrics should only be logged once. |
| { |
| base::HistogramTester histogram_tester; |
| personal_data_->RecreateCreditCards( |
| false /* include_local_credit_card */, |
| true /* include_masked_server_credit_card */, |
| true /* include_full_server_credit_card */); |
| histogram_tester.ExpectTotalCount( |
| "Autofill.StoredServerCreditCardCount.Masked", 0); |
| } |
| } |
| |
| // Test that the unmasked (full) server credit card counts are logged correctly. |
| TEST_F(AutofillMetricsTest, StoredServerCreditCardCounts_Unmasked) { |
| // The metrics should be logged when the credit cards are first loaded. |
| { |
| base::HistogramTester histogram_tester; |
| personal_data_->RecreateCreditCards( |
| false /* include_local_credit_card */, |
| false /* include_masked_server_credit_card */, |
| true /* include_full_server_credit_card */); |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.StoredServerCreditCardCount.Unmasked", 1, 1); |
| } |
| |
| // The metrics should only be logged once. |
| { |
| base::HistogramTester histogram_tester; |
| personal_data_->RecreateCreditCards( |
| false /* include_local_credit_card */, |
| false /* include_masked_server_credit_card */, |
| true /* include_full_server_credit_card */); |
| histogram_tester.ExpectTotalCount( |
| "Autofill.StoredServerCreditCardCount.Unmasked", 0); |
| } |
| } |
| |
| // Test that we correctly log when Autofill is enabled. |
| TEST_F(AutofillMetricsTest, AutofillIsEnabledAtStartup) { |
| base::HistogramTester histogram_tester; |
| personal_data_->set_autofill_enabled(true); |
| personal_data_->Init( |
| autofill_client_.GetDatabase(), autofill_client_.GetPrefs(), |
| account_tracker_.get(), signin_manager_.get(), false); |
| histogram_tester.ExpectUniqueSample("Autofill.IsEnabled.Startup", true, 1); |
| } |
| |
| // Test that we correctly log when Autofill is disabled. |
| TEST_F(AutofillMetricsTest, AutofillIsDisabledAtStartup) { |
| base::HistogramTester histogram_tester; |
| personal_data_->set_autofill_enabled(false); |
| personal_data_->Init( |
| autofill_client_.GetDatabase(), autofill_client_.GetPrefs(), |
| account_tracker_.get(), signin_manager_.get(), false); |
| histogram_tester.ExpectUniqueSample("Autofill.IsEnabled.Startup", false, 1); |
| } |
| |
| // Test that we log the number of Autofill suggestions when filling a form. |
| TEST_F(AutofillMetricsTest, AddressSuggestionsCount) { |
| // Set up our form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field; |
| std::vector<ServerFieldType> field_types; |
| test::CreateTestFormField("Name", "name", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(NAME_FULL); |
| test::CreateTestFormField("Email", "email", "", "email", &field); |
| form.fields.push_back(field); |
| field_types.push_back(EMAIL_ADDRESS); |
| test::CreateTestFormField("Phone", "phone", "", "tel", &field); |
| form.fields.push_back(field); |
| field_types.push_back(PHONE_HOME_NUMBER); |
| |
| // Simulate having seen this form on page load. |
| // |form_structure| will be owned by |autofill_manager_|. |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulate activating the autofill popup for the phone field. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| histogram_tester.ExpectUniqueSample("Autofill.AddressSuggestionsCount", 2, |
| 1); |
| } |
| |
| { |
| // Simulate activating the autofill popup for the email field after typing. |
| // No new metric should be logged, since we're still on the same page. |
| test::CreateTestFormField("Email", "email", "b", "email", &field); |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| histogram_tester.ExpectTotalCount("Autofill.AddressSuggestionsCount", 0); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulate activating the autofill popup for the email field after typing. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| histogram_tester.ExpectUniqueSample("Autofill.AddressSuggestionsCount", 1, |
| 1); |
| } |
| |
| // Reset the autofill manager state again. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulate activating the autofill popup for the email field after typing. |
| form.fields[0].is_autofilled = true; |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| histogram_tester.ExpectTotalCount("Autofill.AddressSuggestionsCount", 0); |
| } |
| } |
| |
| // Test that the credit card checkout flow user actions are correctly logged. |
| TEST_F(AutofillMetricsTest, CreditCardCheckoutFlowUserActions) { |
| personal_data_->RecreateCreditCards( |
| true /* include_local_credit_card */, |
| false /* include_masked_server_credit_card */, |
| false /* include_full_server_credit_card */); |
| |
| // Set up our form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field; |
| std::vector<ServerFieldType> field_types; |
| test::CreateTestFormField("Name on card", "cc-name", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_NAME_FULL); |
| test::CreateTestFormField("Credit card", "card", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_NUMBER); |
| test::CreateTestFormField("Month", "card_month", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_EXP_MONTH); |
| |
| // Simulate having seen this form on page load. |
| // |form_structure| will be owned by |autofill_manager_|. |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| // Simulate an Autofill query on a credit card field. |
| { |
| base::UserActionTester user_action_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| EXPECT_EQ(1, user_action_tester.GetActionCount( |
| "Autofill_PolledCreditCardSuggestions")); |
| } |
| |
| // Simulate showing a credit card suggestion. |
| { |
| base::UserActionTester user_action_tester; |
| autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field); |
| EXPECT_EQ(1, user_action_tester.GetActionCount( |
| "Autofill_ShowedCreditCardSuggestions")); |
| } |
| |
| // Simulate selecting a credit card suggestions. |
| { |
| base::UserActionTester user_action_tester; |
| std::string guid("10000000-0000-0000-0000-000000000001"); // local card |
| external_delegate_->DidAcceptSuggestion( |
| ASCIIToUTF16("Test"), |
| autofill_manager_->MakeFrontendID(guid, std::string()), 0); |
| EXPECT_EQ(1, |
| user_action_tester.GetActionCount("Autofill_SelectedSuggestion")); |
| } |
| |
| // Simulate filling a credit card suggestion. |
| { |
| base::UserActionTester user_action_tester; |
| std::string guid("10000000-0000-0000-0000-000000000001"); // local card |
| autofill_manager_->FillOrPreviewForm( |
| AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(), |
| autofill_manager_->MakeFrontendID(guid, std::string())); |
| EXPECT_EQ(1, user_action_tester.GetActionCount( |
| "Autofill_FilledCreditCardSuggestion")); |
| } |
| |
| // Simulate submitting the credit card form. |
| { |
| base::UserActionTester user_action_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| EXPECT_EQ(1, |
| user_action_tester.GetActionCount("Autofill_OnWillSubmitForm")); |
| EXPECT_EQ(1, user_action_tester.GetActionCount( |
| "Autofill_FormSubmitted_NonFillable")); |
| } |
| } |
| |
| // Test that the profile checkout flow user actions are correctly logged. |
| TEST_F(AutofillMetricsTest, ProfileCheckoutFlowUserActions) { |
| // Create a profile. |
| personal_data_->RecreateProfile(); |
| |
| // Set up our form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field; |
| std::vector<ServerFieldType> field_types; |
| test::CreateTestFormField("State", "state", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(ADDRESS_HOME_STATE); |
| test::CreateTestFormField("City", "city", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(ADDRESS_HOME_CITY); |
| test::CreateTestFormField("Street", "street", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(ADDRESS_HOME_STREET_ADDRESS); |
| |
| // Simulate having seen this form on page load. |
| // |form_structure| will be owned by |autofill_manager_|. |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| // Simulate an Autofill query on a profile field. |
| { |
| base::UserActionTester user_action_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| EXPECT_EQ(1, user_action_tester.GetActionCount( |
| "Autofill_PolledProfileSuggestions")); |
| } |
| |
| // Simulate showing a profile suggestion. |
| { |
| base::UserActionTester user_action_tester; |
| autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field); |
| EXPECT_EQ(1, user_action_tester.GetActionCount( |
| "Autofill_ShowedProfileSuggestions")); |
| } |
| |
| // Simulate selecting a profile suggestions. |
| { |
| base::UserActionTester user_action_tester; |
| std::string guid("00000000-0000-0000-0000-000000000001"); // local profile. |
| external_delegate_->DidAcceptSuggestion( |
| ASCIIToUTF16("Test"), |
| autofill_manager_->MakeFrontendID(guid, std::string()), 0); |
| EXPECT_EQ(1, |
| user_action_tester.GetActionCount("Autofill_SelectedSuggestion")); |
| } |
| |
| // Simulate filling a profile suggestion. |
| { |
| base::UserActionTester user_action_tester; |
| std::string guid("00000000-0000-0000-0000-000000000001"); // local profile. |
| autofill_manager_->FillOrPreviewForm( |
| AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(), |
| autofill_manager_->MakeFrontendID(std::string(), guid)); |
| EXPECT_EQ(1, user_action_tester.GetActionCount( |
| "Autofill_FilledProfileSuggestion")); |
| } |
| |
| // Simulate submitting the profile form. |
| { |
| base::UserActionTester user_action_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| EXPECT_EQ(1, |
| user_action_tester.GetActionCount("Autofill_OnWillSubmitForm")); |
| EXPECT_EQ(1, user_action_tester.GetActionCount( |
| "Autofill_FormSubmitted_NonFillable")); |
| } |
| } |
| |
| // Tests that the Autofill_PolledCreditCardSuggestions user action is only |
| // logged once if the field is queried repeatedly. |
| TEST_F(AutofillMetricsTest, PolledCreditCardSuggestions_DebounceLogs) { |
| personal_data_->RecreateCreditCards( |
| true /* include_local_credit_card */, |
| false /* include_masked_server_credit_card */, |
| false /* include_full_server_credit_card */); |
| |
| // Set up the form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| |
| FormFieldData field; |
| std::vector<ServerFieldType> field_types; |
| test::CreateTestFormField("Name on card", "cc-name", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_NAME_FULL); |
| test::CreateTestFormField("Credit card", "card", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_NUMBER); |
| test::CreateTestFormField("Month", "card_month", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_EXP_MONTH); |
| |
| // Simulate having seen this form on page load. |
| // |form_structure| will be owned by |autofill_manager_|. |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| // Simulate an Autofill query on a credit card field. A poll should be logged. |
| base::UserActionTester user_action_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, form.fields[0], |
| gfx::RectF()); |
| EXPECT_EQ(1, user_action_tester.GetActionCount( |
| "Autofill_PolledCreditCardSuggestions")); |
| |
| // Simulate a second query on the same field. There should still only be one |
| // logged poll. |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, form.fields[0], |
| gfx::RectF()); |
| EXPECT_EQ(1, user_action_tester.GetActionCount( |
| "Autofill_PolledCreditCardSuggestions")); |
| |
| // Simulate a query to another field. There should be a second poll logged. |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, form.fields[1], |
| gfx::RectF()); |
| EXPECT_EQ(2, user_action_tester.GetActionCount( |
| "Autofill_PolledCreditCardSuggestions")); |
| |
| // Simulate a query back to the initial field. There should be a third poll |
| // logged. |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, form.fields[0], |
| gfx::RectF()); |
| EXPECT_EQ(3, user_action_tester.GetActionCount( |
| "Autofill_PolledCreditCardSuggestions")); |
| } |
| |
| // Tests that the Autofill.QueriedCreditCardFormIsSecure histogram is logged |
| // properly. |
| TEST_F(AutofillMetricsTest, QueriedCreditCardFormIsSecure) { |
| personal_data_->RecreateCreditCards( |
| true /* include_local_credit_card */, |
| false /* include_masked_server_credit_card */, |
| false /* include_full_server_credit_card */); |
| |
| // Set up the form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| autofill_client_.set_form_origin(form.origin); |
| |
| FormFieldData field; |
| std::vector<ServerFieldType> field_types; |
| test::CreateTestFormField("Month", "card_month", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_EXP_MONTH); |
| test::CreateTestFormField("Year", "card_year", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_EXP_2_DIGIT_YEAR); |
| test::CreateTestFormField("Credit card", "card", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_NUMBER); |
| |
| { |
| // Simulate having seen this insecure form on page load. |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| // Simulate an Autofill query on a credit card field (HTTP, non-secure |
| // form). |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, form.fields[1], |
| gfx::RectF()); |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.QueriedCreditCardFormIsSecure", false, 1); |
| } |
| |
| { |
| // Simulate having seen this secure form on page load. |
| autofill_manager_->Reset(); |
| form.origin = GURL("https://example.com/form.html"); |
| form.action = GURL("https://example.com/submit.html"); |
| autofill_client_.set_form_origin(form.origin); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| // Simulate an Autofill query on a credit card field (HTTPS form). |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, form.fields[1], |
| gfx::RectF()); |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.QueriedCreditCardFormIsSecure", true, 1); |
| } |
| } |
| |
| // Tests that the Autofill_PolledProfileSuggestions user action is only logged |
| // once if the field is queried repeatedly. |
| TEST_F(AutofillMetricsTest, PolledProfileSuggestions_DebounceLogs) { |
| personal_data_->RecreateProfile(); |
| |
| // Set up the form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field; |
| std::vector<ServerFieldType> field_types; |
| test::CreateTestFormField("State", "state", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(ADDRESS_HOME_STATE); |
| test::CreateTestFormField("City", "city", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(ADDRESS_HOME_CITY); |
| test::CreateTestFormField("Street", "street", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(ADDRESS_HOME_STREET_ADDRESS); |
| |
| // Simulate having seen this form on page load. |
| // |form_structure| will be owned by |autofill_manager_|. |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| // Simulate an Autofill query on a profile field. A poll should be logged. |
| base::UserActionTester user_action_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, form.fields[0], |
| gfx::RectF()); |
| EXPECT_EQ(1, user_action_tester.GetActionCount( |
| "Autofill_PolledProfileSuggestions")); |
| |
| // Simulate a second query on the same field. There should still only be poll |
| // logged. |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, form.fields[0], |
| gfx::RectF()); |
| EXPECT_EQ(1, user_action_tester.GetActionCount( |
| "Autofill_PolledProfileSuggestions")); |
| |
| // Simulate a query to another field. There should be a second poll logged. |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, form.fields[1], |
| gfx::RectF()); |
| EXPECT_EQ(2, user_action_tester.GetActionCount( |
| "Autofill_PolledProfileSuggestions")); |
| |
| // Simulate a query back to the initial field. There should be a third poll |
| // logged. |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, form.fields[0], |
| gfx::RectF()); |
| EXPECT_EQ(3, user_action_tester.GetActionCount( |
| "Autofill_PolledProfileSuggestions")); |
| } |
| |
| // Test that we log interacted form event for credit cards related. |
| TEST_F(AutofillMetricsTest, CreditCardInteractedFormEvents) { |
| // Set up our form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field; |
| std::vector<ServerFieldType> field_types; |
| test::CreateTestFormField("Month", "card_month", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_EXP_MONTH); |
| test::CreateTestFormField("Year", "card_year", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_EXP_2_DIGIT_YEAR); |
| test::CreateTestFormField("Credit card", "card", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_NUMBER); |
| |
| // Simulate having seen this form on page load. |
| // |form_structure| will be owned by |autofill_manager_|. |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulate activating the autofill popup for the credit card field. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulate activating the autofill popup for the credit card field twice. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| autofill_manager_->OnQueryFormFieldAutofill(1, form, field, gfx::RectF()); |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1); |
| } |
| } |
| |
| // Test that we log suggestion shown form events for credit cards. |
| TEST_F(AutofillMetricsTest, CreditCardShownFormEvents) { |
| // Set up our form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field; |
| std::vector<ServerFieldType> field_types; |
| test::CreateTestFormField("Month", "card_month", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_EXP_MONTH); |
| test::CreateTestFormField("Year", "card_year", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_EXP_2_DIGIT_YEAR); |
| test::CreateTestFormField("Credit card", "card", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_NUMBER); |
| |
| // Simulate having seen this form on page load. |
| // |form_structure| will be owned by |autofill_manager_|. |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating new popup being shown. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating two popups in the same page load. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field); |
| autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 2); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating same popup being refreshed. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->DidShowSuggestions(false /* is_new_popup */, form, |
| field); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 0); |
| } |
| } |
| |
| // Test that we log selected form event for credit cards. |
| TEST_F(AutofillMetricsTest, CreditCardSelectedFormEvents) { |
| EnableWalletSync(); |
| // Creating all kinds of cards. |
| personal_data_->RecreateCreditCards( |
| true /* include_local_credit_card */, |
| true /* include_masked_server_credit_card */, |
| true /* include_full_server_credit_card */); |
| // Set up our form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field; |
| std::vector<ServerFieldType> field_types; |
| test::CreateTestFormField("Month", "card_month", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_EXP_MONTH); |
| test::CreateTestFormField("Year", "card_year", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_EXP_2_DIGIT_YEAR); |
| test::CreateTestFormField("Credit card", "card", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_NUMBER); |
| |
| // Simulate having seen this form on page load. |
| // |form_structure| will be owned by |autofill_manager_|. |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating selecting a masked card server suggestion. |
| base::HistogramTester histogram_tester; |
| std::string guid( |
| "10000000-0000-0000-0000-000000000002"); // masked server card |
| autofill_manager_->FillOrPreviewForm( |
| AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields[2], |
| autofill_manager_->MakeFrontendID(guid, std::string())); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE, |
| 1); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating selecting multiple times a masked card server. |
| base::HistogramTester histogram_tester; |
| std::string guid( |
| "10000000-0000-0000-0000-000000000002"); // masked server card |
| autofill_manager_->FillOrPreviewForm( |
| AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields[2], |
| autofill_manager_->MakeFrontendID(guid, std::string())); |
| autofill_manager_->FillOrPreviewForm( |
| AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields[2], |
| autofill_manager_->MakeFrontendID(guid, std::string())); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED, 2); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE, |
| 1); |
| } |
| } |
| |
| // Test that we log filled form events for credit cards. |
| TEST_F(AutofillMetricsTest, CreditCardFilledFormEvents) { |
| // Creating all kinds of cards. |
| personal_data_->RecreateCreditCards( |
| true /* include_local_credit_card */, |
| true /* include_masked_server_credit_card */, |
| true /* include_full_server_credit_card */); |
| // Set up our form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field; |
| std::vector<ServerFieldType> field_types; |
| test::CreateTestFormField("Month", "card_month", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_EXP_MONTH); |
| test::CreateTestFormField("Year", "card_year", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_EXP_2_DIGIT_YEAR); |
| test::CreateTestFormField("Credit card", "card", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_NUMBER); |
| |
| // Simulate having seen this form on page load. |
| // |form_structure| will be owned by |autofill_manager_|. |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating filling a local card suggestion. |
| base::HistogramTester histogram_tester; |
| std::string guid("10000000-0000-0000-0000-000000000001"); // local card |
| autofill_manager_->FillOrPreviewForm( |
| AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(), |
| autofill_manager_->MakeFrontendID(guid, std::string())); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE, 1); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating filling a masked card server suggestion. |
| base::HistogramTester histogram_tester; |
| std::string guid( |
| "10000000-0000-0000-0000-000000000002"); // masked server card |
| autofill_manager_->FillOrPreviewForm( |
| AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.back(), |
| autofill_manager_->MakeFrontendID(guid, std::string())); |
| autofill_manager_->OnDidGetRealPan(AutofillClient::SUCCESS, |
| "6011000990139424"); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE, |
| 1); |
| } |
| |
| // Recreating cards as the previous test should have upgraded the masked |
| // card to a full card. |
| personal_data_->RecreateCreditCards( |
| true /* include_local_credit_card */, |
| 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); |
| |
| { |
| // Simulating filling a full card server suggestion. |
| base::HistogramTester histogram_tester; |
| std::string guid( |
| "10000000-0000-0000-0000-000000000003"); // full server card |
| autofill_manager_->FillOrPreviewForm( |
| AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(), |
| autofill_manager_->MakeFrontendID(guid, std::string())); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE, 1); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating filling multiple times. |
| base::HistogramTester histogram_tester; |
| std::string guid("10000000-0000-0000-0000-000000000001"); // local card |
| autofill_manager_->FillOrPreviewForm( |
| AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(), |
| autofill_manager_->MakeFrontendID(guid, std::string())); |
| autofill_manager_->FillOrPreviewForm( |
| AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(), |
| autofill_manager_->MakeFrontendID(guid, std::string())); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED, 2); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE, 1); |
| } |
| } |
| |
| // Test that we log submitted form events for credit cards. |
| TEST_F(AutofillMetricsTest, CreditCardGetRealPanDuration) { |
| EnableWalletSync(); |
| // Creating masked card |
| personal_data_->RecreateCreditCards( |
| false /* include_local_credit_card */, |
| true /* include_masked_server_credit_card */, |
| false /* include_full_server_credit_card */); |
| // Set up our form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field; |
| std::vector<ServerFieldType> field_types; |
| test::CreateTestFormField("Month", "card_month", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_EXP_MONTH); |
| test::CreateTestFormField("Year", "card_year", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_EXP_2_DIGIT_YEAR); |
| test::CreateTestFormField("Credit card", "card", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_NUMBER); |
| |
| // Simulate having seen this form on page load. |
| // |form_structure| will be owned by |autofill_manager_|. |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating filling a masked card server suggestion. |
| base::HistogramTester histogram_tester; |
| // Masked server card. |
| std::string guid("10000000-0000-0000-0000-000000000002"); |
| autofill_manager_->FillOrPreviewForm( |
| AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.back(), |
| autofill_manager_->MakeFrontendID(guid, std::string())); |
| autofill_manager_->OnDidGetRealPan(AutofillClient::SUCCESS, |
| "6011000990139424"); |
| histogram_tester.ExpectTotalCount( |
| "Autofill.UnmaskPrompt.GetRealPanDuration", 1); |
| histogram_tester.ExpectTotalCount( |
| "Autofill.UnmaskPrompt.GetRealPanDuration.Success", 1); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| // Creating masked card |
| personal_data_->RecreateCreditCards( |
| false /* include_local_credit_card */, |
| true /* include_masked_server_credit_card */, |
| false /* include_full_server_credit_card */); |
| |
| { |
| // Simulating filling a masked card server suggestion. |
| base::HistogramTester histogram_tester; |
| // Masked server card. |
| std::string guid("10000000-0000-0000-0000-000000000002"); |
| autofill_manager_->FillOrPreviewForm( |
| AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.back(), |
| autofill_manager_->MakeFrontendID(guid, std::string())); |
| autofill_manager_->OnDidGetRealPan(AutofillClient::PERMANENT_FAILURE, |
| std::string()); |
| histogram_tester.ExpectTotalCount( |
| "Autofill.UnmaskPrompt.GetRealPanDuration", 1); |
| histogram_tester.ExpectTotalCount( |
| "Autofill.UnmaskPrompt.GetRealPanDuration.Failure", 1); |
| } |
| } |
| |
| // Test that we log submitted form events for credit cards. |
| TEST_F(AutofillMetricsTest, CreditCardSubmittedFormEvents) { |
| EnableWalletSync(); |
| // Creating all kinds of cards. |
| personal_data_->RecreateCreditCards( |
| true /* include_local_credit_card */, |
| true /* include_masked_server_credit_card */, |
| true /* include_full_server_credit_card */); |
| // Set up our form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field; |
| std::vector<ServerFieldType> field_types; |
| test::CreateTestFormField("Month", "card_month", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_EXP_MONTH); |
| test::CreateTestFormField("Year", "card_year", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_EXP_2_DIGIT_YEAR); |
| test::CreateTestFormField("Credit card", "card", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_NUMBER); |
| |
| // Simulate having seen this form on page load. |
| // |form_structure| will be owned by |autofill_manager_|. |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating submission with no filled data. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating submission with suggestion shown. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field); |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating submission with filled local data. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| std::string guid("10000000-0000-0000-0000-000000000001"); // local card |
| autofill_manager_->FillOrPreviewForm( |
| AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(), |
| autofill_manager_->MakeFrontendID(guid, std::string())); |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating submission with filled server data. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| std::string guid( |
| "10000000-0000-0000-0000-000000000003"); // full server card |
| autofill_manager_->FillOrPreviewForm( |
| AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(), |
| autofill_manager_->MakeFrontendID(guid, std::string())); |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 1); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating submission with a masked card server suggestion. |
| base::HistogramTester histogram_tester; |
| std::string guid( |
| "10000000-0000-0000-0000-000000000002"); // masked server card |
| autofill_manager_->FillOrPreviewForm( |
| AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.back(), |
| autofill_manager_->MakeFrontendID(guid, std::string())); |
| autofill_manager_->OnDidGetRealPan(AutofillClient::SUCCESS, |
| "6011000990139424"); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE, |
| 1); |
| } |
| |
| // Recreating cards as the previous test should have upgraded the masked |
| // card to a full card. |
| personal_data_->RecreateCreditCards( |
| true /* include_local_credit_card */, |
| 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); |
| |
| { |
| // Simulating multiple submissions. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics:: |
| FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE, |
| 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics:: |
| FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE, |
| 0); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating submission with suggestion shown but without previous |
| // interaction. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field); |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics:: |
| FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE, |
| 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics:: |
| FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE, |
| 0); |
| } |
| } |
| |
| // Test that we log "will submit" (but not submitted) form events for credit |
| // cards. Mirrors CreditCardSubmittedFormEvents test but does not expect any |
| // "submitted" metrics. |
| TEST_F(AutofillMetricsTest, CreditCardWillSubmitFormEvents) { |
| EnableWalletSync(); |
| // Creating all kinds of cards. |
| personal_data_->RecreateCreditCards( |
| true /* include_local_credit_card */, |
| true /* include_masked_server_credit_card */, |
| true /* include_full_server_credit_card */); |
| // Set up our form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field; |
| std::vector<ServerFieldType> field_types; |
| test::CreateTestFormField("Month", "card_month", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_EXP_MONTH); |
| test::CreateTestFormField("Year", "card_year", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_EXP_2_DIGIT_YEAR); |
| test::CreateTestFormField("Credit card", "card", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_NUMBER); |
| |
| // Simulate having seen this form on page load. |
| // |form_structure| will be owned by |autofill_manager_|. |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating submission with no filled data. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| autofill_manager_->WillSubmitForm(form, TimeTicks::Now()); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 0); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating submission with suggestion shown. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field); |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| autofill_manager_->WillSubmitForm(form, TimeTicks::Now()); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating submission with filled local data. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| std::string guid("10000000-0000-0000-0000-000000000001"); // local card |
| autofill_manager_->FillOrPreviewForm( |
| AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(), |
| autofill_manager_->MakeFrontendID(guid, std::string())); |
| autofill_manager_->WillSubmitForm(form, TimeTicks::Now()); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating submission with filled server data. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| // Full server card. |
| std::string guid("10000000-0000-0000-0000-000000000003"); |
| autofill_manager_->FillOrPreviewForm( |
| AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(), |
| autofill_manager_->MakeFrontendID(guid, std::string())); |
| autofill_manager_->WillSubmitForm(form, TimeTicks::Now()); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating submission with a masked card server suggestion. |
| base::HistogramTester histogram_tester; |
| // Masked server card. |
| std::string guid("10000000-0000-0000-0000-000000000002"); |
| autofill_manager_->FillOrPreviewForm( |
| AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.back(), |
| autofill_manager_->MakeFrontendID(guid, std::string())); |
| autofill_manager_->OnDidGetRealPan(AutofillClient::SUCCESS, |
| "6011000990139424"); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE, |
| 1); |
| } |
| |
| // Recreating cards as the previous test should have upgraded the masked |
| // card to a full card. |
| personal_data_->RecreateCreditCards( |
| true /* include_local_credit_card */, |
| 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); |
| |
| { |
| // Simulating multiple submissions. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| autofill_manager_->WillSubmitForm(form, TimeTicks::Now()); |
| autofill_manager_->WillSubmitForm(form, TimeTicks::Now()); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics:: |
| FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE, |
| 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics |
| ::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE, |
| 0); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating submission with suggestion shown but without previous |
| // interaction. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field); |
| autofill_manager_->WillSubmitForm(form, TimeTicks::Now()); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics:: |
| FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE, |
| 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics:: |
| FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE, |
| 0); |
| } |
| } |
| |
| // Test that we log interacted form events for address. |
| TEST_F(AutofillMetricsTest, AddressInteractedFormEvents) { |
| // Set up our form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field; |
| std::vector<ServerFieldType> field_types; |
| test::CreateTestFormField("State", "state", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(ADDRESS_HOME_STATE); |
| test::CreateTestFormField("City", "city", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(ADDRESS_HOME_CITY); |
| test::CreateTestFormField("Street", "street", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(ADDRESS_HOME_STREET_ADDRESS); |
| |
| // Simulate having seen this form on page load. |
| // |form_structure| will be owned by |autofill_manager_|. |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulate activating the autofill popup for the street field. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulate activating the autofill popup for the street field twice. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| autofill_manager_->OnQueryFormFieldAutofill(1, form, field, gfx::RectF()); |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1); |
| } |
| } |
| |
| // Test that we log suggestion shown form events for address. |
| TEST_F(AutofillMetricsTest, AddressShownFormEvents) { |
| EnableWalletSync(); |
| // Create a profile. |
| personal_data_->RecreateProfile(); |
| // Set up our form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field; |
| std::vector<ServerFieldType> field_types; |
| test::CreateTestFormField("State", "state", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(ADDRESS_HOME_STATE); |
| test::CreateTestFormField("City", "city", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(ADDRESS_HOME_CITY); |
| test::CreateTestFormField("Street", "street", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(ADDRESS_HOME_STREET_ADDRESS); |
| |
| // Simulate having seen this form on page load. |
| // |form_structure| will be owned by |autofill_manager_|. |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating new popup being shown. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating two popups in the same page load. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field); |
| autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 2); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 1); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating same popup being refreshed. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->DidShowSuggestions(false /* is_new_popup */, form, |
| field); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE, 0); |
| } |
| } |
| |
| // Test that we log filled form events for address. |
| TEST_F(AutofillMetricsTest, AddressFilledFormEvents) { |
| EnableWalletSync(); |
| // Create a profile. |
| personal_data_->RecreateProfile(); |
| // Set up our form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field; |
| std::vector<ServerFieldType> field_types; |
| test::CreateTestFormField("State", "state", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(ADDRESS_HOME_STATE); |
| test::CreateTestFormField("City", "city", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(ADDRESS_HOME_CITY); |
| test::CreateTestFormField("Street", "street", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(ADDRESS_HOME_STREET_ADDRESS); |
| |
| // Simulate having seen this form on page load. |
| // |form_structure| will be owned by |autofill_manager_|. |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating selecting/filling a local profile suggestion. |
| base::HistogramTester histogram_tester; |
| std::string guid("00000000-0000-0000-0000-000000000001"); // local profile |
| autofill_manager_->FillOrPreviewForm( |
| AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(), |
| autofill_manager_->MakeFrontendID(std::string(), guid)); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE, 1); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating selecting/filling a local profile suggestion. |
| base::HistogramTester histogram_tester; |
| std::string guid("00000000-0000-0000-0000-000000000001"); // local profile |
| autofill_manager_->FillOrPreviewForm( |
| AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(), |
| autofill_manager_->MakeFrontendID(std::string(), guid)); |
| autofill_manager_->FillOrPreviewForm( |
| AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(), |
| autofill_manager_->MakeFrontendID(std::string(), guid)); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED, 2); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE, 1); |
| } |
| } |
| |
| // Test that we log submitted form events for address. |
| TEST_F(AutofillMetricsTest, AddressSubmittedFormEvents) { |
| EnableWalletSync(); |
| // Create a profile. |
| personal_data_->RecreateProfile(); |
| // Set up our form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field; |
| std::vector<ServerFieldType> field_types; |
| test::CreateTestFormField("State", "state", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(ADDRESS_HOME_STATE); |
| test::CreateTestFormField("City", "city", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(ADDRESS_HOME_CITY); |
| test::CreateTestFormField("Street", "street", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(ADDRESS_HOME_STREET_ADDRESS); |
| |
| // Simulate having seen this form on page load. |
| // |form_structure| will be owned by |autofill_manager_|. |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating submission with no filled data. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating submission with suggestion shown. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field); |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 1); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating submission with filled local data. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| std::string guid("00000000-0000-0000-0000-000000000001"); // local profile |
| autofill_manager_->FillOrPreviewForm( |
| AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(), |
| autofill_manager_->MakeFrontendID(std::string(), guid)); |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 1); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating multiple submissions. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating submission with suggestion show but without previous |
| // interaction. |
| 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); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics:: |
| FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE, |
| 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics:: |
| FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE, |
| 0); |
| } |
| } |
| |
| // Test that we log "will submit" (but not submitted) form events for address. |
| // Mirrors AddressSubmittedFormEvents test but does not expect any "submitted" |
| // metrics. |
| TEST_F(AutofillMetricsTest, AddressWillSubmitFormEvents) { |
| EnableWalletSync(); |
| // Create a profile. |
| personal_data_->RecreateProfile(); |
| // Set up our form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field; |
| std::vector<ServerFieldType> field_types; |
| test::CreateTestFormField("State", "state", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(ADDRESS_HOME_STATE); |
| test::CreateTestFormField("City", "city", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(ADDRESS_HOME_CITY); |
| test::CreateTestFormField("Street", "street", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(ADDRESS_HOME_STREET_ADDRESS); |
| |
| // Simulate having seen this form on page load. |
| // |form_structure| will be owned by |autofill_manager_|. |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating submission with no filled data. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| autofill_manager_->WillSubmitForm(form, TimeTicks::Now()); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 0); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating submission with suggestion shown. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field); |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| autofill_manager_->WillSubmitForm(form, TimeTicks::Now()); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating submission with filled local data. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| std::string guid("00000000-0000-0000-0000-000000000001"); // local profile |
| autofill_manager_->FillOrPreviewForm( |
| AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(), |
| autofill_manager_->MakeFrontendID(std::string(), guid)); |
| autofill_manager_->WillSubmitForm(form, TimeTicks::Now()); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating multiple submissions. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| autofill_manager_->WillSubmitForm(form, TimeTicks::Now()); |
| autofill_manager_->WillSubmitForm(form, TimeTicks::Now()); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics:: |
| FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE, |
| 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics:: |
| FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE, |
| 0); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| { |
| // Simulating submission with suggestion shown but without previous |
| // interaction. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->DidShowSuggestions(true /* is_new_popup */, form, field); |
| autofill_manager_->WillSubmitForm(form, TimeTicks::Now()); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_WILL_SUBMIT_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics:: |
| FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE, |
| 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_SUGGESTION_SHOWN_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE, 0); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.FormEvents.Address", |
| AutofillMetrics:: |
| FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE, |
| 0); |
| } |
| } |
| |
| // Test that we log interacted form event for credit cards only once. |
| TEST_F(AutofillMetricsTest, CreditCardFormEventsAreSegmented) { |
| EnableWalletSync(); |
| |
| // Set up our form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field; |
| std::vector<ServerFieldType> field_types; |
| test::CreateTestFormField("Month", "card_month", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_EXP_MONTH); |
| test::CreateTestFormField("Year", "card_year", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_EXP_2_DIGIT_YEAR); |
| test::CreateTestFormField("Credit card", "card", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_NUMBER); |
| |
| // Simulate having seen this form on page load. |
| // |form_structure| will be owned by |autofill_manager_|. |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| personal_data_->RecreateCreditCards( |
| false /* include_local_credit_card */, |
| false /* include_masked_server_credit_card */, |
| false /* include_full_server_credit_card */); |
| |
| { |
| // Simulate activating the autofill popup for the credit card field. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.FormEvents.CreditCard.WithNoData", |
| AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| personal_data_->RecreateCreditCards( |
| true /* include_local_credit_card */, |
| false /* include_masked_server_credit_card */, |
| false /* include_full_server_credit_card */); |
| |
| { |
| // Simulate activating the autofill popup for the credit card field. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.FormEvents.CreditCard.WithOnlyLocalData", |
| AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| personal_data_->RecreateCreditCards( |
| false /* include_local_credit_card */, |
| true /* include_masked_server_credit_card */, |
| false /* include_full_server_credit_card */); |
| |
| { |
| // Simulate activating the autofill popup for the credit card field. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.FormEvents.CreditCard.WithOnlyServerData", |
| AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| personal_data_->RecreateCreditCards( |
| false /* include_local_credit_card */, |
| false /* include_masked_server_credit_card */, |
| true /* include_full_server_credit_card */); |
| |
| { |
| // Simulate activating the autofill popup for the credit card field. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.FormEvents.CreditCard.WithOnlyServerData", |
| AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| personal_data_->RecreateCreditCards( |
| true /* include_local_credit_card */, |
| false /* include_masked_server_credit_card */, |
| true /* include_full_server_credit_card */); |
| |
| { |
| // Simulate activating the autofill popup for the credit card field. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.FormEvents.CreditCard.WithBothServerAndLocalData", |
| AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1); |
| } |
| } |
| |
| // Test that we log interacted form event for address only once. |
| TEST_F(AutofillMetricsTest, AddressFormEventsAreSegmented) { |
| EnableWalletSync(); |
| |
| // Set up our form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field; |
| std::vector<ServerFieldType> field_types; |
| test::CreateTestFormField("State", "state", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(ADDRESS_HOME_STATE); |
| test::CreateTestFormField("City", "city", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(ADDRESS_HOME_CITY); |
| test::CreateTestFormField("Street", "street", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(ADDRESS_HOME_STREET_ADDRESS); |
| |
| // Simulate having seen this form on page load. |
| // |form_structure| will be owned by |autofill_manager_|. |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| personal_data_->ClearProfiles(); |
| |
| { |
| // Simulate activating the autofill popup for the street field. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.FormEvents.Address.WithNoData", |
| AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1); |
| } |
| |
| // Reset the autofill manager state. |
| autofill_manager_->Reset(); |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| personal_data_->RecreateProfile(); |
| |
| { |
| // Simulate activating the autofill popup for the street field. |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.FormEvents.Address.WithOnlyLocalData", |
| AutofillMetrics::FORM_EVENT_INTERACTED_ONCE, 1); |
| } |
| } |
| |
| |
| // Test that we log that Autofill is enabled when filling a form. |
| TEST_F(AutofillMetricsTest, AutofillIsEnabledAtPageLoad) { |
| base::HistogramTester histogram_tester; |
| autofill_manager_->set_autofill_enabled(true); |
| autofill_manager_->OnFormsSeen(std::vector<FormData>(), TimeTicks()); |
| histogram_tester.ExpectUniqueSample("Autofill.IsEnabled.PageLoad", true, 1); |
| } |
| |
| // Test that we log that Autofill is disabled when filling a form. |
| TEST_F(AutofillMetricsTest, AutofillIsDisabledAtPageLoad) { |
| base::HistogramTester histogram_tester; |
| autofill_manager_->set_autofill_enabled(false); |
| autofill_manager_->OnFormsSeen(std::vector<FormData>(), TimeTicks()); |
| histogram_tester.ExpectUniqueSample("Autofill.IsEnabled.PageLoad", false, 1); |
| } |
| |
| // Test that we log the days since last use of a credit card when it is used. |
| TEST_F(AutofillMetricsTest, DaysSinceLastUse_CreditCard) { |
| base::HistogramTester histogram_tester; |
| CreditCard credit_card; |
| credit_card.set_use_date(base::Time::Now() - base::TimeDelta::FromDays(21)); |
| credit_card.RecordAndLogUse(); |
| histogram_tester.ExpectBucketCount("Autofill.DaysSinceLastUse.CreditCard", 21, |
| 1); |
| } |
| |
| // Test that we log the days since last use of a profile when it is used. |
| TEST_F(AutofillMetricsTest, DaysSinceLastUse_Profile) { |
| base::HistogramTester histogram_tester; |
| AutofillProfile profile; |
| profile.set_use_date(base::Time::Now() - base::TimeDelta::FromDays(13)); |
| profile.RecordAndLogUse(); |
| histogram_tester.ExpectBucketCount("Autofill.DaysSinceLastUse.Profile", 13, |
| 1); |
| } |
| |
| // Verify that we correctly log the submitted form's state. |
| TEST_F(AutofillMetricsTest, AutofillFormSubmittedState) { |
| // Start with a form with insufficiently many fields. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field; |
| test::CreateTestFormField("Name", "name", "", "text", &field); |
| form.fields.push_back(field); |
| test::CreateTestFormField("Email", "email", "", "text", &field); |
| form.fields.push_back(field); |
| test::CreateTestFormField("Phone", "phone", "", "text", &field); |
| form.fields.push_back(field); |
| test::CreateTestFormField("Unknown", "unknown", "", "text", &field); |
| form.fields.push_back(field); |
| std::vector<FormData> forms(1, form); |
| |
| // Expect no notifications when the form is first seen. |
| { |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnFormsSeen(forms, TimeTicks()); |
| histogram_tester.ExpectTotalCount("Autofill.FormSubmittedState", 0); |
| } |
| |
| // No data entered in the form. |
| { |
| base::HistogramTester histogram_tester; |
| base::UserActionTester user_action_tester; |
| 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")); |
| } |
| |
| // Non fillable form. |
| form.fields[0].value = ASCIIToUTF16("Elvis Aaron Presley"); |
| form.fields[1].value = ASCIIToUTF16("theking@gmail.com"); |
| forms.front() = form; |
| |
| { |
| base::HistogramTester histogram_tester; |
| base::UserActionTester user_action_tester; |
| 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")); |
| } |
| |
| // Fill in the third field. |
| form.fields[2].value = ASCIIToUTF16("12345678901"); |
| forms.front() = form; |
| |
| // Autofilled none with no suggestions shown. |
| { |
| base::HistogramTester histogram_tester; |
| base::UserActionTester user_action_tester; |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.FormSubmittedState", |
| AutofillMetrics::FILLABLE_FORM_AUTOFILLED_NONE_DID_NOT_SHOW_SUGGESTIONS, |
| 1); |
| EXPECT_EQ(1, user_action_tester.GetActionCount( |
| "Autofill_FormSubmitted_FilledNone_SuggestionsNotShown")); |
| } |
| |
| // Autofilled none with suggestions shown. |
| autofill_manager_->DidShowSuggestions(true, form, form.fields[2]); |
| { |
| base::HistogramTester histogram_tester; |
| base::UserActionTester user_action_tester; |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.FormSubmittedState", |
| AutofillMetrics::FILLABLE_FORM_AUTOFILLED_NONE_DID_SHOW_SUGGESTIONS, 1); |
| EXPECT_EQ(1, user_action_tester.GetActionCount( |
| "Autofill_FormSubmitted_FilledNone_SuggestionsShown")); |
| } |
| |
| // Mark one of the fields as autofilled. |
| form.fields[1].is_autofilled = true; |
| forms.front() = form; |
| |
| // Autofilled some of the fields. |
| { |
| base::HistogramTester histogram_tester; |
| base::UserActionTester user_action_tester; |
| 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")); |
| } |
| |
| // Mark all of the fillable fields as autofilled. |
| form.fields[0].is_autofilled = true; |
| form.fields[2].is_autofilled = true; |
| forms.front() = form; |
| |
| // Autofilled all the fields. |
| { |
| base::HistogramTester histogram_tester; |
| base::UserActionTester user_action_tester; |
| 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")); |
| } |
| |
| // Clear out the third field's value. |
| form.fields[2].value = base::string16(); |
| forms.front() = form; |
| |
| // Non fillable form. |
| { |
| base::HistogramTester histogram_tester; |
| base::UserActionTester user_action_tester; |
| 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")); |
| } |
| } |
| |
| // Verify that we correctly log user happiness metrics dealing with form |
| // interaction. |
| TEST_F(AutofillMetricsTest, UserHappinessFormInteraction) { |
| // Load a fillable form. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field; |
| test::CreateTestFormField("Name", "name", "", "text", &field); |
| form.fields.push_back(field); |
| test::CreateTestFormField("Email", "email", "", "text", &field); |
| form.fields.push_back(field); |
| test::CreateTestFormField("Phone", "phone", "", "text", &field); |
| form.fields.push_back(field); |
| |
| std::vector<FormData> forms(1, form); |
| |
| // Expect a notification when the form is first seen. |
| { |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnFormsSeen(forms, TimeTicks()); |
| histogram_tester.ExpectUniqueSample("Autofill.UserHappiness", |
| AutofillMetrics::FORMS_LOADED, 1); |
| } |
| |
| // Simulate typing. |
| { |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnTextFieldDidChange(form, form.fields.front(), |
| TimeTicks()); |
| histogram_tester.ExpectUniqueSample("Autofill.UserHappiness", |
| AutofillMetrics::USER_DID_TYPE, 1); |
| } |
| |
| // Simulate suggestions shown twice for a single edit (i.e. multiple |
| // keystrokes in a single field). |
| { |
| base::HistogramTester histogram_tester; |
| autofill_manager_->DidShowSuggestions(true, form, field); |
| autofill_manager_->DidShowSuggestions(false, form, field); |
| histogram_tester.ExpectBucketCount("Autofill.UserHappiness", |
| AutofillMetrics::SUGGESTIONS_SHOWN, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.UserHappiness", AutofillMetrics::SUGGESTIONS_SHOWN_ONCE, 1); |
| } |
| |
| // Simulate suggestions shown for a different field. |
| { |
| base::HistogramTester histogram_tester; |
| autofill_manager_->DidShowSuggestions(true, form, form.fields[1]); |
| histogram_tester.ExpectUniqueSample("Autofill.UserHappiness", |
| AutofillMetrics::SUGGESTIONS_SHOWN, 1); |
| } |
| |
| // Simulate invoking autofill. |
| { |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnDidFillAutofillFormData(form, TimeTicks()); |
| histogram_tester.ExpectBucketCount("Autofill.UserHappiness", |
| AutofillMetrics::USER_DID_AUTOFILL, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.UserHappiness", AutofillMetrics::USER_DID_AUTOFILL_ONCE, 1); |
| } |
| |
| // Simulate editing an autofilled field. |
| { |
| base::HistogramTester histogram_tester; |
| std::string guid("00000000-0000-0000-0000-000000000001"); |
| autofill_manager_->FillOrPreviewForm( |
| AutofillDriver::FORM_DATA_ACTION_FILL, 0, form, form.fields.front(), |
| autofill_manager_->MakeFrontendID(std::string(), guid)); |
| autofill_manager_->OnTextFieldDidChange(form, form.fields.front(), |
| TimeTicks()); |
| // Simulate a second keystroke; make sure we don't log the metric twice. |
| autofill_manager_->OnTextFieldDidChange(form, form.fields.front(), |
| TimeTicks()); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.UserHappiness", |
| AutofillMetrics::USER_DID_EDIT_AUTOFILLED_FIELD, 1); |
| histogram_tester.ExpectBucketCount( |
| "Autofill.UserHappiness", |
| AutofillMetrics::USER_DID_EDIT_AUTOFILLED_FIELD_ONCE, 1); |
| } |
| |
| // Simulate invoking autofill again. |
| { |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnDidFillAutofillFormData(form, TimeTicks()); |
| histogram_tester.ExpectUniqueSample("Autofill.UserHappiness", |
| AutofillMetrics::USER_DID_AUTOFILL, 1); |
| } |
| |
| // Simulate editing another autofilled field. |
| { |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnTextFieldDidChange(form, form.fields[1], TimeTicks()); |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.UserHappiness", |
| AutofillMetrics::USER_DID_EDIT_AUTOFILLED_FIELD, 1); |
| } |
| } |
| |
| // Verify that we correctly log metrics tracking the duration of form fill. |
| TEST_F(AutofillMetricsTest, FormFillDuration) { |
| // Load a fillable form. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field; |
| test::CreateTestFormField("Name", "name", "", "text", &field); |
| form.fields.push_back(field); |
| test::CreateTestFormField("Email", "email", "", "text", &field); |
| form.fields.push_back(field); |
| test::CreateTestFormField("Phone", "phone", "", "text", &field); |
| form.fields.push_back(field); |
| |
| const std::vector<FormData> forms(1, form); |
| |
| // Fill additional form. |
| FormData second_form = form; |
| test::CreateTestFormField("Second Phone", "second_phone", "", "text", &field); |
| second_form.fields.push_back(field); |
| |
| std::vector<FormData> second_forms(1, second_form); |
| |
| // Fill the field values for form submission. |
| form.fields[0].value = ASCIIToUTF16("Elvis Aaron Presley"); |
| form.fields[1].value = ASCIIToUTF16("theking@gmail.com"); |
| form.fields[2].value = ASCIIToUTF16("12345678901"); |
| |
| // Fill the field values for form submission. |
| second_form.fields[0].value = ASCIIToUTF16("Elvis Aaron Presley"); |
| second_form.fields[1].value = ASCIIToUTF16("theking@gmail.com"); |
| second_form.fields[2].value = ASCIIToUTF16("12345678901"); |
| second_form.fields[3].value = ASCIIToUTF16("51512345678"); |
| |
| // Expect only form load metrics to be logged if the form is submitted without |
| // user interaction. |
| { |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnFormsSeen(forms, TimeTicks::FromInternalValue(1)); |
| autofill_manager_->SubmitForm(form, TimeTicks::FromInternalValue(17)); |
| |
| histogram_tester.ExpectTotalCount( |
| "Autofill.FillDuration.FromLoad.WithAutofill", 0); |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.FillDuration.FromLoad.WithoutAutofill", 16, 1); |
| histogram_tester.ExpectTotalCount( |
| "Autofill.FillDuration.FromInteraction.WithAutofill", 0); |
| histogram_tester.ExpectTotalCount( |
| "Autofill.FillDuration.FromInteraction.WithoutAutofill", 0); |
| |
| autofill_manager_->Reset(); |
| } |
| |
| // Expect metric to be logged if the user manually edited a form field. |
| { |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnFormsSeen(forms, TimeTicks::FromInternalValue(1)); |
| autofill_manager_->OnTextFieldDidChange(form, form.fields.front(), |
| TimeTicks::FromInternalValue(3)); |
| autofill_manager_->SubmitForm(form, TimeTicks::FromInternalValue(17)); |
| |
| histogram_tester.ExpectTotalCount( |
| "Autofill.FillDuration.FromLoad.WithAutofill", 0); |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.FillDuration.FromLoad.WithoutAutofill", 16, 1); |
| histogram_tester.ExpectTotalCount( |
| "Autofill.FillDuration.FromInteraction.WithAutofill", 0); |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.FillDuration.FromInteraction.WithoutAutofill", 14, 1); |
| |
| // We expected an upload to be triggered when the manager is reset. |
| autofill_manager_->ResetRunLoop(); |
| autofill_manager_->Reset(); |
| autofill_manager_->RunRunLoop(); |
| } |
| |
| // Expect metric to be logged if the user autofilled the form. |
| form.fields[0].is_autofilled = true; |
| { |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnFormsSeen(forms, TimeTicks::FromInternalValue(1)); |
| autofill_manager_->OnDidFillAutofillFormData( |
| form, TimeTicks::FromInternalValue(5)); |
| autofill_manager_->SubmitForm(form, TimeTicks::FromInternalValue(17)); |
| |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.FillDuration.FromLoad.WithAutofill", 16, 1); |
| histogram_tester.ExpectTotalCount( |
| "Autofill.FillDuration.FromLoad.WithoutAutofill", 0); |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.FillDuration.FromInteraction.WithAutofill", 12, 1); |
| histogram_tester.ExpectTotalCount( |
| "Autofill.FillDuration.FromInteraction.WithoutAutofill", 0); |
| |
| // We expected an upload to be triggered when the manager is reset. |
| autofill_manager_->ResetRunLoop(); |
| autofill_manager_->Reset(); |
| autofill_manager_->RunRunLoop(); |
| } |
| |
| // Expect metric to be logged if the user both manually filled some fields |
| // and autofilled others. Messages can arrive out of order, so make sure they |
| // take precedence appropriately. |
| { |
| base::HistogramTester histogram_tester; |
| |
| autofill_manager_->OnFormsSeen(forms, TimeTicks::FromInternalValue(1)); |
| autofill_manager_->OnDidFillAutofillFormData( |
| form, TimeTicks::FromInternalValue(5)); |
| autofill_manager_->OnTextFieldDidChange(form, form.fields.front(), |
| TimeTicks::FromInternalValue(3)); |
| autofill_manager_->SubmitForm(form, TimeTicks::FromInternalValue(17)); |
| |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.FillDuration.FromLoad.WithAutofill", 16, 1); |
| histogram_tester.ExpectTotalCount( |
| "Autofill.FillDuration.FromLoad.WithoutAutofill", 0); |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.FillDuration.FromInteraction.WithAutofill", 14, 1); |
| histogram_tester.ExpectTotalCount( |
| "Autofill.FillDuration.FromInteraction.WithoutAutofill", 0); |
| |
| // We expected an upload to be triggered when the manager is reset. |
| autofill_manager_->ResetRunLoop(); |
| autofill_manager_->Reset(); |
| autofill_manager_->RunRunLoop(); |
| } |
| |
| // Make sure that loading another form doesn't affect metrics from the first |
| // form. |
| { |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnFormsSeen(forms, TimeTicks::FromInternalValue(1)); |
| autofill_manager_->OnFormsSeen(second_forms, |
| TimeTicks::FromInternalValue(3)); |
| autofill_manager_->OnDidFillAutofillFormData( |
| form, TimeTicks::FromInternalValue(5)); |
| autofill_manager_->OnTextFieldDidChange(form, form.fields.front(), |
| TimeTicks::FromInternalValue(3)); |
| autofill_manager_->SubmitForm(form, TimeTicks::FromInternalValue(17)); |
| |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.FillDuration.FromLoad.WithAutofill", 16, 1); |
| histogram_tester.ExpectTotalCount( |
| "Autofill.FillDuration.FromLoad.WithoutAutofill", 0); |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.FillDuration.FromInteraction.WithAutofill", 14, 1); |
| histogram_tester.ExpectTotalCount( |
| "Autofill.FillDuration.FromInteraction.WithoutAutofill", 0); |
| |
| // We expected an upload to be triggered when the manager is reset. |
| autofill_manager_->ResetRunLoop(); |
| autofill_manager_->Reset(); |
| autofill_manager_->RunRunLoop(); |
| } |
| |
| // Make sure that submitting a form that was loaded later will report the |
| // later loading time. |
| { |
| base::HistogramTester histogram_tester; |
| autofill_manager_->OnFormsSeen(forms, TimeTicks::FromInternalValue(1)); |
| autofill_manager_->OnFormsSeen(second_forms, |
| TimeTicks::FromInternalValue(5)); |
| autofill_manager_->SubmitForm(second_form, |
| TimeTicks::FromInternalValue(17)); |
| |
| histogram_tester.ExpectTotalCount( |
| "Autofill.FillDuration.FromLoad.WithAutofill", 0); |
| histogram_tester.ExpectUniqueSample( |
| "Autofill.FillDuration.FromLoad.WithoutAutofill", 12, 1); |
| histogram_tester.ExpectTotalCount( |
| "Autofill.FillDuration.FromInteraction.WithAutofill", 0); |
| histogram_tester.ExpectTotalCount( |
| "Autofill.FillDuration.FromInteraction.WithoutAutofill", 0); |
| |
| autofill_manager_->Reset(); |
| } |
| } |
| |
| // Verify that we correctly log metrics for profile action on form submission. |
| TEST_F(AutofillMetricsTest, ProfileActionOnFormSubmitted) { |
| base::HistogramTester histogram_tester; |
| |
| // Load a fillable form. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| // Create the form's fields. |
| FormFieldData field; |
| test::CreateTestFormField("Name", "name", "", "text", &field); |
| form.fields.push_back(field); |
| test::CreateTestFormField("Email", "email", "", "text", &field); |
| form.fields.push_back(field); |
| test::CreateTestFormField("Phone", "phone", "", "text", &field); |
| form.fields.push_back(field); |
| test::CreateTestFormField("Address", "address", "", "text", &field); |
| form.fields.push_back(field); |
| test::CreateTestFormField("City", "city", "", "text", &field); |
| form.fields.push_back(field); |
| test::CreateTestFormField("Country", "country", "", "text", &field); |
| form.fields.push_back(field); |
| test::CreateTestFormField("State", "state", "", "text", &field); |
| form.fields.push_back(field); |
| test::CreateTestFormField("Zip", "zip", "", "text", &field); |
| form.fields.push_back(field); |
| test::CreateTestFormField("Organization", "organization", "", "text", &field); |
| form.fields.push_back(field); |
| |
| std::vector<FormData> forms(1, form); |
| |
| // Fill second form. |
| FormData second_form = form; |
| std::vector<FormData> second_forms(1, second_form); |
| |
| // Fill a third form. |
| FormData third_form = form; |
| std::vector<FormData> third_forms(1, third_form); |
| |
| // Fill a fourth form. |
| FormData fourth_form = form; |
| std::vector<FormData> fourth_forms(1, fourth_form); |
| |
| // Fill the field values for the first form submission. |
| form.fields[0].value = ASCIIToUTF16("Albert Canuck"); |
| form.fields[1].value = ASCIIToUTF16("can@gmail.com"); |
| form.fields[2].value = ASCIIToUTF16("12345678901"); |
| form.fields[3].value = ASCIIToUTF16("1234 McGill street."); |
| form.fields[4].value = ASCIIToUTF16("Montreal"); |
| form.fields[5].value = ASCIIToUTF16("Canada"); |
| form.fields[6].value = ASCIIToUTF16("Quebec"); |
| form.fields[7].value = ASCIIToUTF16("A1A 1A1"); |
| |
| // Fill the field values for the second form submission (same as first form). |
| second_form.fields = form.fields; |
| |
| // Fill the field values for the third form submission. |
| third_form.fields[0].value = ASCIIToUTF16("Jean-Paul Canuck"); |
| third_form.fields[1].value = ASCIIToUTF16("can2@gmail.com"); |
| third_form.fields[2].value = ASCIIToUTF16(""); |
| third_form.fields[3].value = ASCIIToUTF16("1234 McGill street."); |
| third_form.fields[4].value = ASCIIToUTF16("Montreal"); |
| third_form.fields[5].value = ASCIIToUTF16("Canada"); |
| third_form.fields[6].value = ASCIIToUTF16("Quebec"); |
| third_form.fields[7].value = ASCIIToUTF16("A1A 1A1"); |
| |
| // Fill the field values for the fourth form submission (same as third form |
| // plus phone info). |
| fourth_form.fields = third_form.fields; |
| fourth_form.fields[2].value = ASCIIToUTF16("12345678901"); |
| |
| // Expect to log NEW_PROFILE_CREATED for the metric since a new profile is |
| // submitted. |
| autofill_manager_->OnFormsSeen(forms, TimeTicks::FromInternalValue(1)); |
| autofill_manager_->SubmitForm(form, TimeTicks::FromInternalValue(17)); |
| histogram_tester.ExpectBucketCount("Autofill.ProfileActionOnFormSubmitted", |
| AutofillMetrics::NEW_PROFILE_CREATED, 1); |
| histogram_tester.ExpectBucketCount("Autofill.ProfileActionOnFormSubmitted", |
| AutofillMetrics::EXISTING_PROFILE_USED, 0); |
| histogram_tester.ExpectBucketCount("Autofill.ProfileActionOnFormSubmitted", |
| AutofillMetrics::EXISTING_PROFILE_UPDATED, |
| 0); |
| |
| // Expect to log EXISTING_PROFILE_USED for the metric since the same profile |
| // is submitted. |
| autofill_manager_->OnFormsSeen(second_forms, TimeTicks::FromInternalValue(1)); |
| autofill_manager_->SubmitForm(second_form, TimeTicks::FromInternalValue(17)); |
| histogram_tester.ExpectBucketCount("Autofill.ProfileActionOnFormSubmitted", |
| AutofillMetrics::NEW_PROFILE_CREATED, 1); |
| histogram_tester.ExpectBucketCount("Autofill.ProfileActionOnFormSubmitted", |
| AutofillMetrics::EXISTING_PROFILE_USED, 1); |
| histogram_tester.ExpectBucketCount("Autofill.ProfileActionOnFormSubmitted", |
| AutofillMetrics::EXISTING_PROFILE_UPDATED, |
| 0); |
| |
| // Expect to log NEW_PROFILE_CREATED for the metric since a new profile is |
| // submitted. |
| autofill_manager_->OnFormsSeen(third_forms, TimeTicks::FromInternalValue(1)); |
| autofill_manager_->SubmitForm(third_form, TimeTicks::FromInternalValue(17)); |
| histogram_tester.ExpectBucketCount("Autofill.ProfileActionOnFormSubmitted", |
| AutofillMetrics::NEW_PROFILE_CREATED, 2); |
| histogram_tester.ExpectBucketCount("Autofill.ProfileActionOnFormSubmitted", |
| AutofillMetrics::EXISTING_PROFILE_USED, 1); |
| histogram_tester.ExpectBucketCount("Autofill.ProfileActionOnFormSubmitted", |
| AutofillMetrics::EXISTING_PROFILE_UPDATED, |
| 0); |
| |
| // Expect to log EXISTING_PROFILE_UPDATED for the metric since the profile was |
| // updated. |
| autofill_manager_->OnFormsSeen(fourth_forms, TimeTicks::FromInternalValue(1)); |
| autofill_manager_->SubmitForm(fourth_form, TimeTicks::FromInternalValue(17)); |
| histogram_tester.ExpectBucketCount("Autofill.ProfileActionOnFormSubmitted", |
| AutofillMetrics::NEW_PROFILE_CREATED, 2); |
| histogram_tester.ExpectBucketCount("Autofill.ProfileActionOnFormSubmitted", |
| AutofillMetrics::EXISTING_PROFILE_USED, 1); |
| histogram_tester.ExpectBucketCount("Autofill.ProfileActionOnFormSubmitted", |
| AutofillMetrics::EXISTING_PROFILE_UPDATED, |
| 1); |
| } |
| |
| // Test class that shares setup code for testing ParseQueryResponse. |
| class AutofillMetricsParseQueryResponseTest : public testing::Test { |
| public: |
| void SetUp() override { |
| FormData form; |
| form.origin = GURL("http://foo.com"); |
| FormFieldData field; |
| field.form_control_type = "text"; |
| |
| field.label = ASCIIToUTF16("fullname"); |
| field.name = ASCIIToUTF16("fullname"); |
| form.fields.push_back(field); |
| |
| field.label = ASCIIToUTF16("address"); |
| field.name = ASCIIToUTF16("address"); |
| form.fields.push_back(field); |
| |
| // Checkable fields should be ignored in parsing. |
| FormFieldData checkable_field; |
| checkable_field.label = ASCIIToUTF16("radio_button"); |
| checkable_field.form_control_type = "radio"; |
| checkable_field.check_status = FormFieldData::CHECKABLE_BUT_UNCHECKED; |
| form.fields.push_back(checkable_field); |
| |
| owned_forms_.push_back(base::MakeUnique<FormStructure>(form)); |
| forms_.push_back(owned_forms_.back().get()); |
| |
| field.label = ASCIIToUTF16("email"); |
| field.name = ASCIIToUTF16("email"); |
| form.fields.push_back(field); |
| |
| field.label = ASCIIToUTF16("password"); |
| field.name = ASCIIToUTF16("password"); |
| field.form_control_type = "password"; |
| form.fields.push_back(field); |
| |
| owned_forms_.push_back(base::MakeUnique<FormStructure>(form)); |
| forms_.push_back(owned_forms_.back().get()); |
| } |
| |
| protected: |
| TestRapporServiceImpl rappor_service_; |
| std::vector<std::unique_ptr<FormStructure>> owned_forms_; |
| std::vector<FormStructure*> forms_; |
| }; |
| |
| TEST_F(AutofillMetricsParseQueryResponseTest, ServerHasData) { |
| AutofillQueryResponseContents response; |
| response.add_field()->set_autofill_type(7); |
| response.add_field()->set_autofill_type(30); |
| response.add_field()->set_autofill_type(9); |
| response.add_field()->set_autofill_type(0); |
| |
| std::string response_string; |
| ASSERT_TRUE(response.SerializeToString(&response_string)); |
| |
| base::HistogramTester histogram_tester; |
| FormStructure::ParseQueryResponse(response_string, forms_, &rappor_service_); |
| EXPECT_THAT( |
| histogram_tester.GetAllSamples("Autofill.ServerResponseHasDataForForm"), |
| ElementsAre(Bucket(true, 2))); |
| |
| // No RAPPOR metrics are logged in the case there is server data available for |
| // all forms. |
| EXPECT_EQ(0, rappor_service_.GetReportsCount()); |
| } |
| |
| // If the server returns NO_SERVER_DATA for one of the forms, expect RAPPOR |
| // logging. |
| TEST_F(AutofillMetricsParseQueryResponseTest, OneFormNoServerData) { |
| AutofillQueryResponseContents response; |
| response.add_field()->set_autofill_type(0); |
| response.add_field()->set_autofill_type(0); |
| response.add_field()->set_autofill_type(9); |
| response.add_field()->set_autofill_type(0); |
| |
| std::string response_string; |
| ASSERT_TRUE(response.SerializeToString(&response_string)); |
| |
| base::HistogramTester histogram_tester; |
| FormStructure::ParseQueryResponse(response_string, forms_, &rappor_service_); |
| EXPECT_THAT( |
| histogram_tester.GetAllSamples("Autofill.ServerResponseHasDataForForm"), |
| ElementsAre(Bucket(false, 1), Bucket(true, 1))); |
| |
| EXPECT_EQ(1, rappor_service_.GetReportsCount()); |
| std::string sample; |
| rappor::RapporType type; |
| EXPECT_TRUE(rappor_service_.GetRecordedSampleForMetric( |
| "Autofill.QueryResponseHasNoServerDataForForm", &sample, &type)); |
| EXPECT_EQ("foo.com", sample); |
| EXPECT_EQ(rappor::ETLD_PLUS_ONE_RAPPOR_TYPE, type); |
| } |
| |
| // If the server returns NO_SERVER_DATA for both of the forms, expect RAPPOR |
| // logging. |
| TEST_F(AutofillMetricsParseQueryResponseTest, AllFormsNoServerData) { |
| AutofillQueryResponseContents response; |
| for (int i = 0; i < 4; ++i) { |
| response.add_field()->set_autofill_type(0); |
| } |
| |
| std::string response_string; |
| ASSERT_TRUE(response.SerializeToString(&response_string)); |
| |
| base::HistogramTester histogram_tester; |
| FormStructure::ParseQueryResponse(response_string, forms_, &rappor_service_); |
| EXPECT_THAT( |
| histogram_tester.GetAllSamples("Autofill.ServerResponseHasDataForForm"), |
| ElementsAre(Bucket(false, 2))); |
| |
| // Even though both forms are logging to RAPPOR, there is only one sample for |
| // a given eTLD+1. |
| EXPECT_EQ(1, rappor_service_.GetReportsCount()); |
| std::string sample; |
| rappor::RapporType type; |
| EXPECT_TRUE(rappor_service_.GetRecordedSampleForMetric( |
| "Autofill.QueryResponseHasNoServerDataForForm", &sample, &type)); |
| EXPECT_EQ("foo.com", sample); |
| EXPECT_EQ(rappor::ETLD_PLUS_ONE_RAPPOR_TYPE, type); |
| } |
| |
| // If the server returns NO_SERVER_DATA for only some of the fields, expect no |
| // RAPPOR logging, and expect the UMA metric to say there is data. |
| TEST_F(AutofillMetricsParseQueryResponseTest, PartialNoServerData) { |
| AutofillQueryResponseContents response; |
| response.add_field()->set_autofill_type(0); |
| response.add_field()->set_autofill_type(10); |
| response.add_field()->set_autofill_type(0); |
| response.add_field()->set_autofill_type(11); |
| |
| std::string response_string; |
| ASSERT_TRUE(response.SerializeToString(&response_string)); |
| |
| base::HistogramTester histogram_tester; |
| FormStructure::ParseQueryResponse(response_string, forms_, &rappor_service_); |
| EXPECT_THAT( |
| histogram_tester.GetAllSamples("Autofill.ServerResponseHasDataForForm"), |
| ElementsAre(Bucket(true, 2))); |
| |
| // No RAPPOR metrics are logged in the case there is at least some server data |
| // available for all forms. |
| EXPECT_EQ(0, rappor_service_.GetReportsCount()); |
| } |
| |
| // Test that the Form-Not-Secure warning user action is recorded. |
| TEST_F(AutofillMetricsTest, ShowHttpNotSecureExplanationUserAction) { |
| base::UserActionTester user_action_tester; |
| external_delegate_->DidAcceptSuggestion( |
| ASCIIToUTF16("Test"), POPUP_ITEM_ID_HTTP_NOT_SECURE_WARNING_MESSAGE, 0); |
| EXPECT_EQ(1, user_action_tester.GetActionCount( |
| "Autofill_ShowedHttpNotSecureExplanation")); |
| } |
| |
| // Tests that credit card form submissions are logged specially when the form is |
| // on a non-secure page. |
| TEST_F(AutofillMetricsTest, NonsecureCreditCardForm) { |
| personal_data_->RecreateCreditCards( |
| true /* include_local_credit_card */, |
| false /* include_masked_server_credit_card */, |
| false /* include_full_server_credit_card */); |
| |
| // Set up our form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("http://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| autofill_client_.set_form_origin(form.origin); |
| |
| FormFieldData field; |
| std::vector<ServerFieldType> field_types; |
| test::CreateTestFormField("Name on card", "cc-name", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_NAME_FULL); |
| test::CreateTestFormField("Credit card", "card", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_NUMBER); |
| test::CreateTestFormField("Month", "card_month", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_EXP_MONTH); |
| |
| // Simulate having seen this form on page load. |
| // |form_structure| will be owned by |autofill_manager_|. |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| // Simulate an Autofill query on a credit card field. |
| { |
| base::UserActionTester user_action_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| EXPECT_EQ(1, user_action_tester.GetActionCount( |
| "Autofill_PolledCreditCardSuggestions")); |
| } |
| |
| // Simulate submitting the credit card form. |
| { |
| base::HistogramTester histograms; |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| histograms.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard.OnNonsecurePage", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1); |
| histograms.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1); |
| histograms.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard.WithOnlyLocalData", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1); |
| } |
| } |
| |
| // Tests that credit card form submissions are *not* logged specially when the |
| // form is *not* on a non-secure page. |
| TEST_F(AutofillMetricsTest, |
| NonsecureCreditCardFormMetricsNotRecordedOnSecurePage) { |
| personal_data_->RecreateCreditCards( |
| true /* include_local_credit_card */, |
| false /* include_masked_server_credit_card */, |
| false /* include_full_server_credit_card */); |
| |
| // Set up our form data. |
| FormData form; |
| form.name = ASCIIToUTF16("TestForm"); |
| form.origin = GURL("https://example.com/form.html"); |
| form.action = GURL("http://example.com/submit.html"); |
| |
| FormFieldData field; |
| std::vector<ServerFieldType> field_types; |
| test::CreateTestFormField("Name on card", "cc-name", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_NAME_FULL); |
| test::CreateTestFormField("Credit card", "card", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_NUMBER); |
| test::CreateTestFormField("Month", "card_month", "", "text", &field); |
| form.fields.push_back(field); |
| field_types.push_back(CREDIT_CARD_EXP_MONTH); |
| |
| // Simulate having seen this form on page load. |
| // |form_structure| will be owned by |autofill_manager_|. |
| autofill_manager_->AddSeenForm(form, field_types, field_types); |
| |
| // Simulate an Autofill query on a credit card field. |
| { |
| base::UserActionTester user_action_tester; |
| autofill_manager_->OnQueryFormFieldAutofill(0, form, field, gfx::RectF()); |
| EXPECT_EQ(1, user_action_tester.GetActionCount( |
| "Autofill_PolledCreditCardSuggestions")); |
| } |
| |
| // Simulate submitting the credit card form. |
| { |
| base::HistogramTester histograms; |
| autofill_manager_->SubmitForm(form, TimeTicks::Now()); |
| histograms.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE, 1); |
| histograms.ExpectBucketCount( |
| "Autofill.FormEvents.CreditCard", |
| AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE, 1); |
| // Check that the nonsecure histogram was not recorded. ExpectBucketCount() |
| // can't be used here because it expects the histogram to exist. |
| EXPECT_EQ( |
| 0, histograms.GetTotalCountsForPrefix("Autofill.FormEvents.CreditCard") |
| ["Autofill.FormEvents.CreditCard.OnNonsecurePage"]); |
| } |
| } |
| |
| // Tests that logging CardUploadDecision UKM works as expected. |
| TEST_F(AutofillMetricsTest, RecordCardUploadDecisionMetric) { |
| EnableUkmLogging(); |
| ukm::UkmServiceTestingHarness ukm_service_test_harness; |
| GURL url("https://www.google.com"); |
| int upload_decision = 1; |
| std::map<std::string, int> metrics = { |
| {internal::kUKMCardUploadDecisionMetricName, upload_decision}}; |
| |
| EXPECT_TRUE(AutofillMetrics::LogUkm( |
| ukm_service_test_harness.test_ukm_service(), url, |
| internal::kUKMCardUploadDecisionEntryName, metrics)); |
| |
| // Make sure that the UKM was logged correctly. |
| ukm::TestUkmService* ukm_service = |
| ukm_service_test_harness.test_ukm_service(); |
| |
| ASSERT_EQ(1U, ukm_service->sources_count()); |
| const ukm::UkmSource* source = |
| ukm_service->GetSourceForUrl(url.spec().c_str()); |
| EXPECT_EQ(url.spec(), source->url().spec()); |
| |
| ASSERT_EQ(1U, ukm_service->entries_count()); |
| const ukm::UkmEntry* entry = ukm_service->GetEntry(0); |
| EXPECT_EQ(source->id(), entry->source_id()); |
| |
| // Make sure that a card upload decision entry was logged. |
| ukm::Entry entry_proto; |
| entry->PopulateProto(&entry_proto); |
| EXPECT_EQ(source->id(), entry_proto.source_id()); |
| EXPECT_EQ(base::HashMetricName(internal::kUKMCardUploadDecisionEntryName), |
| entry_proto.event_hash()); |
| EXPECT_EQ(1, entry_proto.metrics_size()); |
| |
| // Make sure that the correct upload decision was logged. |
| const ukm::Entry_Metric* metric = FindMetric( |
| internal::kUKMCardUploadDecisionMetricName, entry_proto.metrics()); |
| ASSERT_NE(nullptr, metric); |
| EXPECT_EQ(upload_decision, metric->value()); |
| } |
| |
| // Tests that logging DeveloperEngagement UKM works as expected. |
| TEST_F(AutofillMetricsTest, RecordDeveloperEngagementMetric) { |
| EnableUkmLogging(); |
| ukm::UkmServiceTestingHarness ukm_service_test_harness; |
| GURL url("https://www.google.com"); |
| int form_structure_metric = 1; |
| std::map<std::string, int> metrics = { |
| {internal::kUKMDeveloperEngagementMetricName, form_structure_metric}}; |
| |
| EXPECT_TRUE(AutofillMetrics::LogUkm( |
| ukm_service_test_harness.test_ukm_service(), url, |
| internal::kUKMDeveloperEngagementEntryName, metrics)); |
| |
| // Make sure that the UKM was logged correctly. |
| ukm::TestUkmService* ukm_service = |
| ukm_service_test_harness.test_ukm_service(); |
| |
| ASSERT_EQ(1U, ukm_service->sources_count()); |
| const ukm::UkmSource* source = |
| ukm_service->GetSourceForUrl(url.spec().c_str()); |
| EXPECT_EQ(url.spec(), source->url().spec()); |
| |
| ASSERT_EQ(1U, ukm_service->entries_count()); |
| const ukm::UkmEntry* entry = ukm_service->GetEntry(0); |
| EXPECT_EQ(source->id(), entry->source_id()); |
| |
| // Make sure that a developer engagement entry was logged. |
| 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()); |
| EXPECT_EQ(1, entry_proto.metrics_size()); |
| |
| // Make sure that the correct developer engagement metric was logged. |
| const ukm::Entry_Metric* metric = FindMetric( |
| internal::kUKMDeveloperEngagementMetricName, entry_proto.metrics()); |
| ASSERT_NE(nullptr, metric); |
| EXPECT_EQ(form_structure_metric, metric->value()); |
| } |
| |
| // Tests that no UKM is logged when the URL is not valid. |
| TEST_F(AutofillMetricsTest, RecordCardUploadDecisionMetric_InvalidUrl) { |
| EnableUkmLogging(); |
| ukm::UkmServiceTestingHarness ukm_service_test_harness; |
| GURL url(""); |
| std::map<std::string, int> metrics = {{"metric", 1}}; |
| |
| EXPECT_FALSE(AutofillMetrics::LogUkm( |
| ukm_service_test_harness.test_ukm_service(), url, "test_ukm", metrics)); |
| EXPECT_EQ(0U, ukm_service_test_harness.test_ukm_service()->sources_count()); |
| } |
| |
| // Tests that no UKM is logged when the metrics map is empty. |
| TEST_F(AutofillMetricsTest, RecordCardUploadDecisionMetric_NoMetrics) { |
| EnableUkmLogging(); |
| ukm::UkmServiceTestingHarness ukm_service_test_harness; |
| GURL url("https://www.google.com"); |
| std::map<std::string, int> metrics; |
| |
| EXPECT_FALSE(AutofillMetrics::LogUkm( |
| ukm_service_test_harness.test_ukm_service(), url, "test_ukm", metrics)); |
| EXPECT_EQ(0U, ukm_service_test_harness.test_ukm_service()->sources_count()); |
| } |
| |
| // Tests that no UKM is logged when the ukm service is null. |
| 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}}; |
| |
| EXPECT_FALSE(AutofillMetrics::LogUkm(nullptr, url, "test_ukm", metrics)); |
| ASSERT_EQ(0U, ukm_service_test_harness.test_ukm_service()->sources_count()); |
| } |
| |
| // Tests that no UKM is logged when the ukm logging feature is disabled. |
| 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}}; |
| |
| EXPECT_FALSE(AutofillMetrics::LogUkm( |
| ukm_service_test_harness.test_ukm_service(), url, "test_ukm", metrics)); |
| EXPECT_EQ(0U, ukm_service_test_harness.test_ukm_service()->sources_count()); |
| } |
| |
| } // namespace autofill |