form_structure_browsertest.cc revision 3f50c38dc070f4bb515c1b64450dae14f316474e
1// Copyright (c) 2010 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/file_path.h" 8#include "base/path_service.h" 9#include "base/string_util.h" 10#include "base/utf_string_conversions.h" 11#include "chrome/browser/autofill/autofill_manager.h" 12#include "chrome/browser/autofill/form_structure.h" 13#include "chrome/browser/tab_contents/tab_contents.h" 14#include "chrome/browser/ui/browser.h" 15#include "chrome/common/chrome_paths.h" 16#include "chrome/test/in_process_browser_test.h" 17#include "chrome/test/ui_test_utils.h" 18#include "googleurl/src/gurl.h" 19 20namespace { 21 22FilePath GetInputFileDirectory() { 23 FilePath test_data_dir_; 24 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_); 25 test_data_dir_ = test_data_dir_.AppendASCII("autofill_heuristics") 26 .AppendASCII("input"); 27 return test_data_dir_; 28} 29 30FilePath GetOutputFileDirectory() { 31 FilePath test_data_dir_; 32 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir_); 33 test_data_dir_ = test_data_dir_.AppendASCII("autofill_heuristics") 34 .AppendASCII("output"); 35 return test_data_dir_; 36} 37 38// Write |content| to |file|. Returns true on success. 39bool WriteFile(const FilePath& file, const std::string& content) { 40 int write_size = file_util::WriteFile(file, content.c_str(), 41 content.length()); 42 return write_size == static_cast<int>(content.length()); 43} 44 45// Convert |html| to URL format, and return the converted string. 46const std::string ConvertToURLFormat(const std::string& html) { 47 return std::string("data:text/html;charset=utf-8,") + html; 48} 49 50// Convert strings with platform end-of-line characters with spaces. 51const std::string NormalizeText(const std::string& text) { 52 std::string normalized = text; 53 ReplaceSubstringsAfterOffset(&normalized, 0, "\r\n", " "); 54 ReplaceSubstringsAfterOffset(&normalized, 0, "\r", " "); 55 ReplaceSubstringsAfterOffset(&normalized, 0, "\n", " "); 56 return normalized; 57} 58 59} // namespace 60 61// Test class for verifying proper form structure as determined by AutoFill 62// heuristics. A test inputs each form file(e.g. form_[language_code].html), 63// loads its HTML content with a call to |NavigateToURL|, the |AutoFillManager| 64// associated with the tab contents is queried for the form structures that 65// were loaded and parsed. These form structures are serialized to string form. 66// If this is the first time test is run, a gold test result file is generated 67// in output directory, else the form structures are compared against the 68// existing result file. 69class FormStructureBrowserTest : public InProcessBrowserTest { 70 public: 71 FormStructureBrowserTest() {} 72 virtual ~FormStructureBrowserTest() {} 73 74 protected: 75 // Returns a vector of form structure objects associated with the given 76 // |autofill_manager|. 77 const std::vector<FormStructure*>& GetFormStructures( 78 const AutoFillManager& autofill_manager); 79 80 // Serializes the given form structures in |forms| to string form. 81 const std::string FormStructuresToString( 82 const std::vector<FormStructure*>& forms); 83 84 private: 85 // A helper utility for converting an |AutoFillFieldType| to string form. 86 const std::string AutoFillFieldTypeToString(AutoFillFieldType type); 87 88 DISALLOW_COPY_AND_ASSIGN(FormStructureBrowserTest); 89}; 90 91const std::vector<FormStructure*>& FormStructureBrowserTest::GetFormStructures( 92 const AutoFillManager& autofill_manager) { 93 return autofill_manager.form_structures_.get(); 94} 95 96const std::string FormStructureBrowserTest::FormStructuresToString( 97 const std::vector<FormStructure*>& forms) { 98 std::string forms_string; 99 for (std::vector<FormStructure*>::const_iterator iter = forms.begin(); 100 iter != forms.end(); 101 ++iter) { 102 103 for (std::vector<AutoFillField*>::const_iterator field_iter = 104 (*iter)->begin(); 105 field_iter != (*iter)->end(); 106 ++field_iter) { 107 // The field list is NULL-terminated. Exit loop when at the end. 108 if (!*field_iter) 109 break; 110 forms_string += AutoFillFieldTypeToString((*field_iter)->type()); 111 forms_string += "\n"; 112 } 113 } 114 return forms_string; 115} 116 117const std::string FormStructureBrowserTest::AutoFillFieldTypeToString( 118 AutoFillFieldType type) { 119 switch (type) { 120 case NO_SERVER_DATA: 121 return "NO_SERVER_DATA"; 122 case UNKNOWN_TYPE: 123 return "UNKNOWN_TYPE"; 124 case EMPTY_TYPE: 125 return "EMPTY_TYPE"; 126 case NAME_FIRST: 127 return "NAME_FIRST"; 128 case NAME_MIDDLE: 129 return "NAME_MIDDLE"; 130 case NAME_LAST: 131 return "NAME_LAST"; 132 case NAME_MIDDLE_INITIAL: 133 return "NAME_MIDDLE_INITIAL"; 134 case NAME_FULL: 135 return "NAME_FULL"; 136 case NAME_SUFFIX: 137 return "NAME_SUFFIX"; 138 case EMAIL_ADDRESS: 139 return "EMAIL_ADDRESS"; 140 case PHONE_HOME_NUMBER: 141 return "PHONE_HOME_NUMBER"; 142 case PHONE_HOME_CITY_CODE: 143 return "PHONE_HOME_CITY_CODE"; 144 case PHONE_HOME_COUNTRY_CODE: 145 return "PHONE_HOME_COUNTRY_CODE"; 146 case PHONE_HOME_CITY_AND_NUMBER: 147 return "PHONE_HOME_CITY_AND_NUMBER"; 148 case PHONE_HOME_WHOLE_NUMBER: 149 return "PHONE_HOME_WHOLE_NUMBER"; 150 case PHONE_FAX_NUMBER: 151 return "PHONE_FAX_NUMBER"; 152 case PHONE_FAX_CITY_CODE: 153 return "PHONE_FAX_CITY_CODE"; 154 case PHONE_FAX_COUNTRY_CODE: 155 return "PHONE_FAX_COUNTRY_CODE"; 156 case PHONE_FAX_CITY_AND_NUMBER: 157 return "PHONE_FAX_CITY_AND_NUMBER"; 158 case PHONE_FAX_WHOLE_NUMBER: 159 return "PHONE_FAX_WHOLE_NUMBER"; 160 case ADDRESS_HOME_LINE1: 161 return "ADDRESS_HOME_LINE1"; 162 case ADDRESS_HOME_LINE2: 163 return "ADDRESS_HOME_LINE2"; 164 case ADDRESS_HOME_APT_NUM: 165 return "ADDRESS_HOME_APT_NUM"; 166 case ADDRESS_HOME_CITY: 167 return "ADDRESS_HOME_CITY"; 168 case ADDRESS_HOME_STATE: 169 return "ADDRESS_HOME_STATE"; 170 case ADDRESS_HOME_ZIP: 171 return "ADDRESS_HOME_ZIP"; 172 case ADDRESS_HOME_COUNTRY: 173 return "ADDRESS_HOME_COUNTRY"; 174 case ADDRESS_BILLING_LINE1: 175 return "ADDRESS_BILLING_LINE1"; 176 case ADDRESS_BILLING_LINE2: 177 return "ADDRESS_BILLING_LINE2"; 178 case ADDRESS_BILLING_APT_NUM: 179 return "ADDRESS_BILLING_APT_NUM"; 180 case ADDRESS_BILLING_CITY: 181 return "ADDRESS_BILLING_CITY"; 182 case ADDRESS_BILLING_STATE: 183 return "ADDRESS_BILLING_STATE"; 184 case ADDRESS_BILLING_ZIP: 185 return "ADDRESS_BILLING_ZIP"; 186 case ADDRESS_BILLING_COUNTRY: 187 return "ADDRESS_BILLING_COUNTRY"; 188 case CREDIT_CARD_NAME: 189 return "CREDIT_CARD_NAME"; 190 case CREDIT_CARD_NUMBER: 191 return "CREDIT_CARD_NUMBER"; 192 case CREDIT_CARD_EXP_MONTH: 193 return "CREDIT_CARD_EXP_MONTH"; 194 case CREDIT_CARD_EXP_2_DIGIT_YEAR: 195 return "CREDIT_CARD_EXP_2_DIGIT_YEAR"; 196 case CREDIT_CARD_EXP_4_DIGIT_YEAR: 197 return "CREDIT_CARD_EXP_4_DIGIT_YEAR"; 198 case CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR: 199 return "CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR"; 200 case CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR: 201 return "CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR"; 202 case CREDIT_CARD_TYPE: 203 return "CREDIT_CARD_TYPE"; 204 case CREDIT_CARD_VERIFICATION_CODE: 205 return "CREDIT_CARD_VERIFICATION_CODE"; 206 case COMPANY_NAME: 207 return "COMPANY_NAME"; 208 default: 209 NOTREACHED() << "Invalid AutoFillFieldType value."; 210 } 211 return std::string(); 212} 213 214IN_PROC_BROWSER_TEST_F(FormStructureBrowserTest, HTMLFiles) { 215 FilePath input_file_path = GetInputFileDirectory(); 216 file_util::FileEnumerator input_file_enumerator(input_file_path, 217 false, file_util::FileEnumerator::FILES, FILE_PATH_LITERAL("*.html")); 218 219 for (input_file_path = input_file_enumerator.Next(); 220 !input_file_path.empty(); 221 input_file_path = input_file_enumerator.Next()) { 222 std::string input_file_source; 223 224 ASSERT_TRUE(file_util::ReadFileToString(input_file_path, 225 &input_file_source)); 226 input_file_source = ConvertToURLFormat(input_file_source); 227 228 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); 229 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL( 230 browser(), GURL(input_file_source))); 231 232 ASSERT_NO_FATAL_FAILURE(ui_test_utils::ClickOnView(browser(), 233 VIEW_ID_TAB_CONTAINER)); 234 ASSERT_TRUE(ui_test_utils::IsViewFocused( 235 browser(), 236 VIEW_ID_TAB_CONTAINER_FOCUS_VIEW)); 237 238 AutoFillManager* autofill_manager = 239 browser()->GetSelectedTabContents()->GetAutoFillManager(); 240 ASSERT_NE(static_cast<AutoFillManager*>(NULL), autofill_manager); 241 std::vector<FormStructure*> forms = GetFormStructures(*autofill_manager); 242 243 FilePath output_file_directory = GetOutputFileDirectory(); 244 FilePath output_file_path = output_file_directory.Append( 245 input_file_path.BaseName().StripTrailingSeparators().ReplaceExtension( 246 FILE_PATH_LITERAL(".out"))); 247 248 std::string output_file_source; 249 if (file_util::ReadFileToString(output_file_path, &output_file_source)) { 250 ASSERT_EQ(NormalizeText(output_file_source), 251 NormalizeText( 252 FormStructureBrowserTest::FormStructuresToString(forms))); 253 254 } else { 255 ASSERT_TRUE(WriteFile( 256 output_file_path, 257 FormStructureBrowserTest::FormStructuresToString(forms))); 258 } 259 } 260} 261