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
22namespace autofill {
23namespace {
24
25const base::FilePath::CharType kTestName[] = FILE_PATH_LITERAL("heuristics");
26
27// Convert the |html| snippet to a data URI.
28GURL HTMLToDataURI(const std::string& html) {
29  return GURL(std::string("data:text/html;charset=utf-8,") + html);
30}
31
32const 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.
44class 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
61FormStructureBrowserTest::FormStructureBrowserTest()
62    : DataDrivenTest(GetTestDataDir()) {
63}
64
65FormStructureBrowserTest::~FormStructureBrowserTest() {
66}
67
68void 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
83std::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
110IN_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
118IN_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
126IN_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
135IN_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
144IN_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
153IN_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
162IN_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
171IN_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
180IN_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
189IN_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
198IN_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
207IN_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
216IN_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
225IN_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
234IN_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
243IN_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
253IN_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
262IN_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
271IN_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