1// Copyright (c) 2011 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 "base/time/time.h"
6#include "chrome/test/base/chrome_render_view_test.h"
7#include "components/autofill/content/common/autofill_messages.h"
8#include "components/autofill/core/common/form_data.h"
9#include "testing/gtest/include/gtest/gtest.h"
10#include "third_party/WebKit/public/platform/WebString.h"
11#include "third_party/WebKit/public/platform/WebURLError.h"
12#include "third_party/WebKit/public/web/WebDocument.h"
13#include "third_party/WebKit/public/web/WebFormElement.h"
14#include "third_party/WebKit/public/web/WebLocalFrame.h"
15
16using blink::WebString;
17using blink::WebURLError;
18
19typedef ChromeRenderViewTest FormAutocompleteTest;
20
21namespace autofill {
22
23// Tests that submitting a form generates a FormSubmitted message
24// with the form fields.
25TEST_F(FormAutocompleteTest, NormalFormSubmit) {
26  // Load a form.
27  LoadHTML("<html><form id='myForm'><input name='fname' value='Rick'/>"
28           "<input name='lname' value='Deckard'/></form></html>");
29
30  // Submit the form.
31  ExecuteJavaScript("document.getElementById('myForm').submit();");
32  ProcessPendingMessages();
33
34  const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
35      AutofillHostMsg_FormSubmitted::ID);
36  ASSERT_TRUE(message != NULL);
37
38  // The tuple also includes a timestamp, which is ignored.
39  Tuple2<FormData, base::TimeTicks> forms;
40  AutofillHostMsg_FormSubmitted::Read(message, &forms);
41  ASSERT_EQ(2U, forms.a.fields.size());
42
43  FormFieldData& form_field = forms.a.fields[0];
44  EXPECT_EQ(WebString("fname"), form_field.name);
45  EXPECT_EQ(WebString("Rick"), form_field.value);
46
47  form_field = forms.a.fields[1];
48  EXPECT_EQ(WebString("lname"), form_field.name);
49  EXPECT_EQ(WebString("Deckard"), form_field.value);
50}
51
52// Tests that submitting a form that has autocomplete="off" generates a
53// FormSubmitted message.
54TEST_F(FormAutocompleteTest, AutoCompleteOffFormSubmit) {
55  // Load a form.
56  LoadHTML("<html><form id='myForm' autocomplete='off'>"
57           "<input name='fname' value='Rick'/>"
58           "<input name='lname' value='Deckard'/>"
59           "</form></html>");
60
61  // Submit the form.
62  ExecuteJavaScript("document.getElementById('myForm').submit();");
63  ProcessPendingMessages();
64
65  const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
66      AutofillHostMsg_FormSubmitted::ID);
67  ASSERT_TRUE(message != NULL);
68
69  // The tuple also includes a timestamp, which is ignored.
70  Tuple2<FormData, base::TimeTicks> forms;
71  AutofillHostMsg_FormSubmitted::Read(message, &forms);
72  ASSERT_EQ(2U, forms.a.fields.size());
73
74  FormFieldData& form_field = forms.a.fields[0];
75  EXPECT_EQ(WebString("fname"), form_field.name);
76  EXPECT_EQ(WebString("Rick"), form_field.value);
77
78  form_field = forms.a.fields[1];
79  EXPECT_EQ(WebString("lname"), form_field.name);
80  EXPECT_EQ(WebString("Deckard"), form_field.value);
81}
82
83// Tests that fields with autocomplete off are submitted.
84TEST_F(FormAutocompleteTest, AutoCompleteOffInputSubmit) {
85  // Load a form.
86  LoadHTML("<html><form id='myForm'>"
87           "<input name='fname' value='Rick'/>"
88           "<input name='lname' value='Deckard' autocomplete='off'/>"
89           "</form></html>");
90
91  // Submit the form.
92  ExecuteJavaScript("document.getElementById('myForm').submit();");
93  ProcessPendingMessages();
94
95  const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
96      AutofillHostMsg_FormSubmitted::ID);
97  ASSERT_TRUE(message != NULL);
98
99  // The tuple also includes a timestamp, which is ignored.
100  Tuple2<FormData, base::TimeTicks> forms;
101  AutofillHostMsg_FormSubmitted::Read(message, &forms);
102  ASSERT_EQ(2U, forms.a.fields.size());
103
104  FormFieldData& form_field = forms.a.fields[0];
105  EXPECT_EQ(WebString("fname"), form_field.name);
106  EXPECT_EQ(WebString("Rick"), form_field.value);
107
108  form_field = forms.a.fields[1];
109  EXPECT_EQ(WebString("lname"), form_field.name);
110  EXPECT_EQ(WebString("Deckard"), form_field.value);
111}
112
113// Tests that submitting a form that has been dynamically set as autocomplete
114// off generates a FormSubmitted message.
115// Note: We previously did the opposite, for bug http://crbug.com/36520
116TEST_F(FormAutocompleteTest, DynamicAutoCompleteOffFormSubmit) {
117  LoadHTML("<html><form id='myForm'><input name='fname' value='Rick'/>"
118           "<input name='lname' value='Deckard'/></form></html>");
119
120  blink::WebElement element =
121      GetMainFrame()->document().getElementById(blink::WebString("myForm"));
122  ASSERT_FALSE(element.isNull());
123  blink::WebFormElement form = element.to<blink::WebFormElement>();
124  EXPECT_TRUE(form.autoComplete());
125
126  // Dynamically mark the form as autocomplete off.
127  ExecuteJavaScript("document.getElementById('myForm')."
128                    "setAttribute('autocomplete', 'off');");
129  ProcessPendingMessages();
130  EXPECT_FALSE(form.autoComplete());
131
132  // Submit the form.
133  ExecuteJavaScript("document.getElementById('myForm').submit();");
134  ProcessPendingMessages();
135
136  const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
137      AutofillHostMsg_FormSubmitted::ID);
138  ASSERT_TRUE(message != NULL);
139
140  // The tuple also includes a timestamp, which is ignored.
141  Tuple2<FormData, base::TimeTicks> forms;
142  AutofillHostMsg_FormSubmitted::Read(message, &forms);
143  ASSERT_EQ(2U, forms.a.fields.size());
144
145  FormFieldData& form_field = forms.a.fields[0];
146  EXPECT_EQ(WebString("fname"), form_field.name);
147  EXPECT_EQ(WebString("Rick"), form_field.value);
148
149  form_field = forms.a.fields[1];
150  EXPECT_EQ(WebString("lname"), form_field.name);
151  EXPECT_EQ(WebString("Deckard"), form_field.value);
152}
153
154}  // namespace autofill
155