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/files/file_path.h"
8 #include "base/path_service.h"
9 #include "base/strings/string_util.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "chrome/browser/ui/browser.h"
12 #include "chrome/browser/ui/tabs/tab_strip_model.h"
13 #include "chrome/common/chrome_paths.h"
14 #include "chrome/test/base/in_process_browser_test.h"
15 #include "chrome/test/base/ui_test_utils.h"
16 #include "components/autofill/content/browser/content_autofill_driver.h"
17 #include "components/autofill/core/browser/autofill_manager.h"
18 #include "components/autofill/core/browser/data_driven_test.h"
19 #include "components/autofill/core/browser/form_structure.h"
20 #include "url/gurl.h"
21
22 namespace autofill {
23 namespace {
24
25 const base::FilePath::CharType kTestName[] = FILE_PATH_LITERAL("heuristics");
26
27 // Convert the |html| snippet to a data URI.
HTMLToDataURI(const std::string & html)28 GURL HTMLToDataURI(const std::string& html) {
29 return GURL(std::string("data:text/html;charset=utf-8,") + html);
30 }
31
GetTestDataDir()32 const base::FilePath& GetTestDataDir() {
33 CR_DEFINE_STATIC_LOCAL(base::FilePath, dir, ());
34 if (dir.empty())
35 PathService::Get(chrome::DIR_TEST_DATA, &dir);
36 return dir;
37 }
38
39 } // namespace
40
41 // A data-driven test for verifying Autofill heuristics. Each input is an HTML
42 // file that contains one or more forms. The corresponding output file lists the
43 // heuristically detected type for eachfield.
44 class FormStructureBrowserTest : public InProcessBrowserTest,
45 public DataDrivenTest {
46 protected:
47 FormStructureBrowserTest();
48 virtual ~FormStructureBrowserTest();
49
50 // DataDrivenTest:
51 virtual void GenerateResults(const std::string& input,
52 std::string* output) OVERRIDE;
53
54 // Serializes the given |forms| into a string.
55 std::string FormStructuresToString(const std::vector<FormStructure*>& forms);
56
57 private:
58 DISALLOW_COPY_AND_ASSIGN(FormStructureBrowserTest);
59 };
60
FormStructureBrowserTest()61 FormStructureBrowserTest::FormStructureBrowserTest()
62 : DataDrivenTest(GetTestDataDir()) {
63 }
64
~FormStructureBrowserTest()65 FormStructureBrowserTest::~FormStructureBrowserTest() {
66 }
67
GenerateResults(const std::string & input,std::string * output)68 void FormStructureBrowserTest::GenerateResults(const std::string& input,
69 std::string* output) {
70 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(),
71 HTMLToDataURI(input)));
72
73 ContentAutofillDriver* autofill_driver =
74 ContentAutofillDriver::FromWebContents(
75 browser()->tab_strip_model()->GetActiveWebContents());
76 ASSERT_NE(static_cast<ContentAutofillDriver*>(NULL), autofill_driver);
77 AutofillManager* autofill_manager = autofill_driver->autofill_manager();
78 ASSERT_NE(static_cast<AutofillManager*>(NULL), autofill_manager);
79 std::vector<FormStructure*> forms = autofill_manager->form_structures_.get();
80 *output = FormStructureBrowserTest::FormStructuresToString(forms);
81 }
82
FormStructuresToString(const std::vector<FormStructure * > & forms)83 std::string FormStructureBrowserTest::FormStructuresToString(
84 const std::vector<FormStructure*>& forms) {
85 std::string forms_string;
86 for (std::vector<FormStructure*>::const_iterator iter = forms.begin();
87 iter != forms.end();
88 ++iter) {
89
90 for (std::vector<AutofillField*>::const_iterator field_iter =
91 (*iter)->begin();
92 field_iter != (*iter)->end();
93 ++field_iter) {
94 forms_string += (*field_iter)->Type().ToString();
95 forms_string += " | " + base::UTF16ToUTF8((*field_iter)->name);
96 forms_string += " | " + base::UTF16ToUTF8((*field_iter)->label);
97 forms_string += " | " + base::UTF16ToUTF8((*field_iter)->value);
98 forms_string += "\n";
99 }
100 }
101 return forms_string;
102 }
103
104 // Heuristics tests timeout on Windows. See http://crbug.com/85276
105 #if defined(OS_WIN)
106 #define MAYBE_DataDrivenHeuristics(n) DISABLED_DataDrivenHeuristics##n
107 #else
108 #define MAYBE_DataDrivenHeuristics(n) DataDrivenHeuristics##n
109 #endif
IN_PROC_BROWSER_TEST_F(FormStructureBrowserTest,DataDrivenHeuristics00)110 IN_PROC_BROWSER_TEST_F(FormStructureBrowserTest, DataDrivenHeuristics00) {
111 const base::FilePath::CharType kFileNamePattern[] =
112 FILE_PATH_LITERAL("00_*.html");
113 RunDataDrivenTest(GetInputDirectory(kTestName),
114 GetOutputDirectory(kTestName),
115 kFileNamePattern);
116 }
117
IN_PROC_BROWSER_TEST_F(FormStructureBrowserTest,DataDrivenHeuristics01)118 IN_PROC_BROWSER_TEST_F(FormStructureBrowserTest, DataDrivenHeuristics01) {
119 const base::FilePath::CharType kFileNamePattern[] =
120 FILE_PATH_LITERAL("01_*.html");
121 RunDataDrivenTest(GetInputDirectory(kTestName),
122 GetOutputDirectory(kTestName),
123 kFileNamePattern);
124 }
125
126 IN_PROC_BROWSER_TEST_F(FormStructureBrowserTest,
127 MAYBE_DataDrivenHeuristics(02)) {
128 const base::FilePath::CharType kFileNamePattern[] =
129 FILE_PATH_LITERAL("02_*.html");
130 RunDataDrivenTest(GetInputDirectory(kTestName),
131 GetOutputDirectory(kTestName),
132 kFileNamePattern);
133 }
134
135 IN_PROC_BROWSER_TEST_F(FormStructureBrowserTest,
136 MAYBE_DataDrivenHeuristics(03)) {
137 const base::FilePath::CharType kFileNamePattern[] =
138 FILE_PATH_LITERAL("03_*.html");
139 RunDataDrivenTest(GetInputDirectory(kTestName),
140 GetOutputDirectory(kTestName),
141 kFileNamePattern);
142 }
143
144 IN_PROC_BROWSER_TEST_F(FormStructureBrowserTest,
145 MAYBE_DataDrivenHeuristics(04)) {
146 const base::FilePath::CharType kFileNamePattern[] =
147 FILE_PATH_LITERAL("04_*.html");
148 RunDataDrivenTest(GetInputDirectory(kTestName),
149 GetOutputDirectory(kTestName),
150 kFileNamePattern);
151 }
152
153 IN_PROC_BROWSER_TEST_F(FormStructureBrowserTest,
154 MAYBE_DataDrivenHeuristics(05)) {
155 const base::FilePath::CharType kFileNamePattern[] =
156 FILE_PATH_LITERAL("05_*.html");
157 RunDataDrivenTest(GetInputDirectory(kTestName),
158 GetOutputDirectory(kTestName),
159 kFileNamePattern);
160 }
161
162 IN_PROC_BROWSER_TEST_F(FormStructureBrowserTest,
163 MAYBE_DataDrivenHeuristics(06)) {
164 const base::FilePath::CharType kFileNamePattern[] =
165 FILE_PATH_LITERAL("06_*.html");
166 RunDataDrivenTest(GetInputDirectory(kTestName),
167 GetOutputDirectory(kTestName),
168 kFileNamePattern);
169 }
170
171 IN_PROC_BROWSER_TEST_F(FormStructureBrowserTest,
172 MAYBE_DataDrivenHeuristics(07)) {
173 const base::FilePath::CharType kFileNamePattern[] =
174 FILE_PATH_LITERAL("07_*.html");
175 RunDataDrivenTest(GetInputDirectory(kTestName),
176 GetOutputDirectory(kTestName),
177 kFileNamePattern);
178 }
179
180 IN_PROC_BROWSER_TEST_F(FormStructureBrowserTest,
181 MAYBE_DataDrivenHeuristics(08)) {
182 const base::FilePath::CharType kFileNamePattern[] =
183 FILE_PATH_LITERAL("08_*.html");
184 RunDataDrivenTest(GetInputDirectory(kTestName),
185 GetOutputDirectory(kTestName),
186 kFileNamePattern);
187 }
188
189 IN_PROC_BROWSER_TEST_F(FormStructureBrowserTest,
190 MAYBE_DataDrivenHeuristics(09)) {
191 const base::FilePath::CharType kFileNamePattern[] =
192 FILE_PATH_LITERAL("09_*.html");
193 RunDataDrivenTest(GetInputDirectory(kTestName),
194 GetOutputDirectory(kTestName),
195 kFileNamePattern);
196 }
197
198 IN_PROC_BROWSER_TEST_F(FormStructureBrowserTest,
199 MAYBE_DataDrivenHeuristics(10)) {
200 const base::FilePath::CharType kFileNamePattern[] =
201 FILE_PATH_LITERAL("10_*.html");
202 RunDataDrivenTest(GetInputDirectory(kTestName),
203 GetOutputDirectory(kTestName),
204 kFileNamePattern);
205 }
206
207 IN_PROC_BROWSER_TEST_F(FormStructureBrowserTest,
208 MAYBE_DataDrivenHeuristics(11)) {
209 const base::FilePath::CharType kFileNamePattern[] =
210 FILE_PATH_LITERAL("11_*.html");
211 RunDataDrivenTest(GetInputDirectory(kTestName),
212 GetOutputDirectory(kTestName),
213 kFileNamePattern);
214 }
215
216 IN_PROC_BROWSER_TEST_F(FormStructureBrowserTest,
217 MAYBE_DataDrivenHeuristics(12)) {
218 const base::FilePath::CharType kFileNamePattern[] =
219 FILE_PATH_LITERAL("12_*.html");
220 RunDataDrivenTest(GetInputDirectory(kTestName),
221 GetOutputDirectory(kTestName),
222 kFileNamePattern);
223 }
224
225 IN_PROC_BROWSER_TEST_F(FormStructureBrowserTest,
226 MAYBE_DataDrivenHeuristics(13)) {
227 const base::FilePath::CharType kFileNamePattern[] =
228 FILE_PATH_LITERAL("13_*.html");
229 RunDataDrivenTest(GetInputDirectory(kTestName),
230 GetOutputDirectory(kTestName),
231 kFileNamePattern);
232 }
233
234 IN_PROC_BROWSER_TEST_F(FormStructureBrowserTest,
235 MAYBE_DataDrivenHeuristics(14)) {
236 const base::FilePath::CharType kFileNamePattern[] =
237 FILE_PATH_LITERAL("14_*.html");
238 RunDataDrivenTest(GetInputDirectory(kTestName),
239 GetOutputDirectory(kTestName),
240 kFileNamePattern);
241 }
242
243 IN_PROC_BROWSER_TEST_F(FormStructureBrowserTest,
244 MAYBE_DataDrivenHeuristics(15)) {
245 const base::FilePath::CharType kFileNamePattern[] =
246 FILE_PATH_LITERAL("15_*.html");
247 RunDataDrivenTest(GetInputDirectory(kTestName),
248 GetOutputDirectory(kTestName),
249 kFileNamePattern);
250 }
251
252 // This test has real failures. http://crbug.com/323093
IN_PROC_BROWSER_TEST_F(FormStructureBrowserTest,DISABLED_DataDrivenHeuristics16)253 IN_PROC_BROWSER_TEST_F(FormStructureBrowserTest,
254 DISABLED_DataDrivenHeuristics16) {
255 const base::FilePath::CharType kFileNamePattern[] =
256 FILE_PATH_LITERAL("16_*.html");
257 RunDataDrivenTest(GetInputDirectory(kTestName),
258 GetOutputDirectory(kTestName),
259 kFileNamePattern);
260 }
261
262 IN_PROC_BROWSER_TEST_F(FormStructureBrowserTest,
263 MAYBE_DataDrivenHeuristics(17)) {
264 const base::FilePath::CharType kFileNamePattern[] =
265 FILE_PATH_LITERAL("17_*.html");
266 RunDataDrivenTest(GetInputDirectory(kTestName),
267 GetOutputDirectory(kTestName),
268 kFileNamePattern);
269 }
270
271 IN_PROC_BROWSER_TEST_F(FormStructureBrowserTest,
272 MAYBE_DataDrivenHeuristics(20)) {
273 const base::FilePath::CharType kFileNamePattern[] =
274 FILE_PATH_LITERAL("20_*.html");
275 RunDataDrivenTest(GetInputDirectory(kTestName),
276 GetOutputDirectory(kTestName),
277 kFileNamePattern);
278 }
279
280 } // namespace autofill
281