| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include <vector> | |
| 6 | |
| 7 #include "base/memory/scoped_ptr.h" | |
| 8 #include "base/string16.h" | |
| 9 #include "base/time.h" | |
| 10 #include "base/utf_string_conversions.h" | |
| 11 #include "chrome/browser/autofill/autocheckout_page_meta_data.h" | |
| 12 #include "chrome/browser/autofill/autofill_cc_infobar_delegate.h" | |
| 13 #include "chrome/browser/autofill/autofill_common_test.h" | |
| 14 #include "chrome/browser/autofill/autofill_manager.h" | |
| 15 #include "chrome/browser/autofill/autofill_manager_delegate.h" | |
| 16 #include "chrome/browser/autofill/autofill_metrics.h" | |
| 17 #include "chrome/browser/autofill/personal_data_manager.h" | |
| 18 #include "chrome/browser/autofill/personal_data_manager_factory.h" | |
| 19 #include "chrome/browser/ui/autofill/tab_autofill_manager_delegate.h" | |
| 20 #include "chrome/browser/webdata/web_data_service.h" | |
| 21 #include "chrome/test/base/chrome_render_view_host_test_harness.h" | |
| 22 #include "chrome/test/base/testing_profile.h" | |
| 23 #include "components/autofill/common/form_data.h" | |
| 24 #include "components/autofill/common/form_field_data.h" | |
| 25 #include "content/public/test/test_browser_thread.h" | |
| 26 #include "googleurl/src/gurl.h" | |
| 27 #include "testing/gmock/include/gmock/gmock.h" | |
| 28 #include "testing/gtest/include/gtest/gtest.h" | |
| 29 #include "ui/gfx/rect.h" | |
| 30 | |
| 31 using content::BrowserThread; | |
| 32 using ::testing::_; | |
| 33 using ::testing::AnyNumber; | |
| 34 using ::testing::Mock; | |
| 35 using base::TimeTicks; | |
| 36 using base::TimeDelta; | |
| 37 | |
| 38 namespace { | |
| 39 | |
| 40 class MockAutofillMetrics : public AutofillMetrics { | |
| 41 public: | |
| 42 MockAutofillMetrics() {} | |
| 43 MOCK_CONST_METHOD1(LogCreditCardInfoBarMetric, void(InfoBarMetric metric)); | |
| 44 MOCK_CONST_METHOD1(LogDeveloperEngagementMetric, | |
| 45 void(DeveloperEngagementMetric metric)); | |
| 46 MOCK_CONST_METHOD3(LogHeuristicTypePrediction, | |
| 47 void(FieldTypeQualityMetric metric, | |
| 48 AutofillFieldType field_type, | |
| 49 const std::string& experiment_id)); | |
| 50 MOCK_CONST_METHOD3(LogOverallTypePrediction, | |
| 51 void(FieldTypeQualityMetric metric, | |
| 52 AutofillFieldType field_type, | |
| 53 const std::string& experiment_id)); | |
| 54 MOCK_CONST_METHOD3(LogServerTypePrediction, | |
| 55 void(FieldTypeQualityMetric metric, | |
| 56 AutofillFieldType field_type, | |
| 57 const std::string& experiment_id)); | |
| 58 MOCK_CONST_METHOD2(LogQualityMetric, void(QualityMetric metric, | |
| 59 const std::string& experiment_id)); | |
| 60 MOCK_CONST_METHOD1(LogServerQueryMetric, void(ServerQueryMetric metric)); | |
| 61 MOCK_CONST_METHOD1(LogUserHappinessMetric, void(UserHappinessMetric metric)); | |
| 62 MOCK_CONST_METHOD1(LogFormFillDurationFromLoadWithAutofill, | |
| 63 void(const TimeDelta& duration)); | |
| 64 MOCK_CONST_METHOD1(LogFormFillDurationFromLoadWithoutAutofill, | |
| 65 void(const TimeDelta& duration)); | |
| 66 MOCK_CONST_METHOD1(LogFormFillDurationFromInteractionWithAutofill, | |
| 67 void(const TimeDelta& duration)); | |
| 68 MOCK_CONST_METHOD1(LogFormFillDurationFromInteractionWithoutAutofill, | |
| 69 void(const TimeDelta& duration)); | |
| 70 MOCK_CONST_METHOD1(LogIsAutofillEnabledAtPageLoad, void(bool enabled)); | |
| 71 MOCK_CONST_METHOD1(LogIsAutofillEnabledAtStartup, void(bool enabled)); | |
| 72 MOCK_CONST_METHOD1(LogStoredProfileCount, void(size_t num_profiles)); | |
| 73 MOCK_CONST_METHOD1(LogAddressSuggestionsCount, void(size_t num_suggestions)); | |
| 74 MOCK_CONST_METHOD1(LogServerExperimentIdForQuery, | |
| 75 void(const std::string& experiment_id)); | |
| 76 MOCK_CONST_METHOD1(LogServerExperimentIdForUpload, | |
| 77 void(const std::string& experiment_id)); | |
| 78 | |
| 79 private: | |
| 80 DISALLOW_COPY_AND_ASSIGN(MockAutofillMetrics); | |
| 81 }; | |
| 82 | |
| 83 class TestPersonalDataManager : public PersonalDataManager { | |
| 84 public: | |
| 85 TestPersonalDataManager() : autofill_enabled_(true) { | |
| 86 set_metric_logger(new MockAutofillMetrics); | |
| 87 CreateTestAutofillProfiles(&web_profiles_); | |
| 88 } | |
| 89 | |
| 90 void SetBrowserContext(content::BrowserContext* context) { | |
| 91 set_browser_context(context); | |
| 92 } | |
| 93 | |
| 94 // Overridden to avoid a trip to the database. This should be a no-op except | |
| 95 // for the side-effect of logging the profile count. | |
| 96 virtual void LoadProfiles() OVERRIDE { | |
| 97 std::vector<AutofillProfile*> profiles; | |
| 98 web_profiles_.release(&profiles); | |
| 99 WDResult<std::vector<AutofillProfile*> > result(AUTOFILL_PROFILES_RESULT, | |
| 100 profiles); | |
| 101 ReceiveLoadedProfiles(0, &result); | |
| 102 } | |
| 103 | |
| 104 // Overridden to avoid a trip to the database. | |
| 105 virtual void LoadCreditCards() OVERRIDE {} | |
| 106 | |
| 107 const MockAutofillMetrics* metric_logger() const { | |
| 108 return static_cast<const MockAutofillMetrics*>( | |
| 109 PersonalDataManager::metric_logger()); | |
| 110 } | |
| 111 | |
| 112 void set_autofill_enabled(bool autofill_enabled) { | |
| 113 autofill_enabled_ = autofill_enabled; | |
| 114 } | |
| 115 | |
| 116 virtual bool IsAutofillEnabled() const OVERRIDE { | |
| 117 return autofill_enabled_; | |
| 118 } | |
| 119 | |
| 120 MOCK_METHOD1(SaveImportedCreditCard, | |
| 121 void(const CreditCard& imported_credit_card)); | |
| 122 | |
| 123 private: | |
| 124 void CreateTestAutofillProfiles(ScopedVector<AutofillProfile>* profiles) { | |
| 125 AutofillProfile* profile = new AutofillProfile; | |
| 126 autofill_test::SetProfileInfo(profile, "Elvis", "Aaron", | |
| 127 "Presley", "theking@gmail.com", "RCA", | |
| 128 "3734 Elvis Presley Blvd.", "Apt. 10", | |
| 129 "Memphis", "Tennessee", "38116", "US", | |
| 130 "12345678901"); | |
| 131 profile->set_guid("00000000-0000-0000-0000-000000000001"); | |
| 132 profiles->push_back(profile); | |
| 133 profile = new AutofillProfile; | |
| 134 autofill_test::SetProfileInfo(profile, "Charles", "Hardin", | |
| 135 "Holley", "buddy@gmail.com", "Decca", | |
| 136 "123 Apple St.", "unit 6", "Lubbock", | |
| 137 "Texas", "79401", "US", "2345678901"); | |
| 138 profile->set_guid("00000000-0000-0000-0000-000000000002"); | |
| 139 profiles->push_back(profile); | |
| 140 } | |
| 141 | |
| 142 bool autofill_enabled_; | |
| 143 | |
| 144 DISALLOW_COPY_AND_ASSIGN(TestPersonalDataManager); | |
| 145 }; | |
| 146 | |
| 147 class TestFormStructure : public FormStructure { | |
| 148 public: | |
| 149 explicit TestFormStructure(const FormData& form) | |
| 150 : FormStructure(form, std::string()) {} | |
| 151 virtual ~TestFormStructure() {} | |
| 152 | |
| 153 void SetFieldTypes(const std::vector<AutofillFieldType>& heuristic_types, | |
| 154 const std::vector<AutofillFieldType>& server_types) { | |
| 155 ASSERT_EQ(field_count(), heuristic_types.size()); | |
| 156 ASSERT_EQ(field_count(), server_types.size()); | |
| 157 | |
| 158 for (size_t i = 0; i < field_count(); ++i) { | |
| 159 AutofillField* form_field = field(i); | |
| 160 ASSERT_TRUE(form_field); | |
| 161 form_field->set_heuristic_type(heuristic_types[i]); | |
| 162 form_field->set_server_type(server_types[i]); | |
| 163 } | |
| 164 | |
| 165 UpdateAutofillCount(); | |
| 166 } | |
| 167 | |
| 168 virtual std::string server_experiment_id() const OVERRIDE { | |
| 169 return server_experiment_id_; | |
| 170 } | |
| 171 void set_server_experiment_id(const std::string& server_experiment_id) { | |
| 172 server_experiment_id_ = server_experiment_id; | |
| 173 } | |
| 174 | |
| 175 private: | |
| 176 std::string server_experiment_id_; | |
| 177 DISALLOW_COPY_AND_ASSIGN(TestFormStructure); | |
| 178 }; | |
| 179 | |
| 180 class TestAutofillManager : public AutofillManager { | |
| 181 public: | |
| 182 TestAutofillManager(content::WebContents* web_contents, | |
| 183 autofill::AutofillManagerDelegate* manager_delegate, | |
| 184 TestPersonalDataManager* personal_manager) | |
| 185 : AutofillManager(web_contents, manager_delegate, personal_manager), | |
| 186 autofill_enabled_(true), | |
| 187 did_finish_async_form_submit_(false), | |
| 188 message_loop_is_running_(false) { | |
| 189 set_metric_logger(new MockAutofillMetrics); | |
| 190 } | |
| 191 virtual ~TestAutofillManager() {} | |
| 192 | |
| 193 virtual bool IsAutofillEnabled() const OVERRIDE { return autofill_enabled_; } | |
| 194 | |
| 195 void set_autofill_enabled(bool autofill_enabled) { | |
| 196 autofill_enabled_ = autofill_enabled; | |
| 197 } | |
| 198 | |
| 199 MockAutofillMetrics* metric_logger() { | |
| 200 return static_cast<MockAutofillMetrics*>(const_cast<AutofillMetrics*>( | |
| 201 AutofillManager::metric_logger())); | |
| 202 } | |
| 203 | |
| 204 void AddSeenForm(const FormData& form, | |
| 205 const std::vector<AutofillFieldType>& heuristic_types, | |
| 206 const std::vector<AutofillFieldType>& server_types, | |
| 207 const std::string& experiment_id) { | |
| 208 FormData empty_form = form; | |
| 209 for (size_t i = 0; i < empty_form.fields.size(); ++i) { | |
| 210 empty_form.fields[i].value = string16(); | |
| 211 } | |
| 212 | |
| 213 // |form_structure| will be owned by |form_structures()|. | |
| 214 TestFormStructure* form_structure = new TestFormStructure(empty_form); | |
| 215 form_structure->SetFieldTypes(heuristic_types, server_types); | |
| 216 form_structure->set_server_experiment_id(experiment_id); | |
| 217 form_structures()->push_back(form_structure); | |
| 218 } | |
| 219 | |
| 220 void FormSubmitted(const FormData& form, const TimeTicks& timestamp) { | |
| 221 if (!OnFormSubmitted(form, timestamp)) | |
| 222 return; | |
| 223 | |
| 224 // Wait for the asynchronous FormSubmitted() call to complete. | |
| 225 if (!did_finish_async_form_submit_) { | |
| 226 // TODO(isherman): It seems silly to need this variable. Is there some | |
| 227 // way I can just query the message loop's state? | |
| 228 message_loop_is_running_ = true; | |
| 229 MessageLoop::current()->Run(); | |
| 230 } else { | |
| 231 did_finish_async_form_submit_ = false; | |
| 232 } | |
| 233 } | |
| 234 | |
| 235 virtual void UploadFormDataAsyncCallback( | |
| 236 const FormStructure* submitted_form, | |
| 237 const base::TimeTicks& load_time, | |
| 238 const base::TimeTicks& interaction_time, | |
| 239 const base::TimeTicks& submission_time) OVERRIDE { | |
| 240 if (message_loop_is_running_) { | |
| 241 MessageLoop::current()->Quit(); | |
| 242 message_loop_is_running_ = false; | |
| 243 } else { | |
| 244 did_finish_async_form_submit_ = true; | |
| 245 } | |
| 246 | |
| 247 AutofillManager::UploadFormDataAsyncCallback(submitted_form, | |
| 248 load_time, | |
| 249 interaction_time, | |
| 250 submission_time); | |
| 251 } | |
| 252 | |
| 253 private: | |
| 254 bool autofill_enabled_; | |
| 255 bool did_finish_async_form_submit_; | |
| 256 bool message_loop_is_running_; | |
| 257 | |
| 258 DISALLOW_COPY_AND_ASSIGN(TestAutofillManager); | |
| 259 }; | |
| 260 | |
| 261 } // namespace | |
| 262 | |
| 263 class AutofillMetricsTest : public ChromeRenderViewHostTestHarness { | |
| 264 public: | |
| 265 AutofillMetricsTest(); | |
| 266 virtual ~AutofillMetricsTest(); | |
| 267 | |
| 268 virtual void SetUp() OVERRIDE; | |
| 269 virtual void TearDown() OVERRIDE; | |
| 270 | |
| 271 protected: | |
| 272 scoped_ptr<ConfirmInfoBarDelegate> CreateDelegate( | |
| 273 MockAutofillMetrics* metric_logger); | |
| 274 | |
| 275 content::TestBrowserThread ui_thread_; | |
| 276 content::TestBrowserThread file_thread_; | |
| 277 content::TestBrowserThread io_thread_; | |
| 278 | |
| 279 scoped_ptr<TestAutofillManager> autofill_manager_; | |
| 280 TestPersonalDataManager personal_data_; | |
| 281 | |
| 282 private: | |
| 283 std::string default_gmock_verbosity_level_; | |
| 284 | |
| 285 DISALLOW_COPY_AND_ASSIGN(AutofillMetricsTest); | |
| 286 }; | |
| 287 | |
| 288 AutofillMetricsTest::AutofillMetricsTest() | |
| 289 : ChromeRenderViewHostTestHarness(), | |
| 290 ui_thread_(BrowserThread::UI, &message_loop_), | |
| 291 file_thread_(BrowserThread::FILE), | |
| 292 io_thread_(BrowserThread::IO) { | |
| 293 } | |
| 294 | |
| 295 AutofillMetricsTest::~AutofillMetricsTest() { | |
| 296 // Order of destruction is important as AutofillManager relies on | |
| 297 // PersonalDataManager to be around when it gets destroyed. | |
| 298 autofill_manager_.reset(); | |
| 299 } | |
| 300 | |
| 301 void AutofillMetricsTest::SetUp() { | |
| 302 TestingProfile* profile = new TestingProfile(); | |
| 303 profile->CreateRequestContext(); | |
| 304 browser_context_.reset(profile); | |
| 305 PersonalDataManagerFactory::GetInstance()->SetTestingFactory(profile, NULL); | |
| 306 | |
| 307 ChromeRenderViewHostTestHarness::SetUp(); | |
| 308 io_thread_.StartIOThread(); | |
| 309 autofill::TabAutofillManagerDelegate::CreateForWebContents(web_contents()); | |
| 310 personal_data_.SetBrowserContext(profile); | |
| 311 autofill_manager_.reset(new TestAutofillManager( | |
| 312 web_contents(), | |
| 313 autofill::TabAutofillManagerDelegate::FromWebContents(web_contents()), | |
| 314 &personal_data_)); | |
| 315 | |
| 316 file_thread_.Start(); | |
| 317 | |
| 318 // Ignore any metrics that we haven't explicitly set expectations for. | |
| 319 // If we don't override the verbosity level, we'll get lots of log spew from | |
| 320 // mocked functions that aren't relevant to a test but happen to be called | |
| 321 // during the test's execution. | |
| 322 // CAUTION: This is a global variable. So as to not affect other tests, this | |
| 323 // _must_ be restored to its original value at the end of the test. | |
| 324 default_gmock_verbosity_level_ = ::testing::FLAGS_gmock_verbose; | |
| 325 ::testing::FLAGS_gmock_verbose = "error"; | |
| 326 } | |
| 327 | |
| 328 void AutofillMetricsTest::TearDown() { | |
| 329 // Restore the global Gmock verbosity level to its default value. | |
| 330 ::testing::FLAGS_gmock_verbose = default_gmock_verbosity_level_; | |
| 331 | |
| 332 // Order of destruction is important as AutofillManager relies on | |
| 333 // PersonalDataManager to be around when it gets destroyed. Also, a real | |
| 334 // AutofillManager is tied to the lifetime of the WebContents, so it must | |
| 335 // be destroyed at the destruction of the WebContents. | |
| 336 autofill_manager_.reset(); | |
| 337 profile()->ResetRequestContext(); | |
| 338 file_thread_.Stop(); | |
| 339 ChromeRenderViewHostTestHarness::TearDown(); | |
| 340 io_thread_.Stop(); | |
| 341 } | |
| 342 | |
| 343 scoped_ptr<ConfirmInfoBarDelegate> AutofillMetricsTest::CreateDelegate( | |
| 344 MockAutofillMetrics* metric_logger) { | |
| 345 EXPECT_CALL(*metric_logger, | |
| 346 LogCreditCardInfoBarMetric(AutofillMetrics::INFOBAR_SHOWN)); | |
| 347 | |
| 348 CreditCard credit_card; | |
| 349 return AutofillCCInfoBarDelegate::CreateForTesting( | |
| 350 metric_logger, | |
| 351 base::Bind(&TestPersonalDataManager::SaveImportedCreditCard, | |
| 352 base::Unretained(&personal_data_), credit_card)); | |
| 353 } | |
| 354 | |
| 355 // Test that we log quality metrics appropriately. | |
| 356 TEST_F(AutofillMetricsTest, QualityMetrics) { | |
| 357 // Set up our form data. | |
| 358 FormData form; | |
| 359 form.name = ASCIIToUTF16("TestForm"); | |
| 360 form.method = ASCIIToUTF16("POST"); | |
| 361 form.origin = GURL("http://example.com/form.html"); | |
| 362 form.action = GURL("http://example.com/submit.html"); | |
| 363 form.user_submitted = true; | |
| 364 | |
| 365 std::vector<AutofillFieldType> heuristic_types, server_types; | |
| 366 FormFieldData field; | |
| 367 | |
| 368 autofill_test::CreateTestFormField( | |
| 369 "Autofilled", "autofilled", "Elvis Aaron Presley", "text", &field); | |
| 370 field.is_autofilled = true; | |
| 371 form.fields.push_back(field); | |
| 372 heuristic_types.push_back(NAME_FULL); | |
| 373 server_types.push_back(NAME_FIRST); | |
| 374 | |
| 375 autofill_test::CreateTestFormField( | |
| 376 "Autofill Failed", "autofillfailed", "buddy@gmail.com", "text", &field); | |
| 377 field.is_autofilled = false; | |
| 378 form.fields.push_back(field); | |
| 379 heuristic_types.push_back(PHONE_HOME_NUMBER); | |
| 380 server_types.push_back(EMAIL_ADDRESS); | |
| 381 | |
| 382 autofill_test::CreateTestFormField( | |
| 383 "Empty", "empty", "", "text", &field); | |
| 384 field.is_autofilled = false; | |
| 385 form.fields.push_back(field); | |
| 386 heuristic_types.push_back(NAME_FULL); | |
| 387 server_types.push_back(NAME_FIRST); | |
| 388 | |
| 389 autofill_test::CreateTestFormField( | |
| 390 "Unknown", "unknown", "garbage", "text", &field); | |
| 391 field.is_autofilled = false; | |
| 392 form.fields.push_back(field); | |
| 393 heuristic_types.push_back(PHONE_HOME_NUMBER); | |
| 394 server_types.push_back(EMAIL_ADDRESS); | |
| 395 | |
| 396 autofill_test::CreateTestFormField( | |
| 397 "Select", "select", "USA", "select-one", &field); | |
| 398 field.is_autofilled = false; | |
| 399 form.fields.push_back(field); | |
| 400 heuristic_types.push_back(UNKNOWN_TYPE); | |
| 401 server_types.push_back(NO_SERVER_DATA); | |
| 402 | |
| 403 autofill_test::CreateTestFormField( | |
| 404 "Phone", "phone", "2345678901", "tel", &field); | |
| 405 field.is_autofilled = true; | |
| 406 form.fields.push_back(field); | |
| 407 heuristic_types.push_back(PHONE_HOME_CITY_AND_NUMBER); | |
| 408 server_types.push_back(PHONE_HOME_WHOLE_NUMBER); | |
| 409 | |
| 410 // Simulate having seen this form on page load. | |
| 411 autofill_manager_->AddSeenForm(form, heuristic_types, server_types, | |
| 412 std::string()); | |
| 413 | |
| 414 // Establish our expectations. | |
| 415 ::testing::InSequence dummy; | |
| 416 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 417 LogServerExperimentIdForUpload(std::string())); | |
| 418 // Autofilled field | |
| 419 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 420 LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED, | |
| 421 std::string())); | |
| 422 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 423 LogHeuristicTypePrediction(AutofillMetrics::TYPE_MATCH, | |
| 424 NAME_FULL, std::string())); | |
| 425 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 426 LogServerTypePrediction(AutofillMetrics::TYPE_MISMATCH, | |
| 427 NAME_FULL, std::string())); | |
| 428 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 429 LogOverallTypePrediction(AutofillMetrics::TYPE_MISMATCH, | |
| 430 NAME_FULL, std::string())); | |
| 431 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 432 LogQualityMetric(AutofillMetrics::FIELD_AUTOFILLED, | |
| 433 std::string())); | |
| 434 // Non-autofilled field for which we had data | |
| 435 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 436 LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED, | |
| 437 std::string())); | |
| 438 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 439 LogHeuristicTypePrediction(AutofillMetrics::TYPE_MISMATCH, | |
| 440 EMAIL_ADDRESS, std::string())); | |
| 441 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 442 LogServerTypePrediction(AutofillMetrics::TYPE_MATCH, | |
| 443 EMAIL_ADDRESS, std::string())); | |
| 444 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 445 LogOverallTypePrediction(AutofillMetrics::TYPE_MATCH, | |
| 446 EMAIL_ADDRESS, std::string())); | |
| 447 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 448 LogQualityMetric(AutofillMetrics::FIELD_NOT_AUTOFILLED, | |
| 449 std::string())); | |
| 450 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 451 LogQualityMetric( | |
| 452 AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_MISMATCH, | |
| 453 std::string())); | |
| 454 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 455 LogQualityMetric( | |
| 456 AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MATCH, | |
| 457 std::string())); | |
| 458 // Empty field | |
| 459 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 460 LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED, | |
| 461 std::string())); | |
| 462 // Unknown field | |
| 463 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 464 LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED, | |
| 465 std::string())); | |
| 466 // <select> field | |
| 467 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 468 LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED, | |
| 469 std::string())); | |
| 470 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 471 LogHeuristicTypePrediction(AutofillMetrics::TYPE_UNKNOWN, | |
| 472 ADDRESS_HOME_COUNTRY, std::string())); | |
| 473 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 474 LogServerTypePrediction(AutofillMetrics::TYPE_UNKNOWN, | |
| 475 ADDRESS_HOME_COUNTRY, std::string())); | |
| 476 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 477 LogOverallTypePrediction(AutofillMetrics::TYPE_UNKNOWN, | |
| 478 ADDRESS_HOME_COUNTRY, std::string())); | |
| 479 // Phone field | |
| 480 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 481 LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED, | |
| 482 std::string())); | |
| 483 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 484 LogHeuristicTypePrediction(AutofillMetrics::TYPE_MATCH, | |
| 485 PHONE_HOME_WHOLE_NUMBER, std::string())); | |
| 486 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 487 LogServerTypePrediction(AutofillMetrics::TYPE_MATCH, | |
| 488 PHONE_HOME_WHOLE_NUMBER, std::string())); | |
| 489 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 490 LogOverallTypePrediction(AutofillMetrics::TYPE_MATCH, | |
| 491 PHONE_HOME_WHOLE_NUMBER, std::string())); | |
| 492 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 493 LogQualityMetric(AutofillMetrics::FIELD_AUTOFILLED, | |
| 494 std::string())); | |
| 495 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 496 LogUserHappinessMetric( | |
| 497 AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_SOME)); | |
| 498 | |
| 499 // Simulate form submission. | |
| 500 EXPECT_NO_FATAL_FAILURE(autofill_manager_->FormSubmitted(form, | |
| 501 TimeTicks::Now())); | |
| 502 } | |
| 503 | |
| 504 // Test that we log the appropriate additional metrics when Autofill failed. | |
| 505 TEST_F(AutofillMetricsTest, QualityMetricsForFailure) { | |
| 506 // Set up our form data. | |
| 507 FormData form; | |
| 508 form.name = ASCIIToUTF16("TestForm"); | |
| 509 form.method = ASCIIToUTF16("POST"); | |
| 510 form.origin = GURL("http://example.com/form.html"); | |
| 511 form.action = GURL("http://example.com/submit.html"); | |
| 512 form.user_submitted = true; | |
| 513 | |
| 514 struct { | |
| 515 const char* label; | |
| 516 const char* name; | |
| 517 const char* value; | |
| 518 AutofillFieldType heuristic_type; | |
| 519 AutofillFieldType server_type; | |
| 520 AutofillMetrics::QualityMetric heuristic_metric; | |
| 521 AutofillMetrics::QualityMetric server_metric; | |
| 522 } failure_cases[] = { | |
| 523 { | |
| 524 "Heuristics unknown, server unknown", "0,0", "Elvis", | |
| 525 UNKNOWN_TYPE, NO_SERVER_DATA, | |
| 526 AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_UNKNOWN, | |
| 527 AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_UNKNOWN | |
| 528 }, | |
| 529 { | |
| 530 "Heuristics match, server unknown", "1,0", "Aaron", | |
| 531 NAME_MIDDLE, NO_SERVER_DATA, | |
| 532 AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_MATCH, | |
| 533 AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_UNKNOWN | |
| 534 }, | |
| 535 { | |
| 536 "Heuristics mismatch, server unknown", "2,0", "Presley", | |
| 537 PHONE_HOME_NUMBER, NO_SERVER_DATA, | |
| 538 AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_MISMATCH, | |
| 539 AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_UNKNOWN | |
| 540 }, | |
| 541 { | |
| 542 "Heuristics unknown, server match", "0,1", "theking@gmail.com", | |
| 543 UNKNOWN_TYPE, EMAIL_ADDRESS, | |
| 544 AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_UNKNOWN, | |
| 545 AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MATCH | |
| 546 }, | |
| 547 { | |
| 548 "Heuristics match, server match", "1,1", "3734 Elvis Presley Blvd.", | |
| 549 ADDRESS_HOME_LINE1, ADDRESS_HOME_LINE1, | |
| 550 AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_MATCH, | |
| 551 AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MATCH | |
| 552 }, | |
| 553 { | |
| 554 "Heuristics mismatch, server match", "2,1", "Apt. 10", | |
| 555 PHONE_HOME_NUMBER, ADDRESS_HOME_LINE2, | |
| 556 AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_MISMATCH, | |
| 557 AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MATCH | |
| 558 }, | |
| 559 { | |
| 560 "Heuristics unknown, server mismatch", "0,2", "Memphis", | |
| 561 UNKNOWN_TYPE, PHONE_HOME_NUMBER, | |
| 562 AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_UNKNOWN, | |
| 563 AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MISMATCH | |
| 564 }, | |
| 565 { | |
| 566 "Heuristics match, server mismatch", "1,2", "Tennessee", | |
| 567 ADDRESS_HOME_STATE, PHONE_HOME_NUMBER, | |
| 568 AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_MATCH, | |
| 569 AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MISMATCH | |
| 570 }, | |
| 571 { | |
| 572 "Heuristics mismatch, server mismatch", "2,2", "38116", | |
| 573 PHONE_HOME_NUMBER, PHONE_HOME_NUMBER, | |
| 574 AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_MISMATCH, | |
| 575 AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MISMATCH | |
| 576 } | |
| 577 }; | |
| 578 | |
| 579 std::vector<AutofillFieldType> heuristic_types, server_types; | |
| 580 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(failure_cases); ++i) { | |
| 581 FormFieldData field; | |
| 582 autofill_test::CreateTestFormField(failure_cases[i].label, | |
| 583 failure_cases[i].name, | |
| 584 failure_cases[i].value, "text", &field); | |
| 585 form.fields.push_back(field); | |
| 586 heuristic_types.push_back(failure_cases[i].heuristic_type); | |
| 587 server_types.push_back(failure_cases[i].server_type); | |
| 588 | |
| 589 } | |
| 590 | |
| 591 // Simulate having seen this form with the desired heuristic and server types. | |
| 592 // |form_structure| will be owned by |autofill_manager_|. | |
| 593 autofill_manager_->AddSeenForm(form, heuristic_types, server_types, | |
| 594 std::string()); | |
| 595 | |
| 596 | |
| 597 // Establish our expectations. | |
| 598 ::testing::InSequence dummy; | |
| 599 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 600 LogServerExperimentIdForUpload(std::string())); | |
| 601 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(failure_cases); ++i) { | |
| 602 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 603 LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED, | |
| 604 std::string())); | |
| 605 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 606 LogQualityMetric(AutofillMetrics::FIELD_NOT_AUTOFILLED, | |
| 607 std::string())); | |
| 608 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 609 LogQualityMetric(failure_cases[i].heuristic_metric, | |
| 610 std::string())); | |
| 611 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 612 LogQualityMetric(failure_cases[i].server_metric, | |
| 613 std::string())); | |
| 614 } | |
| 615 | |
| 616 // Simulate form submission. | |
| 617 EXPECT_NO_FATAL_FAILURE(autofill_manager_->FormSubmitted(form, | |
| 618 TimeTicks::Now())); | |
| 619 } | |
| 620 | |
| 621 // Test that we behave sanely when the cached form differs from the submitted | |
| 622 // one. | |
| 623 TEST_F(AutofillMetricsTest, SaneMetricsWithCacheMismatch) { | |
| 624 // Set up our form data. | |
| 625 FormData form; | |
| 626 form.name = ASCIIToUTF16("TestForm"); | |
| 627 form.method = ASCIIToUTF16("POST"); | |
| 628 form.origin = GURL("http://example.com/form.html"); | |
| 629 form.action = GURL("http://example.com/submit.html"); | |
| 630 form.user_submitted = true; | |
| 631 | |
| 632 std::vector<AutofillFieldType> heuristic_types, server_types; | |
| 633 | |
| 634 FormFieldData field; | |
| 635 autofill_test::CreateTestFormField( | |
| 636 "Both match", "match", "Elvis Aaron Presley", "text", &field); | |
| 637 field.is_autofilled = true; | |
| 638 form.fields.push_back(field); | |
| 639 heuristic_types.push_back(NAME_FULL); | |
| 640 server_types.push_back(NAME_FULL); | |
| 641 autofill_test::CreateTestFormField( | |
| 642 "Both mismatch", "mismatch", "buddy@gmail.com", "text", &field); | |
| 643 field.is_autofilled = false; | |
| 644 form.fields.push_back(field); | |
| 645 heuristic_types.push_back(PHONE_HOME_NUMBER); | |
| 646 server_types.push_back(PHONE_HOME_NUMBER); | |
| 647 autofill_test::CreateTestFormField( | |
| 648 "Only heuristics match", "mixed", "Memphis", "text", &field); | |
| 649 field.is_autofilled = false; | |
| 650 form.fields.push_back(field); | |
| 651 heuristic_types.push_back(ADDRESS_HOME_CITY); | |
| 652 server_types.push_back(PHONE_HOME_NUMBER); | |
| 653 autofill_test::CreateTestFormField( | |
| 654 "Unknown", "unknown", "garbage", "text", &field); | |
| 655 field.is_autofilled = false; | |
| 656 form.fields.push_back(field); | |
| 657 heuristic_types.push_back(UNKNOWN_TYPE); | |
| 658 server_types.push_back(UNKNOWN_TYPE); | |
| 659 | |
| 660 // Simulate having seen this form with the desired heuristic and server types. | |
| 661 // |form_structure| will be owned by |autofill_manager_|. | |
| 662 autofill_manager_->AddSeenForm(form, heuristic_types, server_types, | |
| 663 std::string()); | |
| 664 | |
| 665 | |
| 666 // Add a field and re-arrange the remaining form fields before submitting. | |
| 667 std::vector<FormFieldData> cached_fields = form.fields; | |
| 668 form.fields.clear(); | |
| 669 autofill_test::CreateTestFormField( | |
| 670 "New field", "new field", "Tennessee", "text", &field); | |
| 671 form.fields.push_back(field); | |
| 672 form.fields.push_back(cached_fields[2]); | |
| 673 form.fields.push_back(cached_fields[1]); | |
| 674 form.fields.push_back(cached_fields[3]); | |
| 675 form.fields.push_back(cached_fields[0]); | |
| 676 | |
| 677 // Establish our expectations. | |
| 678 ::testing::InSequence dummy; | |
| 679 // New field | |
| 680 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 681 LogServerExperimentIdForUpload(std::string())); | |
| 682 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 683 LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED, | |
| 684 std::string())); | |
| 685 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 686 LogHeuristicTypePrediction(AutofillMetrics::TYPE_UNKNOWN, | |
| 687 ADDRESS_HOME_STATE, std::string())); | |
| 688 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 689 LogServerTypePrediction(AutofillMetrics::TYPE_UNKNOWN, | |
| 690 ADDRESS_HOME_STATE, std::string())); | |
| 691 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 692 LogOverallTypePrediction(AutofillMetrics::TYPE_UNKNOWN, | |
| 693 ADDRESS_HOME_STATE, std::string())); | |
| 694 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 695 LogQualityMetric(AutofillMetrics::FIELD_NOT_AUTOFILLED, | |
| 696 std::string())); | |
| 697 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 698 LogQualityMetric( | |
| 699 AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_UNKNOWN, | |
| 700 std::string())); | |
| 701 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 702 LogQualityMetric( | |
| 703 AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_UNKNOWN, | |
| 704 std::string())); | |
| 705 // Only heuristics match | |
| 706 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 707 LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED, | |
| 708 std::string())); | |
| 709 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 710 LogHeuristicTypePrediction(AutofillMetrics::TYPE_MATCH, | |
| 711 ADDRESS_HOME_CITY, std::string())); | |
| 712 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 713 LogServerTypePrediction(AutofillMetrics::TYPE_MISMATCH, | |
| 714 ADDRESS_HOME_CITY, std::string())); | |
| 715 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 716 LogOverallTypePrediction(AutofillMetrics::TYPE_MISMATCH, | |
| 717 ADDRESS_HOME_CITY, std::string())); | |
| 718 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 719 LogQualityMetric(AutofillMetrics::FIELD_NOT_AUTOFILLED, | |
| 720 std::string())); | |
| 721 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 722 LogQualityMetric( | |
| 723 AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_MATCH, | |
| 724 std::string())); | |
| 725 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 726 LogQualityMetric( | |
| 727 AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MISMATCH, | |
| 728 std::string())); | |
| 729 // Both mismatch | |
| 730 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 731 LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED, | |
| 732 std::string())); | |
| 733 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 734 LogHeuristicTypePrediction(AutofillMetrics::TYPE_MISMATCH, | |
| 735 EMAIL_ADDRESS, std::string())); | |
| 736 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 737 LogServerTypePrediction(AutofillMetrics::TYPE_MISMATCH, | |
| 738 EMAIL_ADDRESS, std::string())); | |
| 739 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 740 LogOverallTypePrediction(AutofillMetrics::TYPE_MISMATCH, | |
| 741 EMAIL_ADDRESS, std::string())); | |
| 742 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 743 LogQualityMetric(AutofillMetrics::FIELD_NOT_AUTOFILLED, | |
| 744 std::string())); | |
| 745 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 746 LogQualityMetric( | |
| 747 AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_MISMATCH, | |
| 748 std::string())); | |
| 749 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 750 LogQualityMetric( | |
| 751 AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MISMATCH, | |
| 752 std::string())); | |
| 753 // Unknown | |
| 754 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 755 LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED, | |
| 756 std::string())); | |
| 757 // Both match | |
| 758 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 759 LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED, | |
| 760 std::string())); | |
| 761 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 762 LogHeuristicTypePrediction(AutofillMetrics::TYPE_MATCH, | |
| 763 NAME_FULL, std::string())); | |
| 764 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 765 LogServerTypePrediction(AutofillMetrics::TYPE_MATCH, | |
| 766 NAME_FULL, std::string())); | |
| 767 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 768 LogOverallTypePrediction(AutofillMetrics::TYPE_MATCH, | |
| 769 NAME_FULL, std::string())); | |
| 770 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 771 LogQualityMetric(AutofillMetrics::FIELD_AUTOFILLED, | |
| 772 std::string())); | |
| 773 | |
| 774 // Simulate form submission. | |
| 775 EXPECT_NO_FATAL_FAILURE(autofill_manager_->FormSubmitted(form, | |
| 776 TimeTicks::Now())); | |
| 777 } | |
| 778 | |
| 779 // Verify that we correctly log metrics regarding developer engagement. | |
| 780 TEST_F(AutofillMetricsTest, DeveloperEngagement) { | |
| 781 // Start with a non-fillable form. | |
| 782 FormData form; | |
| 783 form.name = ASCIIToUTF16("TestForm"); | |
| 784 form.method = ASCIIToUTF16("POST"); | |
| 785 form.origin = GURL("http://example.com/form.html"); | |
| 786 form.action = GURL("http://example.com/submit.html"); | |
| 787 | |
| 788 FormFieldData field; | |
| 789 autofill_test::CreateTestFormField("Name", "name", "", "text", &field); | |
| 790 form.fields.push_back(field); | |
| 791 autofill_test::CreateTestFormField("Email", "email", "", "text", &field); | |
| 792 form.fields.push_back(field); | |
| 793 | |
| 794 std::vector<FormData> forms(1, form); | |
| 795 | |
| 796 // Ensure no metrics are logged when loading a non-fillable form. | |
| 797 { | |
| 798 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 799 LogDeveloperEngagementMetric(_)).Times(0); | |
| 800 autofill_manager_->OnFormsSeen(forms, TimeTicks()); | |
| 801 autofill_manager_->Reset(); | |
| 802 Mock::VerifyAndClearExpectations(autofill_manager_->metric_logger()); | |
| 803 } | |
| 804 | |
| 805 // Add another field to the form, so that it becomes fillable. | |
| 806 autofill_test::CreateTestFormField("Phone", "phone", "", "text", &field); | |
| 807 forms.back().fields.push_back(field); | |
| 808 | |
| 809 // Expect only the "form parsed" metric to be logged; no metrics about | |
| 810 // author-specified field type hints. | |
| 811 { | |
| 812 EXPECT_CALL( | |
| 813 *autofill_manager_->metric_logger(), | |
| 814 LogDeveloperEngagementMetric( | |
| 815 AutofillMetrics::FILLABLE_FORM_PARSED)).Times(1); | |
| 816 EXPECT_CALL( | |
| 817 *autofill_manager_->metric_logger(), | |
| 818 LogDeveloperEngagementMetric( | |
| 819 AutofillMetrics::FILLABLE_FORM_CONTAINS_TYPE_HINTS)).Times(0); | |
| 820 autofill_manager_->OnFormsSeen(forms, TimeTicks()); | |
| 821 autofill_manager_->Reset(); | |
| 822 Mock::VerifyAndClearExpectations(autofill_manager_->metric_logger()); | |
| 823 } | |
| 824 | |
| 825 // Add some fields with an author-specified field type to the form. | |
| 826 // We need to add at least three fields, because a form must have at least | |
| 827 // three fillable fields to be considered to be autofillable; and if at least | |
| 828 // one field specifies an explicit type hint, we don't apply any of our usual | |
| 829 // local heuristics to detect field types in the rest of the form. | |
| 830 autofill_test::CreateTestFormField("", "", "", "text", &field); | |
| 831 field.autocomplete_attribute = "given-name"; | |
| 832 forms.back().fields.push_back(field); | |
| 833 autofill_test::CreateTestFormField("", "", "", "text", &field); | |
| 834 field.autocomplete_attribute = "email"; | |
| 835 forms.back().fields.push_back(field); | |
| 836 autofill_test::CreateTestFormField("", "", "", "text", &field); | |
| 837 field.autocomplete_attribute = "street-address"; | |
| 838 forms.back().fields.push_back(field); | |
| 839 | |
| 840 // Expect both the "form parsed" metric and the author-specified field type | |
| 841 // hints metric to be logged. | |
| 842 { | |
| 843 EXPECT_CALL( | |
| 844 *autofill_manager_->metric_logger(), | |
| 845 LogDeveloperEngagementMetric( | |
| 846 AutofillMetrics::FILLABLE_FORM_PARSED)).Times(1); | |
| 847 EXPECT_CALL( | |
| 848 *autofill_manager_->metric_logger(), | |
| 849 LogDeveloperEngagementMetric( | |
| 850 AutofillMetrics::FILLABLE_FORM_CONTAINS_TYPE_HINTS)).Times(1); | |
| 851 autofill_manager_->OnFormsSeen(forms, TimeTicks()); | |
| 852 autofill_manager_->Reset(); | |
| 853 Mock::VerifyAndClearExpectations(autofill_manager_->metric_logger()); | |
| 854 } | |
| 855 } | |
| 856 | |
| 857 // Test that we don't log quality metrics for non-autofillable forms. | |
| 858 TEST_F(AutofillMetricsTest, NoQualityMetricsForNonAutofillableForms) { | |
| 859 // Forms must include at least three fields to be auto-fillable. | |
| 860 FormData form; | |
| 861 form.name = ASCIIToUTF16("TestForm"); | |
| 862 form.method = ASCIIToUTF16("POST"); | |
| 863 form.origin = GURL("http://example.com/form.html"); | |
| 864 form.action = GURL("http://example.com/submit.html"); | |
| 865 form.user_submitted = true; | |
| 866 | |
| 867 FormFieldData field; | |
| 868 autofill_test::CreateTestFormField( | |
| 869 "Autofilled", "autofilled", "Elvis Presley", "text", &field); | |
| 870 field.is_autofilled = true; | |
| 871 form.fields.push_back(field); | |
| 872 autofill_test::CreateTestFormField( | |
| 873 "Autofill Failed", "autofillfailed", "buddy@gmail.com", "text", &field); | |
| 874 form.fields.push_back(field); | |
| 875 | |
| 876 // Simulate form submission. | |
| 877 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 878 LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED, | |
| 879 std::string())).Times(0); | |
| 880 EXPECT_NO_FATAL_FAILURE(autofill_manager_->FormSubmitted(form, | |
| 881 TimeTicks::Now())); | |
| 882 | |
| 883 // Search forms are not auto-fillable. | |
| 884 form.action = GURL("http://example.com/search?q=Elvis%20Presley"); | |
| 885 autofill_test::CreateTestFormField( | |
| 886 "Empty", "empty", "", "text", &field); | |
| 887 form.fields.push_back(field); | |
| 888 | |
| 889 // Simulate form submission. | |
| 890 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 891 LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED, | |
| 892 std::string())).Times(0); | |
| 893 EXPECT_NO_FATAL_FAILURE(autofill_manager_->FormSubmitted(form, | |
| 894 TimeTicks::Now())); | |
| 895 } | |
| 896 | |
| 897 // Test that we recored the experiment id appropriately. | |
| 898 TEST_F(AutofillMetricsTest, QualityMetricsWithExperimentId) { | |
| 899 // Set up our form data. | |
| 900 FormData form; | |
| 901 form.name = ASCIIToUTF16("TestForm"); | |
| 902 form.method = ASCIIToUTF16("POST"); | |
| 903 form.origin = GURL("http://example.com/form.html"); | |
| 904 form.action = GURL("http://example.com/submit.html"); | |
| 905 form.user_submitted = true; | |
| 906 | |
| 907 std::vector<AutofillFieldType> heuristic_types, server_types; | |
| 908 FormFieldData field; | |
| 909 | |
| 910 autofill_test::CreateTestFormField( | |
| 911 "Autofilled", "autofilled", "Elvis Aaron Presley", "text", &field); | |
| 912 field.is_autofilled = true; | |
| 913 form.fields.push_back(field); | |
| 914 heuristic_types.push_back(NAME_FULL); | |
| 915 server_types.push_back(NAME_FIRST); | |
| 916 | |
| 917 autofill_test::CreateTestFormField( | |
| 918 "Autofill Failed", "autofillfailed", "buddy@gmail.com", "text", &field); | |
| 919 field.is_autofilled = false; | |
| 920 form.fields.push_back(field); | |
| 921 heuristic_types.push_back(PHONE_HOME_NUMBER); | |
| 922 server_types.push_back(EMAIL_ADDRESS); | |
| 923 | |
| 924 autofill_test::CreateTestFormField( | |
| 925 "Empty", "empty", "", "text", &field); | |
| 926 field.is_autofilled = false; | |
| 927 form.fields.push_back(field); | |
| 928 heuristic_types.push_back(NAME_FULL); | |
| 929 server_types.push_back(NAME_FIRST); | |
| 930 | |
| 931 autofill_test::CreateTestFormField( | |
| 932 "Unknown", "unknown", "garbage", "text", &field); | |
| 933 field.is_autofilled = false; | |
| 934 form.fields.push_back(field); | |
| 935 heuristic_types.push_back(PHONE_HOME_NUMBER); | |
| 936 server_types.push_back(EMAIL_ADDRESS); | |
| 937 | |
| 938 autofill_test::CreateTestFormField( | |
| 939 "Select", "select", "USA", "select-one", &field); | |
| 940 field.is_autofilled = false; | |
| 941 form.fields.push_back(field); | |
| 942 heuristic_types.push_back(UNKNOWN_TYPE); | |
| 943 server_types.push_back(NO_SERVER_DATA); | |
| 944 | |
| 945 const std::string experiment_id = "ThatOughtaDoIt"; | |
| 946 | |
| 947 // Simulate having seen this form on page load. | |
| 948 // |form_structure| will be owned by |autofill_manager_|. | |
| 949 autofill_manager_->AddSeenForm(form, heuristic_types, server_types, | |
| 950 experiment_id); | |
| 951 | |
| 952 // Establish our expectations. | |
| 953 ::testing::InSequence dummy; | |
| 954 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 955 LogServerExperimentIdForUpload(experiment_id)); | |
| 956 // Autofilled field | |
| 957 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 958 LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED, | |
| 959 experiment_id)); | |
| 960 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 961 LogHeuristicTypePrediction(AutofillMetrics::TYPE_MATCH, | |
| 962 NAME_FULL, experiment_id)); | |
| 963 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 964 LogServerTypePrediction(AutofillMetrics::TYPE_MISMATCH, | |
| 965 NAME_FULL, experiment_id)); | |
| 966 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 967 LogOverallTypePrediction(AutofillMetrics::TYPE_MISMATCH, | |
| 968 NAME_FULL, experiment_id)); | |
| 969 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 970 LogQualityMetric(AutofillMetrics::FIELD_AUTOFILLED, | |
| 971 experiment_id)); | |
| 972 // Non-autofilled field for which we had data | |
| 973 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 974 LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED, | |
| 975 experiment_id)); | |
| 976 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 977 LogHeuristicTypePrediction(AutofillMetrics::TYPE_MISMATCH, | |
| 978 EMAIL_ADDRESS, experiment_id)); | |
| 979 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 980 LogServerTypePrediction(AutofillMetrics::TYPE_MATCH, | |
| 981 EMAIL_ADDRESS, experiment_id)); | |
| 982 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 983 LogOverallTypePrediction(AutofillMetrics::TYPE_MATCH, | |
| 984 EMAIL_ADDRESS, experiment_id)); | |
| 985 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 986 LogQualityMetric(AutofillMetrics::FIELD_NOT_AUTOFILLED, | |
| 987 experiment_id)); | |
| 988 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 989 LogQualityMetric( | |
| 990 AutofillMetrics::NOT_AUTOFILLED_HEURISTIC_TYPE_MISMATCH, | |
| 991 experiment_id)); | |
| 992 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 993 LogQualityMetric( | |
| 994 AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MATCH, | |
| 995 experiment_id)); | |
| 996 // Empty field | |
| 997 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 998 LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED, | |
| 999 experiment_id)); | |
| 1000 // Unknown field | |
| 1001 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1002 LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED, | |
| 1003 experiment_id)); | |
| 1004 // <select> field | |
| 1005 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1006 LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED, | |
| 1007 experiment_id)); | |
| 1008 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1009 LogHeuristicTypePrediction(AutofillMetrics::TYPE_UNKNOWN, | |
| 1010 ADDRESS_HOME_COUNTRY, experiment_id)); | |
| 1011 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1012 LogServerTypePrediction(AutofillMetrics::TYPE_UNKNOWN, | |
| 1013 ADDRESS_HOME_COUNTRY, experiment_id)); | |
| 1014 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1015 LogOverallTypePrediction(AutofillMetrics::TYPE_UNKNOWN, | |
| 1016 ADDRESS_HOME_COUNTRY, experiment_id)); | |
| 1017 | |
| 1018 // Simulate form submission. | |
| 1019 EXPECT_NO_FATAL_FAILURE(autofill_manager_->FormSubmitted(form, | |
| 1020 TimeTicks::Now())); | |
| 1021 } | |
| 1022 | |
| 1023 // Test that the profile count is logged correctly. | |
| 1024 TEST_F(AutofillMetricsTest, StoredProfileCount) { | |
| 1025 // The metric should be logged when the profiles are first loaded. | |
| 1026 EXPECT_CALL(*personal_data_.metric_logger(), | |
| 1027 LogStoredProfileCount(2)).Times(1); | |
| 1028 personal_data_.LoadProfiles(); | |
| 1029 | |
| 1030 // The metric should only be logged once. | |
| 1031 EXPECT_CALL(*personal_data_.metric_logger(), | |
| 1032 LogStoredProfileCount(::testing::_)).Times(0); | |
| 1033 personal_data_.LoadProfiles(); | |
| 1034 } | |
| 1035 | |
| 1036 // Test that we correctly log when Autofill is enabled. | |
| 1037 TEST_F(AutofillMetricsTest, AutofillIsEnabledAtStartup) { | |
| 1038 personal_data_.set_autofill_enabled(true); | |
| 1039 EXPECT_CALL(*personal_data_.metric_logger(), | |
| 1040 LogIsAutofillEnabledAtStartup(true)).Times(1); | |
| 1041 personal_data_.Init(profile()); | |
| 1042 } | |
| 1043 | |
| 1044 // Test that we correctly log when Autofill is disabled. | |
| 1045 TEST_F(AutofillMetricsTest, AutofillIsDisabledAtStartup) { | |
| 1046 personal_data_.set_autofill_enabled(false); | |
| 1047 EXPECT_CALL(*personal_data_.metric_logger(), | |
| 1048 LogIsAutofillEnabledAtStartup(false)).Times(1); | |
| 1049 personal_data_.Init(profile()); | |
| 1050 } | |
| 1051 | |
| 1052 // Test that we log the number of Autofill suggestions when filling a form. | |
| 1053 TEST_F(AutofillMetricsTest, AddressSuggestionsCount) { | |
| 1054 // Set up our form data. | |
| 1055 FormData form; | |
| 1056 form.name = ASCIIToUTF16("TestForm"); | |
| 1057 form.method = ASCIIToUTF16("POST"); | |
| 1058 form.origin = GURL("http://example.com/form.html"); | |
| 1059 form.action = GURL("http://example.com/submit.html"); | |
| 1060 form.user_submitted = true; | |
| 1061 | |
| 1062 FormFieldData field; | |
| 1063 std::vector<AutofillFieldType> field_types; | |
| 1064 autofill_test::CreateTestFormField("Name", "name", "", "text", &field); | |
| 1065 form.fields.push_back(field); | |
| 1066 field_types.push_back(NAME_FULL); | |
| 1067 autofill_test::CreateTestFormField("Email", "email", "", "email", &field); | |
| 1068 form.fields.push_back(field); | |
| 1069 field_types.push_back(EMAIL_ADDRESS); | |
| 1070 autofill_test::CreateTestFormField("Phone", "phone", "", "tel", &field); | |
| 1071 form.fields.push_back(field); | |
| 1072 field_types.push_back(PHONE_HOME_NUMBER); | |
| 1073 | |
| 1074 // Simulate having seen this form on page load. | |
| 1075 // |form_structure| will be owned by |autofill_manager_|. | |
| 1076 autofill_manager_->AddSeenForm(form, field_types, field_types, | |
| 1077 std::string()); | |
| 1078 | |
| 1079 // Establish our expectations. | |
| 1080 ::testing::InSequence dummy; | |
| 1081 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1082 LogAddressSuggestionsCount(2)).Times(1); | |
| 1083 | |
| 1084 // Simulate activating the autofill popup for the phone field. | |
| 1085 autofill_manager_->OnQueryFormFieldAutofill( | |
| 1086 0, form, field, gfx::Rect(), false); | |
| 1087 | |
| 1088 // Simulate activating the autofill popup for the email field after typing. | |
| 1089 // No new metric should be logged, since we're still on the same page. | |
| 1090 autofill_test::CreateTestFormField("Email", "email", "b", "email", &field); | |
| 1091 autofill_manager_->OnQueryFormFieldAutofill( | |
| 1092 0, form, field, gfx::Rect(), false); | |
| 1093 | |
| 1094 // Reset the autofill manager state. | |
| 1095 autofill_manager_->Reset(); | |
| 1096 autofill_manager_->AddSeenForm(form, field_types, field_types, | |
| 1097 std::string()); | |
| 1098 | |
| 1099 // Establish our expectations. | |
| 1100 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1101 LogAddressSuggestionsCount(1)).Times(1); | |
| 1102 | |
| 1103 // Simulate activating the autofill popup for the email field after typing. | |
| 1104 autofill_manager_->OnQueryFormFieldAutofill( | |
| 1105 0, form, field, gfx::Rect(), false); | |
| 1106 | |
| 1107 // Reset the autofill manager state again. | |
| 1108 autofill_manager_->Reset(); | |
| 1109 autofill_manager_->AddSeenForm(form, field_types, field_types, | |
| 1110 std::string()); | |
| 1111 | |
| 1112 // Establish our expectations. | |
| 1113 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1114 LogAddressSuggestionsCount(::testing::_)).Times(0); | |
| 1115 | |
| 1116 // Simulate activating the autofill popup for the email field after typing. | |
| 1117 form.fields[0].is_autofilled = true; | |
| 1118 autofill_manager_->OnQueryFormFieldAutofill( | |
| 1119 0, form, field, gfx::Rect(), false); | |
| 1120 } | |
| 1121 | |
| 1122 // Test that we log whether Autofill is enabled when filling a form. | |
| 1123 TEST_F(AutofillMetricsTest, AutofillIsEnabledAtPageLoad) { | |
| 1124 // Establish our expectations. | |
| 1125 ::testing::InSequence dummy; | |
| 1126 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1127 LogIsAutofillEnabledAtPageLoad(true)).Times(1); | |
| 1128 | |
| 1129 autofill_manager_->set_autofill_enabled(true); | |
| 1130 autofill_manager_->OnFormsSeen(std::vector<FormData>(), TimeTicks()); | |
| 1131 | |
| 1132 // Reset the autofill manager state. | |
| 1133 autofill_manager_->Reset(); | |
| 1134 | |
| 1135 // Establish our expectations. | |
| 1136 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1137 LogIsAutofillEnabledAtPageLoad(false)).Times(1); | |
| 1138 | |
| 1139 autofill_manager_->set_autofill_enabled(false); | |
| 1140 autofill_manager_->OnFormsSeen(std::vector<FormData>(), TimeTicks()); | |
| 1141 } | |
| 1142 | |
| 1143 // Test that credit card infobar metrics are logged correctly. | |
| 1144 TEST_F(AutofillMetricsTest, CreditCardInfoBar) { | |
| 1145 MockAutofillMetrics metric_logger; | |
| 1146 ::testing::InSequence dummy; | |
| 1147 | |
| 1148 // Accept the infobar. | |
| 1149 { | |
| 1150 scoped_ptr<ConfirmInfoBarDelegate> infobar(CreateDelegate(&metric_logger)); | |
| 1151 ASSERT_TRUE(infobar); | |
| 1152 EXPECT_CALL(personal_data_, SaveImportedCreditCard(_)); | |
| 1153 EXPECT_CALL(metric_logger, | |
| 1154 LogCreditCardInfoBarMetric(AutofillMetrics::INFOBAR_ACCEPTED)).Times(1); | |
| 1155 EXPECT_CALL(metric_logger, | |
| 1156 LogCreditCardInfoBarMetric(AutofillMetrics::INFOBAR_IGNORED)).Times(0); | |
| 1157 EXPECT_TRUE(infobar->Accept()); | |
| 1158 } | |
| 1159 | |
| 1160 // Cancel the infobar. | |
| 1161 { | |
| 1162 scoped_ptr<ConfirmInfoBarDelegate> infobar(CreateDelegate(&metric_logger)); | |
| 1163 ASSERT_TRUE(infobar); | |
| 1164 EXPECT_CALL(metric_logger, | |
| 1165 LogCreditCardInfoBarMetric(AutofillMetrics::INFOBAR_DENIED)).Times(1); | |
| 1166 EXPECT_CALL(metric_logger, | |
| 1167 LogCreditCardInfoBarMetric(AutofillMetrics::INFOBAR_IGNORED)).Times(0); | |
| 1168 EXPECT_TRUE(infobar->Cancel()); | |
| 1169 } | |
| 1170 | |
| 1171 // Dismiss the infobar. | |
| 1172 { | |
| 1173 scoped_ptr<ConfirmInfoBarDelegate> infobar(CreateDelegate(&metric_logger)); | |
| 1174 ASSERT_TRUE(infobar); | |
| 1175 EXPECT_CALL(metric_logger, | |
| 1176 LogCreditCardInfoBarMetric(AutofillMetrics::INFOBAR_DENIED)).Times(1); | |
| 1177 EXPECT_CALL(metric_logger, | |
| 1178 LogCreditCardInfoBarMetric(AutofillMetrics::INFOBAR_IGNORED)).Times(0); | |
| 1179 infobar->InfoBarDismissed(); | |
| 1180 } | |
| 1181 | |
| 1182 // Ignore the infobar. | |
| 1183 { | |
| 1184 scoped_ptr<ConfirmInfoBarDelegate> infobar(CreateDelegate(&metric_logger)); | |
| 1185 ASSERT_TRUE(infobar); | |
| 1186 EXPECT_CALL(metric_logger, | |
| 1187 LogCreditCardInfoBarMetric(AutofillMetrics::INFOBAR_IGNORED)).Times(1); | |
| 1188 } | |
| 1189 } | |
| 1190 | |
| 1191 // Test that server query response experiment id metrics are logged correctly. | |
| 1192 TEST_F(AutofillMetricsTest, ServerQueryExperimentIdForQuery) { | |
| 1193 MockAutofillMetrics metric_logger; | |
| 1194 ::testing::InSequence dummy; | |
| 1195 | |
| 1196 // No experiment specified. | |
| 1197 EXPECT_CALL(metric_logger, | |
| 1198 LogServerQueryMetric(AutofillMetrics::QUERY_RESPONSE_RECEIVED)); | |
| 1199 EXPECT_CALL(metric_logger, | |
| 1200 LogServerQueryMetric(AutofillMetrics::QUERY_RESPONSE_PARSED)); | |
| 1201 EXPECT_CALL(metric_logger, | |
| 1202 LogServerExperimentIdForQuery(std::string())); | |
| 1203 EXPECT_CALL(metric_logger, | |
| 1204 LogServerQueryMetric( | |
| 1205 AutofillMetrics::QUERY_RESPONSE_MATCHED_LOCAL_HEURISTICS)); | |
| 1206 autofill::AutocheckoutPageMetaData page_meta_data; | |
| 1207 FormStructure::ParseQueryResponse( | |
| 1208 "<autofillqueryresponse></autofillqueryresponse>", | |
| 1209 std::vector<FormStructure*>(), | |
| 1210 &page_meta_data, | |
| 1211 metric_logger); | |
| 1212 | |
| 1213 // Experiment "ar1" specified. | |
| 1214 EXPECT_CALL(metric_logger, | |
| 1215 LogServerQueryMetric(AutofillMetrics::QUERY_RESPONSE_RECEIVED)); | |
| 1216 EXPECT_CALL(metric_logger, | |
| 1217 LogServerQueryMetric(AutofillMetrics::QUERY_RESPONSE_PARSED)); | |
| 1218 EXPECT_CALL(metric_logger, | |
| 1219 LogServerExperimentIdForQuery("ar1")); | |
| 1220 EXPECT_CALL(metric_logger, | |
| 1221 LogServerQueryMetric( | |
| 1222 AutofillMetrics::QUERY_RESPONSE_MATCHED_LOCAL_HEURISTICS)); | |
| 1223 FormStructure::ParseQueryResponse( | |
| 1224 "<autofillqueryresponse experimentid=\"ar1\"></autofillqueryresponse>", | |
| 1225 std::vector<FormStructure*>(), | |
| 1226 &page_meta_data, | |
| 1227 metric_logger); | |
| 1228 } | |
| 1229 | |
| 1230 // Verify that we correctly log user happiness metrics dealing with form loading | |
| 1231 // and form submission. | |
| 1232 TEST_F(AutofillMetricsTest, UserHappinessFormLoadAndSubmission) { | |
| 1233 // Start with a form with insufficiently many fields. | |
| 1234 FormData form; | |
| 1235 form.name = ASCIIToUTF16("TestForm"); | |
| 1236 form.method = ASCIIToUTF16("POST"); | |
| 1237 form.origin = GURL("http://example.com/form.html"); | |
| 1238 form.action = GURL("http://example.com/submit.html"); | |
| 1239 form.user_submitted = true; | |
| 1240 | |
| 1241 FormFieldData field; | |
| 1242 autofill_test::CreateTestFormField("Name", "name", "", "text", &field); | |
| 1243 form.fields.push_back(field); | |
| 1244 autofill_test::CreateTestFormField("Email", "email", "", "text", &field); | |
| 1245 form.fields.push_back(field); | |
| 1246 | |
| 1247 std::vector<FormData> forms(1, form); | |
| 1248 | |
| 1249 // Expect no notifications when the form is first seen. | |
| 1250 { | |
| 1251 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1252 LogUserHappinessMetric(AutofillMetrics::FORMS_LOADED)).Times(0); | |
| 1253 autofill_manager_->OnFormsSeen(forms, TimeTicks()); | |
| 1254 } | |
| 1255 | |
| 1256 | |
| 1257 // Expect no notifications when the form is submitted. | |
| 1258 { | |
| 1259 EXPECT_CALL( | |
| 1260 *autofill_manager_->metric_logger(), | |
| 1261 LogUserHappinessMetric( | |
| 1262 AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_ALL)).Times(0); | |
| 1263 EXPECT_CALL( | |
| 1264 *autofill_manager_->metric_logger(), | |
| 1265 LogUserHappinessMetric( | |
| 1266 AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_SOME)).Times(0); | |
| 1267 EXPECT_CALL( | |
| 1268 *autofill_manager_->metric_logger(), | |
| 1269 LogUserHappinessMetric( | |
| 1270 AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_NONE)).Times(0); | |
| 1271 EXPECT_CALL( | |
| 1272 *autofill_manager_->metric_logger(), | |
| 1273 LogUserHappinessMetric( | |
| 1274 AutofillMetrics::SUBMITTED_NON_FILLABLE_FORM)).Times(0); | |
| 1275 autofill_manager_->FormSubmitted(form, TimeTicks::Now()); | |
| 1276 } | |
| 1277 | |
| 1278 // Add more fields to the form. | |
| 1279 autofill_test::CreateTestFormField("Phone", "phone", "", "text", &field); | |
| 1280 form.fields.push_back(field); | |
| 1281 autofill_test::CreateTestFormField("Unknown", "unknown", "", "text", &field); | |
| 1282 form.fields.push_back(field); | |
| 1283 forms.front() = form; | |
| 1284 | |
| 1285 // Expect a notification when the form is first seen. | |
| 1286 { | |
| 1287 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1288 LogUserHappinessMetric(AutofillMetrics::FORMS_LOADED)); | |
| 1289 autofill_manager_->OnFormsSeen(forms, TimeTicks()); | |
| 1290 } | |
| 1291 | |
| 1292 // Expect a notification when the form is submitted. | |
| 1293 { | |
| 1294 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1295 LogUserHappinessMetric( | |
| 1296 AutofillMetrics::SUBMITTED_NON_FILLABLE_FORM)); | |
| 1297 autofill_manager_->FormSubmitted(form, TimeTicks::Now()); | |
| 1298 } | |
| 1299 | |
| 1300 // Fill in two of the fields. | |
| 1301 form.fields[0].value = ASCIIToUTF16("Elvis Aaron Presley"); | |
| 1302 form.fields[1].value = ASCIIToUTF16("theking@gmail.com"); | |
| 1303 forms.front() = form; | |
| 1304 | |
| 1305 // Expect a notification when the form is submitted. | |
| 1306 { | |
| 1307 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1308 LogUserHappinessMetric( | |
| 1309 AutofillMetrics::SUBMITTED_NON_FILLABLE_FORM)); | |
| 1310 autofill_manager_->FormSubmitted(form, TimeTicks::Now()); | |
| 1311 } | |
| 1312 | |
| 1313 // Fill in the third field. | |
| 1314 form.fields[2].value = ASCIIToUTF16("12345678901"); | |
| 1315 forms.front() = form; | |
| 1316 | |
| 1317 // Expect notifications when the form is submitted. | |
| 1318 { | |
| 1319 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1320 LogUserHappinessMetric( | |
| 1321 AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_NONE)); | |
| 1322 autofill_manager_->FormSubmitted(form, TimeTicks::Now()); | |
| 1323 } | |
| 1324 | |
| 1325 | |
| 1326 // Mark one of the fields as autofilled. | |
| 1327 form.fields[1].is_autofilled = true; | |
| 1328 forms.front() = form; | |
| 1329 | |
| 1330 // Expect notifications when the form is submitted. | |
| 1331 { | |
| 1332 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1333 LogUserHappinessMetric( | |
| 1334 AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_SOME)); | |
| 1335 autofill_manager_->FormSubmitted(form, TimeTicks::Now()); | |
| 1336 } | |
| 1337 | |
| 1338 // Mark all of the fillable fields as autofilled. | |
| 1339 form.fields[0].is_autofilled = true; | |
| 1340 form.fields[2].is_autofilled = true; | |
| 1341 forms.front() = form; | |
| 1342 | |
| 1343 // Expect notifications when the form is submitted. | |
| 1344 { | |
| 1345 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1346 LogUserHappinessMetric( | |
| 1347 AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_ALL)); | |
| 1348 autofill_manager_->FormSubmitted(form, TimeTicks::Now()); | |
| 1349 } | |
| 1350 | |
| 1351 // Clear out the third field's value. | |
| 1352 form.fields[2].value = string16(); | |
| 1353 forms.front() = form; | |
| 1354 | |
| 1355 // Expect notifications when the form is submitted. | |
| 1356 { | |
| 1357 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1358 LogUserHappinessMetric( | |
| 1359 AutofillMetrics::SUBMITTED_NON_FILLABLE_FORM)); | |
| 1360 autofill_manager_->FormSubmitted(form, TimeTicks::Now()); | |
| 1361 } | |
| 1362 } | |
| 1363 | |
| 1364 // Verify that we correctly log user happiness metrics dealing with form | |
| 1365 // interaction. | |
| 1366 TEST_F(AutofillMetricsTest, UserHappinessFormInteraction) { | |
| 1367 // Load a fillable form. | |
| 1368 FormData form; | |
| 1369 form.name = ASCIIToUTF16("TestForm"); | |
| 1370 form.method = ASCIIToUTF16("POST"); | |
| 1371 form.origin = GURL("http://example.com/form.html"); | |
| 1372 form.action = GURL("http://example.com/submit.html"); | |
| 1373 form.user_submitted = true; | |
| 1374 | |
| 1375 FormFieldData field; | |
| 1376 autofill_test::CreateTestFormField("Name", "name", "", "text", &field); | |
| 1377 form.fields.push_back(field); | |
| 1378 autofill_test::CreateTestFormField("Email", "email", "", "text", &field); | |
| 1379 form.fields.push_back(field); | |
| 1380 autofill_test::CreateTestFormField("Phone", "phone", "", "text", &field); | |
| 1381 form.fields.push_back(field); | |
| 1382 | |
| 1383 std::vector<FormData> forms(1, form); | |
| 1384 | |
| 1385 // Expect a notification when the form is first seen. | |
| 1386 { | |
| 1387 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1388 LogUserHappinessMetric(AutofillMetrics::FORMS_LOADED)); | |
| 1389 autofill_manager_->OnFormsSeen(forms, TimeTicks()); | |
| 1390 } | |
| 1391 | |
| 1392 // Simulate typing. | |
| 1393 { | |
| 1394 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1395 LogUserHappinessMetric(AutofillMetrics::USER_DID_TYPE)); | |
| 1396 autofill_manager_->OnTextFieldDidChange(form, form.fields.front(), | |
| 1397 TimeTicks()); | |
| 1398 } | |
| 1399 | |
| 1400 // Simulate suggestions shown twice for a single edit (i.e. multiple | |
| 1401 // keystrokes in a single field). | |
| 1402 { | |
| 1403 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1404 LogUserHappinessMetric( | |
| 1405 AutofillMetrics::SUGGESTIONS_SHOWN)).Times(1); | |
| 1406 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1407 LogUserHappinessMetric( | |
| 1408 AutofillMetrics::SUGGESTIONS_SHOWN_ONCE)).Times(1); | |
| 1409 autofill_manager_->OnDidShowAutofillSuggestions(true); | |
| 1410 autofill_manager_->OnDidShowAutofillSuggestions(false); | |
| 1411 } | |
| 1412 | |
| 1413 // Simulate suggestions shown for a different field. | |
| 1414 { | |
| 1415 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1416 LogUserHappinessMetric(AutofillMetrics::SUGGESTIONS_SHOWN)); | |
| 1417 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1418 LogUserHappinessMetric( | |
| 1419 AutofillMetrics::SUGGESTIONS_SHOWN_ONCE)).Times(0); | |
| 1420 autofill_manager_->OnDidShowAutofillSuggestions(true); | |
| 1421 } | |
| 1422 | |
| 1423 // Simulate invoking autofill. | |
| 1424 { | |
| 1425 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1426 LogUserHappinessMetric(AutofillMetrics::USER_DID_AUTOFILL)); | |
| 1427 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1428 LogUserHappinessMetric( | |
| 1429 AutofillMetrics::USER_DID_AUTOFILL_ONCE)); | |
| 1430 autofill_manager_->OnDidFillAutofillFormData(TimeTicks()); | |
| 1431 } | |
| 1432 | |
| 1433 // Simulate editing an autofilled field. | |
| 1434 { | |
| 1435 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1436 LogUserHappinessMetric( | |
| 1437 AutofillMetrics::USER_DID_EDIT_AUTOFILLED_FIELD)); | |
| 1438 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1439 LogUserHappinessMetric( | |
| 1440 AutofillMetrics::USER_DID_EDIT_AUTOFILLED_FIELD_ONCE)); | |
| 1441 PersonalDataManager::GUIDPair guid( | |
| 1442 "00000000-0000-0000-0000-000000000001", 0); | |
| 1443 PersonalDataManager::GUIDPair empty(std::string(), 0); | |
| 1444 autofill_manager_->OnFillAutofillFormData( | |
| 1445 0, form, form.fields.front(), | |
| 1446 autofill_manager_->PackGUIDs(empty, guid)); | |
| 1447 autofill_manager_->OnTextFieldDidChange(form, form.fields.front(), | |
| 1448 TimeTicks()); | |
| 1449 // Simulate a second keystroke; make sure we don't log the metric twice. | |
| 1450 autofill_manager_->OnTextFieldDidChange(form, form.fields.front(), | |
| 1451 TimeTicks()); | |
| 1452 } | |
| 1453 | |
| 1454 // Simulate invoking autofill again. | |
| 1455 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1456 LogUserHappinessMetric(AutofillMetrics::USER_DID_AUTOFILL)); | |
| 1457 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1458 LogUserHappinessMetric( | |
| 1459 AutofillMetrics::USER_DID_AUTOFILL_ONCE)).Times(0); | |
| 1460 autofill_manager_->OnDidFillAutofillFormData(TimeTicks()); | |
| 1461 | |
| 1462 // Simulate editing another autofilled field. | |
| 1463 { | |
| 1464 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1465 LogUserHappinessMetric( | |
| 1466 AutofillMetrics::USER_DID_EDIT_AUTOFILLED_FIELD)); | |
| 1467 autofill_manager_->OnTextFieldDidChange(form, form.fields[1], TimeTicks()); | |
| 1468 } | |
| 1469 } | |
| 1470 | |
| 1471 // Verify that we correctly log metrics tracking the duration of form fill. | |
| 1472 TEST_F(AutofillMetricsTest, FormFillDuration) { | |
| 1473 // Load a fillable form. | |
| 1474 FormData form; | |
| 1475 form.name = ASCIIToUTF16("TestForm"); | |
| 1476 form.method = ASCIIToUTF16("POST"); | |
| 1477 form.origin = GURL("http://example.com/form.html"); | |
| 1478 form.action = GURL("http://example.com/submit.html"); | |
| 1479 form.user_submitted = true; | |
| 1480 | |
| 1481 FormFieldData field; | |
| 1482 autofill_test::CreateTestFormField("Name", "name", "", "text", &field); | |
| 1483 form.fields.push_back(field); | |
| 1484 autofill_test::CreateTestFormField("Email", "email", "", "text", &field); | |
| 1485 form.fields.push_back(field); | |
| 1486 autofill_test::CreateTestFormField("Phone", "phone", "", "text", &field); | |
| 1487 form.fields.push_back(field); | |
| 1488 | |
| 1489 std::vector<FormData> forms(1, form); | |
| 1490 | |
| 1491 // Fill the field values for form submission. | |
| 1492 form.fields[0].value = ASCIIToUTF16("Elvis Aaron Presley"); | |
| 1493 form.fields[1].value = ASCIIToUTF16("theking@gmail.com"); | |
| 1494 form.fields[2].value = ASCIIToUTF16("12345678901"); | |
| 1495 | |
| 1496 // Expect only form load metrics to be logged if the form is submitted without | |
| 1497 // user interaction. | |
| 1498 { | |
| 1499 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1500 LogFormFillDurationFromLoadWithAutofill(_)).Times(0); | |
| 1501 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1502 LogFormFillDurationFromLoadWithoutAutofill( | |
| 1503 TimeDelta::FromInternalValue(16))); | |
| 1504 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1505 LogFormFillDurationFromInteractionWithAutofill(_)).Times(0); | |
| 1506 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1507 LogFormFillDurationFromInteractionWithoutAutofill(_)).Times(0); | |
| 1508 autofill_manager_->OnFormsSeen(forms, TimeTicks::FromInternalValue(1)); | |
| 1509 autofill_manager_->FormSubmitted(form, TimeTicks::FromInternalValue(17)); | |
| 1510 autofill_manager_->Reset(); | |
| 1511 Mock::VerifyAndClearExpectations(autofill_manager_->metric_logger()); | |
| 1512 } | |
| 1513 | |
| 1514 // Expect metric to be logged if the user manually edited a form field. | |
| 1515 { | |
| 1516 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1517 LogFormFillDurationFromLoadWithAutofill(_)).Times(0); | |
| 1518 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1519 LogFormFillDurationFromLoadWithoutAutofill( | |
| 1520 TimeDelta::FromInternalValue(16))); | |
| 1521 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1522 LogFormFillDurationFromInteractionWithAutofill(_)).Times(0); | |
| 1523 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1524 LogFormFillDurationFromInteractionWithoutAutofill( | |
| 1525 TimeDelta::FromInternalValue(14))); | |
| 1526 autofill_manager_->OnFormsSeen(forms, TimeTicks::FromInternalValue(1)); | |
| 1527 autofill_manager_->OnTextFieldDidChange(form, form.fields.front(), | |
| 1528 TimeTicks::FromInternalValue(3)); | |
| 1529 autofill_manager_->FormSubmitted(form, TimeTicks::FromInternalValue(17)); | |
| 1530 autofill_manager_->Reset(); | |
| 1531 Mock::VerifyAndClearExpectations(autofill_manager_->metric_logger()); | |
| 1532 } | |
| 1533 | |
| 1534 // Expect metric to be logged if the user autofilled the form. | |
| 1535 form.fields[0].is_autofilled = true; | |
| 1536 { | |
| 1537 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1538 LogFormFillDurationFromLoadWithAutofill( | |
| 1539 TimeDelta::FromInternalValue(16))); | |
| 1540 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1541 LogFormFillDurationFromLoadWithoutAutofill(_)).Times(0); | |
| 1542 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1543 LogFormFillDurationFromInteractionWithAutofill( | |
| 1544 TimeDelta::FromInternalValue(12))); | |
| 1545 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1546 LogFormFillDurationFromInteractionWithoutAutofill(_)).Times(0); | |
| 1547 autofill_manager_->OnFormsSeen(forms, TimeTicks::FromInternalValue(1)); | |
| 1548 autofill_manager_->OnDidFillAutofillFormData( | |
| 1549 TimeTicks::FromInternalValue(5)); | |
| 1550 autofill_manager_->FormSubmitted(form, TimeTicks::FromInternalValue(17)); | |
| 1551 autofill_manager_->Reset(); | |
| 1552 Mock::VerifyAndClearExpectations(autofill_manager_->metric_logger()); | |
| 1553 } | |
| 1554 | |
| 1555 // Expect metric to be logged if the user both manually filled some fields | |
| 1556 // and autofilled others. Messages can arrive out of order, so make sure they | |
| 1557 // take precedence appropriately. | |
| 1558 { | |
| 1559 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1560 LogFormFillDurationFromLoadWithAutofill( | |
| 1561 TimeDelta::FromInternalValue(16))); | |
| 1562 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1563 LogFormFillDurationFromLoadWithoutAutofill(_)).Times(0); | |
| 1564 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1565 LogFormFillDurationFromInteractionWithAutofill( | |
| 1566 TimeDelta::FromInternalValue(14))); | |
| 1567 EXPECT_CALL(*autofill_manager_->metric_logger(), | |
| 1568 LogFormFillDurationFromInteractionWithoutAutofill(_)).Times(0); | |
| 1569 autofill_manager_->OnFormsSeen(forms, TimeTicks::FromInternalValue(1)); | |
| 1570 autofill_manager_->OnDidFillAutofillFormData( | |
| 1571 TimeTicks::FromInternalValue(5)); | |
| 1572 autofill_manager_->OnTextFieldDidChange(form, form.fields.front(), | |
| 1573 TimeTicks::FromInternalValue(3)); | |
| 1574 autofill_manager_->FormSubmitted(form, TimeTicks::FromInternalValue(17)); | |
| 1575 autofill_manager_->Reset(); | |
| 1576 Mock::VerifyAndClearExpectations(autofill_manager_->metric_logger()); | |
| 1577 } | |
| 1578 } | |
| OLD | NEW |