blob: 76a953d18ad80d5e5ce4af8a007ac0d9fd00c8a2 [file] [log] [blame]
// Copyright (c) 2011 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 <vector>
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/string16.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/autofill/autofill_cc_infobar_delegate.h"
#include "chrome/browser/autofill/autofill_common_test.h"
#include "chrome/browser/autofill/autofill_manager.h"
#include "chrome/browser/autofill/autofill_metrics.h"
#include "chrome/browser/autofill/personal_data_manager.h"
#include "chrome/browser/webdata/web_data_service.h"
#include "chrome/browser/ui/tab_contents/test_tab_contents_wrapper.h"
#include "content/browser/browser_thread.h"
#include "content/browser/tab_contents/test_tab_contents.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webkit/glue/form_data.h"
#include "webkit/glue/form_field.h"
using webkit_glue::FormData;
using webkit_glue::FormField;
namespace {
class MockAutofillMetrics : public AutofillMetrics {
public:
MockAutofillMetrics() {}
MOCK_CONST_METHOD1(LogCreditCardInfoBarMetric, void(InfoBarMetric metric));
MOCK_CONST_METHOD3(LogHeuristicTypePrediction,
void(FieldTypeQualityMetric metric,
AutofillFieldType field_type,
const std::string& experiment_id));
MOCK_CONST_METHOD3(LogOverallTypePrediction,
void(FieldTypeQualityMetric metric,
AutofillFieldType field_type,
const std::string& experiment_id));
MOCK_CONST_METHOD3(LogServerTypePrediction,
void(FieldTypeQualityMetric metric,
AutofillFieldType field_type,
const std::string& experiment_id));
MOCK_CONST_METHOD2(LogQualityMetric, void(QualityMetric metric,
const std::string& experiment_id));
MOCK_CONST_METHOD1(LogServerQueryMetric, void(ServerQueryMetric metric));
MOCK_CONST_METHOD1(LogUserHappinessMetric, void(UserHappinessMetric metric));
MOCK_CONST_METHOD1(LogIsAutofillEnabledAtPageLoad, void(bool enabled));
MOCK_CONST_METHOD1(LogIsAutofillEnabledAtStartup, void(bool enabled));
MOCK_CONST_METHOD1(LogStoredProfileCount, void(size_t num_profiles));
MOCK_CONST_METHOD1(LogAddressSuggestionsCount, void(size_t num_suggestions));
MOCK_CONST_METHOD1(LogServerExperimentIdForQuery,
void(const std::string& experiment_id));
MOCK_CONST_METHOD1(LogServerExperimentIdForUpload,
void(const std::string& experiment_id));
private:
DISALLOW_COPY_AND_ASSIGN(MockAutofillMetrics);
};
class TestPersonalDataManager : public PersonalDataManager {
public:
TestPersonalDataManager() : autofill_enabled_(true) {
set_metric_logger(new MockAutofillMetrics);
CreateTestAutofillProfiles(&web_profiles_);
}
// Overridden to avoid a trip to the database. This should be a no-op except
// for the side-effect of logging the profile count.
virtual void LoadProfiles() OVERRIDE {
std::vector<AutofillProfile*> profiles;
web_profiles_.release(&profiles);
WDResult<std::vector<AutofillProfile*> > result(AUTOFILL_PROFILES_RESULT,
profiles);
ReceiveLoadedProfiles(0, &result);
}
// Overridden to avoid a trip to the database.
virtual void LoadCreditCards() OVERRIDE {}
const MockAutofillMetrics* metric_logger() const {
return static_cast<const MockAutofillMetrics*>(
PersonalDataManager::metric_logger());
}
void set_autofill_enabled(bool autofill_enabled) {
autofill_enabled_ = autofill_enabled;
}
virtual bool IsAutofillEnabled() const OVERRIDE {
return autofill_enabled_;
}
MOCK_METHOD1(SaveImportedCreditCard,
void(const CreditCard& imported_credit_card));
private:
void CreateTestAutofillProfiles(ScopedVector<AutofillProfile>* profiles) {
AutofillProfile* profile = new AutofillProfile;
autofill_test::SetProfileInfo(profile, "Elvis", "Aaron",
"Presley", "theking@gmail.com", "RCA",
"3734 Elvis Presley Blvd.", "Apt. 10",
"Memphis", "Tennessee", "38116", "USA",
"12345678901", "");
profile->set_guid("00000000-0000-0000-0000-000000000001");
profiles->push_back(profile);
profile = new AutofillProfile;
autofill_test::SetProfileInfo(profile, "Charles", "Hardin",
"Holley", "buddy@gmail.com", "Decca",
"123 Apple St.", "unit 6", "Lubbock",
"Texas", "79401", "USA", "2345678901",
"");
profile->set_guid("00000000-0000-0000-0000-000000000002");
profiles->push_back(profile);
}
bool autofill_enabled_;
DISALLOW_COPY_AND_ASSIGN(TestPersonalDataManager);
};
class TestFormStructure : public FormStructure {
public:
explicit TestFormStructure(const FormData& form) : FormStructure(form) {}
virtual ~TestFormStructure() {}
void SetFieldTypes(const std::vector<AutofillFieldType>& heuristic_types,
const std::vector<AutofillFieldType>& 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* field = (*fields())[i];
ASSERT_TRUE(field);
field->set_heuristic_type(heuristic_types[i]);
field->set_server_type(server_types[i]);
}
UpdateAutofillCount();
}
virtual std::string server_experiment_id() const OVERRIDE {
return server_experiment_id_;
}
void set_server_experiment_id(const std::string& server_experiment_id) {
server_experiment_id_ = server_experiment_id;
}
private:
std::string server_experiment_id_;
DISALLOW_COPY_AND_ASSIGN(TestFormStructure);
};
class TestAutofillManager : public AutofillManager {
public:
TestAutofillManager(TabContentsWrapper* tab_contents,
TestPersonalDataManager* personal_manager)
: AutofillManager(tab_contents, personal_manager),
autofill_enabled_(true) {
set_metric_logger(new MockAutofillMetrics);
}
virtual ~TestAutofillManager() {}
virtual bool IsAutofillEnabled() const { return autofill_enabled_; }
void set_autofill_enabled(bool autofill_enabled) {
autofill_enabled_ = autofill_enabled;
}
const MockAutofillMetrics* metric_logger() const {
return static_cast<const MockAutofillMetrics*>(
AutofillManager::metric_logger());
}
void AddSeenForm(const FormData& form,
const std::vector<AutofillFieldType>& heuristic_types,
const std::vector<AutofillFieldType>& server_types,
const std::string& experiment_id) {
FormData empty_form = form;
for (size_t i = 0; i < empty_form.fields.size(); ++i) {
empty_form.fields[i].value = string16();
}
// |form_structure| will be owned by |form_structures()|.
TestFormStructure* form_structure = new TestFormStructure(empty_form);
form_structure->SetFieldTypes(heuristic_types, server_types);
form_structure->set_server_experiment_id(experiment_id);
form_structures()->push_back(form_structure);
}
private:
bool autofill_enabled_;
DISALLOW_COPY_AND_ASSIGN(TestAutofillManager);
};
} // namespace
class AutofillMetricsTest : public TabContentsWrapperTestHarness {
public:
AutofillMetricsTest();
virtual ~AutofillMetricsTest();
virtual void SetUp();
protected:
AutofillCCInfoBarDelegate* CreateDelegate(MockAutofillMetrics* metric_logger,
CreditCard** created_card);
scoped_ptr<TestAutofillManager> autofill_manager_;
scoped_refptr<TestPersonalDataManager> test_personal_data_;
private:
BrowserThread browser_thread_;
DISALLOW_COPY_AND_ASSIGN(AutofillMetricsTest);
};
AutofillMetricsTest::AutofillMetricsTest()
: TabContentsWrapperTestHarness(),
browser_thread_(BrowserThread::UI, &message_loop_) {
}
AutofillMetricsTest::~AutofillMetricsTest() {
// Order of destruction is important as AutofillManager relies on
// PersonalDataManager to be around when it gets destroyed.
autofill_manager_.reset(NULL);
test_personal_data_ = NULL;
}
void AutofillMetricsTest::SetUp() {
TabContentsWrapperTestHarness::SetUp();
test_personal_data_ = new TestPersonalDataManager();
autofill_manager_.reset(new TestAutofillManager(contents_wrapper(),
test_personal_data_.get()));
}
AutofillCCInfoBarDelegate* AutofillMetricsTest::CreateDelegate(
MockAutofillMetrics* metric_logger,
CreditCard** created_card) {
EXPECT_CALL(*metric_logger,
LogCreditCardInfoBarMetric(AutofillMetrics::INFOBAR_SHOWN));
// The delegate created below will take ownership of this object.
CreditCard* credit_card = new CreditCard();
if (created_card)
*created_card = credit_card;
return new AutofillCCInfoBarDelegate(contents(), credit_card,
test_personal_data_.get(), metric_logger);
}
// Test that we log quality metrics appropriately.
TEST_F(AutofillMetricsTest, QualityMetrics) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
form.method = ASCIIToUTF16("POST");
form.origin = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.user_submitted = true;
std::vector<AutofillFieldType> heuristic_types, server_types;
FormField field;
autofill_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);
autofill_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);
autofill_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);
autofill_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);
autofill_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);
autofill_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_WHOLE_NUMBER);
// Simulate having seen this form on page load.
autofill_manager_->AddSeenForm(form, heuristic_types, server_types,
std::string());
// Establish our expectations.
::testing::InSequence dummy;
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogServerExperimentIdForUpload(std::string()));
// Autofilled field
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED,
std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogHeuristicTypePrediction(AutofillMetrics::TYPE_MATCH,
NAME_FULL, std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogServerTypePrediction(AutofillMetrics::TYPE_MISMATCH,
NAME_FULL, std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogOverallTypePrediction(AutofillMetrics::TYPE_MISMATCH,
NAME_FULL, std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_AUTOFILLED,
std::string()));
// Non-autofilled field for which we had data
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED,
std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogHeuristicTypePrediction(AutofillMetrics::TYPE_MISMATCH,
EMAIL_ADDRESS, std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogServerTypePrediction(AutofillMetrics::TYPE_MATCH,
EMAIL_ADDRESS, std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogOverallTypePrediction(AutofillMetrics::TYPE_MATCH,
EMAIL_ADDRESS, std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_NOT_AUTOFILLED,
std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(
AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_MISMATCH,
std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(
AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MATCH,
std::string()));
// Empty field
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED,
std::string()));
// Unknown field
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED,
std::string()));
// <select> field
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED,
std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogHeuristicTypePrediction(AutofillMetrics::TYPE_UNKNOWN,
ADDRESS_HOME_COUNTRY, std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogServerTypePrediction(AutofillMetrics::TYPE_UNKNOWN,
ADDRESS_HOME_COUNTRY, std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogOverallTypePrediction(AutofillMetrics::TYPE_UNKNOWN,
ADDRESS_HOME_COUNTRY, std::string()));
// Phone field
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED,
std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogHeuristicTypePrediction(AutofillMetrics::TYPE_MATCH,
PHONE_HOME_WHOLE_NUMBER, std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogServerTypePrediction(AutofillMetrics::TYPE_MATCH,
PHONE_HOME_WHOLE_NUMBER, std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogOverallTypePrediction(AutofillMetrics::TYPE_MATCH,
PHONE_HOME_WHOLE_NUMBER, std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_AUTOFILLED,
std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogUserHappinessMetric(
AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_SOME));
// Simulate form submission.
EXPECT_NO_FATAL_FAILURE(autofill_manager_->OnFormSubmitted(form));
}
// Test that we log the appropriate additional metrics when Autofill failed.
TEST_F(AutofillMetricsTest, QualityMetricsForFailure) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
form.method = ASCIIToUTF16("POST");
form.origin = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.user_submitted = true;
struct {
const char* label;
const char* name;
const char* value;
AutofillFieldType heuristic_type;
AutofillFieldType server_type;
AutofillMetrics::QualityMetric heuristic_metric;
AutofillMetrics::QualityMetric server_metric;
} failure_cases[] = {
{
"Heuristics unknown, server unknown", "0,0", "Elvis",
UNKNOWN_TYPE, NO_SERVER_DATA,
AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_UNKNOWN,
AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_UNKNOWN
},
{
"Heuristics match, server unknown", "1,0", "Aaron",
NAME_MIDDLE, NO_SERVER_DATA,
AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_MATCH,
AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_UNKNOWN
},
{
"Heuristics mismatch, server unknown", "2,0", "Presley",
PHONE_HOME_NUMBER, NO_SERVER_DATA,
AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_MISMATCH,
AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_UNKNOWN
},
{
"Heuristics unknown, server match", "0,1", "theking@gmail.com",
UNKNOWN_TYPE, EMAIL_ADDRESS,
AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_UNKNOWN,
AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MATCH
},
{
"Heuristics match, server match", "1,1", "3734 Elvis Presley Blvd.",
ADDRESS_HOME_LINE1, ADDRESS_HOME_LINE1,
AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_MATCH,
AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MATCH
},
{
"Heuristics mismatch, server match", "2,1", "Apt. 10",
PHONE_HOME_NUMBER, ADDRESS_HOME_LINE2,
AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_MISMATCH,
AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MATCH
},
{
"Heuristics unknown, server mismatch", "0,2", "Memphis",
UNKNOWN_TYPE, PHONE_HOME_NUMBER,
AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_UNKNOWN,
AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MISMATCH
},
{
"Heuristics match, server mismatch", "1,2", "Tennessee",
ADDRESS_HOME_STATE, PHONE_HOME_NUMBER,
AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_MATCH,
AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MISMATCH
},
{
"Heuristics mismatch, server mismatch", "2,2", "38116",
PHONE_HOME_NUMBER, PHONE_HOME_NUMBER,
AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_MISMATCH,
AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MISMATCH
}
};
std::vector<AutofillFieldType> heuristic_types, server_types;
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(failure_cases); ++i) {
FormField field;
autofill_test::CreateTestFormField(failure_cases[i].label,
failure_cases[i].name,
failure_cases[i].value, "text", &field);
form.fields.push_back(field);
heuristic_types.push_back(failure_cases[i].heuristic_type);
server_types.push_back(failure_cases[i].server_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,
std::string());
// Establish our expectations.
::testing::FLAGS_gmock_verbose = "error";
::testing::InSequence dummy;
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogServerExperimentIdForUpload(std::string()));
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(failure_cases); ++i) {
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED,
std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_NOT_AUTOFILLED,
std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(failure_cases[i].heuristic_metric,
std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(failure_cases[i].server_metric,
std::string()));
}
// Simulate form submission.
EXPECT_NO_FATAL_FAILURE(autofill_manager_->OnFormSubmitted(form));
}
// 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.method = ASCIIToUTF16("POST");
form.origin = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.user_submitted = true;
std::vector<AutofillFieldType> heuristic_types, server_types;
FormField field;
autofill_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);
autofill_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);
autofill_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);
autofill_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,
std::string());
// Add a field and re-arrange the remaining form fields before submitting.
std::vector<FormField> cached_fields = form.fields;
form.fields.clear();
autofill_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]);
// Establish our expectations.
::testing::InSequence dummy;
// New field
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogServerExperimentIdForUpload(std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED,
std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogHeuristicTypePrediction(AutofillMetrics::TYPE_UNKNOWN,
ADDRESS_HOME_STATE, std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogServerTypePrediction(AutofillMetrics::TYPE_UNKNOWN,
ADDRESS_HOME_STATE, std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogOverallTypePrediction(AutofillMetrics::TYPE_UNKNOWN,
ADDRESS_HOME_STATE, std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_NOT_AUTOFILLED,
std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(
AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_UNKNOWN,
std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(
AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_UNKNOWN,
std::string()));
// Only heuristics match
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED,
std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogHeuristicTypePrediction(AutofillMetrics::TYPE_MATCH,
ADDRESS_HOME_CITY, std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogServerTypePrediction(AutofillMetrics::TYPE_MISMATCH,
ADDRESS_HOME_CITY, std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogOverallTypePrediction(AutofillMetrics::TYPE_MISMATCH,
ADDRESS_HOME_CITY, std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_NOT_AUTOFILLED,
std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(
AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_MATCH,
std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(
AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MISMATCH,
std::string()));
// Both mismatch
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED,
std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogHeuristicTypePrediction(AutofillMetrics::TYPE_MISMATCH,
EMAIL_ADDRESS, std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogServerTypePrediction(AutofillMetrics::TYPE_MISMATCH,
EMAIL_ADDRESS, std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogOverallTypePrediction(AutofillMetrics::TYPE_MISMATCH,
EMAIL_ADDRESS, std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_NOT_AUTOFILLED,
std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(
AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_MISMATCH,
std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(
AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MISMATCH,
std::string()));
// Unknown
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED,
std::string()));
// Both match
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED,
std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogHeuristicTypePrediction(AutofillMetrics::TYPE_MATCH,
NAME_FULL, std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogServerTypePrediction(AutofillMetrics::TYPE_MATCH,
NAME_FULL, std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogOverallTypePrediction(AutofillMetrics::TYPE_MATCH,
NAME_FULL, std::string()));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_AUTOFILLED,
std::string()));
// Simulate form submission.
EXPECT_NO_FATAL_FAILURE(autofill_manager_->OnFormSubmitted(form));
}
// Test that we don't log quality metrics for non-autofillable forms.
TEST_F(AutofillMetricsTest, NoQualityMetricsForNonAutofillableForms) {
// Forms must include at least three fields to be auto-fillable.
FormData form;
form.name = ASCIIToUTF16("TestForm");
form.method = ASCIIToUTF16("POST");
form.origin = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.user_submitted = true;
FormField field;
autofill_test::CreateTestFormField(
"Autofilled", "autofilled", "Elvis Presley", "text", &field);
field.is_autofilled = true;
form.fields.push_back(field);
autofill_test::CreateTestFormField(
"Autofill Failed", "autofillfailed", "buddy@gmail.com", "text", &field);
form.fields.push_back(field);
// Simulate form submission.
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED,
std::string())).Times(0);
EXPECT_NO_FATAL_FAILURE(autofill_manager_->OnFormSubmitted(form));
// Search forms are not auto-fillable.
form.action = GURL("http://example.com/search?q=Elvis%20Presley");
autofill_test::CreateTestFormField(
"Empty", "empty", "", "text", &field);
form.fields.push_back(field);
// Simulate form submission.
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED,
std::string())).Times(0);
EXPECT_NO_FATAL_FAILURE(autofill_manager_->OnFormSubmitted(form));
}
// Test that we recored the experiment id appropriately.
TEST_F(AutofillMetricsTest, QualityMetricsWithExperimentId) {
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
form.method = ASCIIToUTF16("POST");
form.origin = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.user_submitted = true;
std::vector<AutofillFieldType> heuristic_types, server_types;
FormField field;
autofill_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);
autofill_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);
autofill_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);
autofill_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);
autofill_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);
const std::string experiment_id = "ThatOughtaDoIt";
// Simulate having seen this form on page load.
// |form_structure| will be owned by |autofill_manager_|.
autofill_manager_->AddSeenForm(form, heuristic_types, server_types,
experiment_id);
// Establish our expectations.
::testing::InSequence dummy;
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogServerExperimentIdForUpload(experiment_id));
// Autofilled field
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED,
experiment_id));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogHeuristicTypePrediction(AutofillMetrics::TYPE_MATCH,
NAME_FULL, experiment_id));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogServerTypePrediction(AutofillMetrics::TYPE_MISMATCH,
NAME_FULL, experiment_id));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogOverallTypePrediction(AutofillMetrics::TYPE_MISMATCH,
NAME_FULL, experiment_id));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_AUTOFILLED,
experiment_id));
// Non-autofilled field for which we had data
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED,
experiment_id));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogHeuristicTypePrediction(AutofillMetrics::TYPE_MISMATCH,
EMAIL_ADDRESS, experiment_id));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogServerTypePrediction(AutofillMetrics::TYPE_MATCH,
EMAIL_ADDRESS, experiment_id));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogOverallTypePrediction(AutofillMetrics::TYPE_MATCH,
EMAIL_ADDRESS, experiment_id));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_NOT_AUTOFILLED,
experiment_id));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(
AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_MISMATCH,
experiment_id));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(
AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MATCH,
experiment_id));
// Empty field
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED,
experiment_id));
// Unknown field
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED,
experiment_id));
// <select> field
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED,
experiment_id));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogHeuristicTypePrediction(AutofillMetrics::TYPE_UNKNOWN,
ADDRESS_HOME_COUNTRY, experiment_id));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogServerTypePrediction(AutofillMetrics::TYPE_UNKNOWN,
ADDRESS_HOME_COUNTRY, experiment_id));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogOverallTypePrediction(AutofillMetrics::TYPE_UNKNOWN,
ADDRESS_HOME_COUNTRY, experiment_id));
// Simulate form submission.
EXPECT_NO_FATAL_FAILURE(autofill_manager_->OnFormSubmitted(form));
}
// Test that the profile count is logged correctly.
TEST_F(AutofillMetricsTest, StoredProfileCount) {
// The metric should be logged when the profiles are first loaded.
EXPECT_CALL(*test_personal_data_->metric_logger(),
LogStoredProfileCount(2)).Times(1);
test_personal_data_->LoadProfiles();
// The metric should only be logged once.
EXPECT_CALL(*test_personal_data_->metric_logger(),
LogStoredProfileCount(::testing::_)).Times(0);
test_personal_data_->LoadProfiles();
}
// Test that we correctly log whether Autofill is enabled.
TEST_F(AutofillMetricsTest, AutofillIsEnabledAtStartup) {
test_personal_data_->set_autofill_enabled(true);
EXPECT_CALL(*test_personal_data_->metric_logger(),
LogIsAutofillEnabledAtStartup(true)).Times(1);
test_personal_data_->Init(NULL);
test_personal_data_->set_autofill_enabled(false);
EXPECT_CALL(*test_personal_data_->metric_logger(),
LogIsAutofillEnabledAtStartup(false)).Times(1);
test_personal_data_->Init(NULL);
}
// 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.method = ASCIIToUTF16("POST");
form.origin = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.user_submitted = true;
FormField field;
std::vector<AutofillFieldType> field_types;
autofill_test::CreateTestFormField("Name", "name", "", "text", &field);
form.fields.push_back(field);
field_types.push_back(NAME_FULL);
autofill_test::CreateTestFormField("Email", "email", "", "email", &field);
form.fields.push_back(field);
field_types.push_back(EMAIL_ADDRESS);
autofill_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,
std::string());
// Establish our expectations.
::testing::FLAGS_gmock_verbose = "error";
::testing::InSequence dummy;
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogAddressSuggestionsCount(2)).Times(1);
// Simulate activating the autofill popup for the phone field.
autofill_manager_->OnQueryFormFieldAutofill(0, form, field);
// 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.
autofill_test::CreateTestFormField("Email", "email", "b", "email", &field);
autofill_manager_->OnQueryFormFieldAutofill(0, form, field);
// Reset the autofill manager state.
autofill_manager_->Reset();
autofill_manager_->AddSeenForm(form, field_types, field_types,
std::string());
// Establish our expectations.
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogAddressSuggestionsCount(1)).Times(1);
// Simulate activating the autofill popup for the email field after typing.
autofill_manager_->OnQueryFormFieldAutofill(0, form, field);
// Reset the autofill manager state again.
autofill_manager_->Reset();
autofill_manager_->AddSeenForm(form, field_types, field_types,
std::string());
// Establish our expectations.
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogAddressSuggestionsCount(::testing::_)).Times(0);
// Simulate activating the autofill popup for the email field after typing.
form.fields[0].is_autofilled = true;
autofill_manager_->OnQueryFormFieldAutofill(0, form, field);
}
// Test that we log whether Autofill is enabled when filling a form.
TEST_F(AutofillMetricsTest, AutofillIsEnabledAtPageLoad) {
// Establish our expectations.
::testing::FLAGS_gmock_verbose = "error";
::testing::InSequence dummy;
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogIsAutofillEnabledAtPageLoad(true)).Times(1);
autofill_manager_->set_autofill_enabled(true);
autofill_manager_->OnFormsSeen(std::vector<FormData>());
// Reset the autofill manager state.
autofill_manager_->Reset();
// Establish our expectations.
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogIsAutofillEnabledAtPageLoad(false)).Times(1);
autofill_manager_->set_autofill_enabled(false);
autofill_manager_->OnFormsSeen(std::vector<FormData>());
}
// Test that credit card infobar metrics are logged correctly.
TEST_F(AutofillMetricsTest, CreditCardInfoBar) {
MockAutofillMetrics metric_logger;
::testing::InSequence dummy;
// Accept the infobar.
{
CreditCard* credit_card;
scoped_ptr<InfoBarDelegate> infobar(CreateDelegate(&metric_logger,
&credit_card));
EXPECT_CALL(*test_personal_data_.get(),
SaveImportedCreditCard(*credit_card));
EXPECT_CALL(metric_logger,
LogCreditCardInfoBarMetric(AutofillMetrics::INFOBAR_ACCEPTED)).Times(1);
EXPECT_CALL(metric_logger,
LogCreditCardInfoBarMetric(AutofillMetrics::INFOBAR_IGNORED)).Times(0);
EXPECT_TRUE(static_cast<ConfirmInfoBarDelegate*>(infobar.get())->Accept());
}
// Cancel the infobar.
{
scoped_ptr<InfoBarDelegate> infobar(CreateDelegate(&metric_logger, NULL));
EXPECT_CALL(metric_logger,
LogCreditCardInfoBarMetric(AutofillMetrics::INFOBAR_DENIED)).Times(1);
EXPECT_CALL(metric_logger,
LogCreditCardInfoBarMetric(AutofillMetrics::INFOBAR_IGNORED)).Times(0);
EXPECT_TRUE(static_cast<ConfirmInfoBarDelegate*>(infobar.get())->Cancel());
}
// Dismiss the infobar.
{
scoped_ptr<InfoBarDelegate> infobar(CreateDelegate(&metric_logger, NULL));
EXPECT_CALL(metric_logger,
LogCreditCardInfoBarMetric(AutofillMetrics::INFOBAR_DENIED)).Times(1);
EXPECT_CALL(metric_logger,
LogCreditCardInfoBarMetric(AutofillMetrics::INFOBAR_IGNORED)).Times(0);
infobar->InfoBarDismissed();
}
// Ignore the infobar.
{
scoped_ptr<InfoBarDelegate> infobar(CreateDelegate(&metric_logger, NULL));
EXPECT_CALL(metric_logger,
LogCreditCardInfoBarMetric(AutofillMetrics::INFOBAR_IGNORED)).Times(1);
}
}
// Test that server query response experiment id metrics are logged correctly.
TEST_F(AutofillMetricsTest, ServerQueryExperimentIdForQuery) {
MockAutofillMetrics metric_logger;
::testing::InSequence dummy;
// No experiment specified.
EXPECT_CALL(metric_logger,
LogServerQueryMetric(AutofillMetrics::QUERY_RESPONSE_RECEIVED));
EXPECT_CALL(metric_logger,
LogServerQueryMetric(AutofillMetrics::QUERY_RESPONSE_PARSED));
EXPECT_CALL(metric_logger,
LogServerExperimentIdForQuery(std::string()));
EXPECT_CALL(metric_logger,
LogServerQueryMetric(
AutofillMetrics::QUERY_RESPONSE_MATCHED_LOCAL_HEURISTICS));
FormStructure::ParseQueryResponse(
"<autofillqueryresponse></autofillqueryresponse>",
std::vector<FormStructure*>(), metric_logger);
// Experiment "ar1" specified.
EXPECT_CALL(metric_logger,
LogServerQueryMetric(AutofillMetrics::QUERY_RESPONSE_RECEIVED));
EXPECT_CALL(metric_logger,
LogServerQueryMetric(AutofillMetrics::QUERY_RESPONSE_PARSED));
EXPECT_CALL(metric_logger,
LogServerExperimentIdForQuery("ar1"));
EXPECT_CALL(metric_logger,
LogServerQueryMetric(
AutofillMetrics::QUERY_RESPONSE_MATCHED_LOCAL_HEURISTICS));
FormStructure::ParseQueryResponse(
"<autofillqueryresponse experimentid=\"ar1\"></autofillqueryresponse>",
std::vector<FormStructure*>(), metric_logger);
}
// Verify that we correctly log user happiness metrics dealing with form loading
// and form submission.
TEST_F(AutofillMetricsTest, UserHappinessFormLoadAndSubmission) {
// Start with a form with insufficiently many fields.
FormData form;
form.name = ASCIIToUTF16("TestForm");
form.method = ASCIIToUTF16("POST");
form.origin = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.user_submitted = true;
FormField field;
autofill_test::CreateTestFormField("Name", "name", "", "text", &field);
form.fields.push_back(field);
autofill_test::CreateTestFormField("Email", "email", "", "text", &field);
form.fields.push_back(field);
std::vector<FormData> forms(1, form);
// Expect no notifications when the form is first seen.
{
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogUserHappinessMetric(AutofillMetrics::FORMS_LOADED)).Times(0);
autofill_manager_->OnFormsSeen(forms);
}
// Expect no notifications when the form is submitted.
{
EXPECT_CALL(
*autofill_manager_->metric_logger(),
LogUserHappinessMetric(
AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_ALL)).Times(0);
EXPECT_CALL(
*autofill_manager_->metric_logger(),
LogUserHappinessMetric(
AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_SOME)).Times(0);
EXPECT_CALL(
*autofill_manager_->metric_logger(),
LogUserHappinessMetric(
AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_NONE)).Times(0);
EXPECT_CALL(
*autofill_manager_->metric_logger(),
LogUserHappinessMetric(
AutofillMetrics::SUBMITTED_NON_FILLABLE_FORM)).Times(0);
autofill_manager_->OnFormSubmitted(form);
}
// Add more fields to the form.
autofill_test::CreateTestFormField("Phone", "phone", "", "text", &field);
form.fields.push_back(field);
autofill_test::CreateTestFormField("Unknown", "unknown", "", "text", &field);
form.fields.push_back(field);
forms.front() = form;
// Expect a notification when the form is first seen.
{
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogUserHappinessMetric(AutofillMetrics::FORMS_LOADED));
autofill_manager_->OnFormsSeen(forms);
}
// Expect a notification when the form is submitted.
{
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogUserHappinessMetric(
AutofillMetrics::SUBMITTED_NON_FILLABLE_FORM));
autofill_manager_->OnFormSubmitted(form);
}
// Fill in two of the fields.
form.fields[0].value = ASCIIToUTF16("Elvis Aaron Presley");
form.fields[1].value = ASCIIToUTF16("theking@gmail.com");
forms.front() = form;
// Expect a notification when the form is submitted.
{
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogUserHappinessMetric(
AutofillMetrics::SUBMITTED_NON_FILLABLE_FORM));
autofill_manager_->OnFormSubmitted(form);
}
// Fill in the third field.
form.fields[2].value = ASCIIToUTF16("12345678901");
forms.front() = form;
// Expect notifications when the form is submitted.
{
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogUserHappinessMetric(
AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_NONE));
autofill_manager_->OnFormSubmitted(form);
}
// Mark one of the fields as autofilled.
form.fields[1].is_autofilled = true;
forms.front() = form;
// Expect notifications when the form is submitted.
{
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogUserHappinessMetric(
AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_SOME));
autofill_manager_->OnFormSubmitted(form);
}
// Mark all of the fillable fields as autofilled.
form.fields[0].is_autofilled = true;
form.fields[2].is_autofilled = true;
forms.front() = form;
// Expect notifications when the form is submitted.
{
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogUserHappinessMetric(
AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_ALL));
autofill_manager_->OnFormSubmitted(form);
}
// Clear out the third field's value.
form.fields[2].value = string16();
forms.front() = form;
// Expect notifications when the form is submitted.
{
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogUserHappinessMetric(
AutofillMetrics::SUBMITTED_NON_FILLABLE_FORM));
autofill_manager_->OnFormSubmitted(form);
}
}
// 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.method = ASCIIToUTF16("POST");
form.origin = GURL("http://example.com/form.html");
form.action = GURL("http://example.com/submit.html");
form.user_submitted = true;
FormField field;
autofill_test::CreateTestFormField("Name", "name", "", "text", &field);
form.fields.push_back(field);
autofill_test::CreateTestFormField("Email", "email", "", "text", &field);
form.fields.push_back(field);
autofill_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.
{
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogUserHappinessMetric(AutofillMetrics::FORMS_LOADED));
autofill_manager_->OnFormsSeen(forms);
}
// Simulate typing.
{
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogUserHappinessMetric(AutofillMetrics::USER_DID_TYPE));
autofill_manager_->OnTextFieldDidChange(form, form.fields.front());
}
// Simulate suggestions shown twice for a single edit (i.e. multiple
// keystrokes in a single field).
{
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogUserHappinessMetric(
AutofillMetrics::SUGGESTIONS_SHOWN)).Times(1);
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogUserHappinessMetric(
AutofillMetrics::SUGGESTIONS_SHOWN_ONCE)).Times(1);
autofill_manager_->OnDidShowAutofillSuggestions(true);
autofill_manager_->OnDidShowAutofillSuggestions(false);
}
// Simulate suggestions shown for a different field.
{
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogUserHappinessMetric(AutofillMetrics::SUGGESTIONS_SHOWN));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogUserHappinessMetric(
AutofillMetrics::SUGGESTIONS_SHOWN_ONCE)).Times(0);
autofill_manager_->OnDidShowAutofillSuggestions(true);
}
// Simulate invoking autofill.
{
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogUserHappinessMetric(AutofillMetrics::USER_DID_AUTOFILL));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogUserHappinessMetric(
AutofillMetrics::USER_DID_AUTOFILL_ONCE));
autofill_manager_->OnDidFillAutofillFormData();
}
// Simulate editing an autofilled field.
{
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogUserHappinessMetric(
AutofillMetrics::USER_DID_EDIT_AUTOFILLED_FIELD));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogUserHappinessMetric(
AutofillMetrics::USER_DID_EDIT_AUTOFILLED_FIELD_ONCE));
AutofillManager::GUIDPair guid("00000000-0000-0000-0000-000000000001", 0);
AutofillManager::GUIDPair empty(std::string(), 0);
autofill_manager_->OnFillAutofillFormData(
0, form, form.fields.front(),
autofill_manager_->PackGUIDs(empty, guid));
autofill_manager_->OnTextFieldDidChange(form, form.fields.front());
// Simulate a second keystroke; make sure we don't log the metric twice.
autofill_manager_->OnTextFieldDidChange(form, form.fields.front());
}
// Simulate invoking autofill again.
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogUserHappinessMetric(AutofillMetrics::USER_DID_AUTOFILL));
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogUserHappinessMetric(
AutofillMetrics::USER_DID_AUTOFILL_ONCE)).Times(0);
autofill_manager_->OnDidFillAutofillFormData();
// Simulate editing another autofilled field.
{
EXPECT_CALL(*autofill_manager_->metric_logger(),
LogUserHappinessMetric(
AutofillMetrics::USER_DID_EDIT_AUTOFILLED_FIELD));
autofill_manager_->OnTextFieldDidChange(form, form.fields[1]);
}
}