blob: 856cdbaa8694a35e1fbe7fb7671494aab14fd645 [file] [log] [blame]
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <vector>
#include "base/format_macros.h"
#include "base/string16.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "chrome/renderer/autofill/form_manager.h"
#include "chrome/test/base/render_view_test.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFormControlElement.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFormElement.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputElement.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSelectElement.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebVector.h"
#include "webkit/glue/form_data.h"
#include "webkit/glue/web_io_operators.h"
using WebKit::WebDocument;
using WebKit::WebElement;
using WebKit::WebFormControlElement;
using WebKit::WebFormElement;
using WebKit::WebFrame;
using WebKit::WebInputElement;
using WebKit::WebSelectElement;
using WebKit::WebNode;
using WebKit::WebString;
using WebKit::WebVector;
using autofill::FormManager;
using webkit_glue::FormData;
using webkit_glue::FormField;
class FormManagerTest : public RenderViewTest {
public:
FormManagerTest() : RenderViewTest() {}
virtual ~FormManagerTest() {}
void ExpectLabels(const char* html,
const std::vector<string16>& labels,
const std::vector<string16>& names,
const std::vector<string16>& values) {
std::vector<string16> control_types(labels.size(), ASCIIToUTF16("text"));
ExpectLabelsAndTypes(html, labels, names, values, control_types);
}
void ExpectLabelsAndTypes(const char* html,
const std::vector<string16>& labels,
const std::vector<string16>& names,
const std::vector<string16>& values,
const std::vector<string16>& control_types) {
ASSERT_EQ(labels.size(), names.size());
ASSERT_EQ(labels.size(), values.size());
ASSERT_EQ(labels.size(), control_types.size());
LoadHTML(html);
WebFrame* web_frame = GetMainFrame();
ASSERT_NE(static_cast<WebFrame*>(NULL), web_frame);
FormManager form_manager;
std::vector<FormData> forms;
form_manager.ExtractForms(web_frame, &forms);
ASSERT_EQ(1U, forms.size());
const FormData& form = forms[0];
EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
EXPECT_EQ(GURL(web_frame->document().url()), form.origin);
EXPECT_EQ(GURL("http://cnn.com"), form.action);
const std::vector<FormField>& fields = form.fields;
ASSERT_EQ(labels.size(), fields.size());
for (size_t i = 0; i < labels.size(); ++i) {
int max_length = control_types[i] == ASCIIToUTF16("text") ?
WebInputElement::defaultMaxLength() : 0;
FormField expected;
expected.label = labels[i];
expected.name = names[i];
expected.value = values[i];
expected.form_control_type = control_types[i];
expected.max_length = max_length;
SCOPED_TRACE(StringPrintf("i: %" PRIuS, i));
EXPECT_FORM_FIELD_EQUALS(expected, fields[i]);
}
}
void ExpectJohnSmithLabels(const char* html) {
std::vector<string16> labels, names, values;
labels.push_back(ASCIIToUTF16("First name:"));
names.push_back(ASCIIToUTF16("firstname"));
values.push_back(ASCIIToUTF16("John"));
labels.push_back(ASCIIToUTF16("Last name:"));
names.push_back(ASCIIToUTF16("lastname"));
values.push_back(ASCIIToUTF16("Smith"));
labels.push_back(ASCIIToUTF16("Email:"));
names.push_back(ASCIIToUTF16("email"));
values.push_back(ASCIIToUTF16("john@example.com"));
ExpectLabels(html, labels, names, values);
}
private:
DISALLOW_COPY_AND_ASSIGN(FormManagerTest);
};
// We should be able to extract a normal text field.
TEST_F(FormManagerTest, WebFormControlElementToFormField) {
LoadHTML("<INPUT type=\"text\" id=\"element\" value=\"value\"/>");
WebFrame* frame = GetMainFrame();
ASSERT_NE(static_cast<WebFrame*>(NULL), frame);
WebElement web_element = frame->document().getElementById("element");
WebFormControlElement element = web_element.to<WebFormControlElement>();
FormField result1;
FormManager::WebFormControlElementToFormField(element,
FormManager::EXTRACT_NONE,
&result1);
FormField expected;
expected.form_control_type = ASCIIToUTF16("text");
expected.max_length = WebInputElement::defaultMaxLength();
expected.name = ASCIIToUTF16("element");
expected.value = string16();
EXPECT_FORM_FIELD_EQUALS(expected, result1);
FormField result2;
FormManager::WebFormControlElementToFormField(element,
FormManager::EXTRACT_VALUE,
&result2);
expected.name = ASCIIToUTF16("element");
expected.value = ASCIIToUTF16("value");
EXPECT_FORM_FIELD_EQUALS(expected, result2);
}
// We should be able to extract a text field with autocomplete="off".
TEST_F(FormManagerTest, WebFormControlElementToFormFieldAutocompleteOff) {
LoadHTML("<INPUT type=\"text\" id=\"element\" value=\"value\""
" autocomplete=\"off\"/>");
WebFrame* frame = GetMainFrame();
ASSERT_NE(static_cast<WebFrame*>(NULL), frame);
WebElement web_element = frame->document().getElementById("element");
WebFormControlElement element = web_element.to<WebFormControlElement>();
FormField result;
FormManager::WebFormControlElementToFormField(element,
FormManager::EXTRACT_VALUE,
&result);
FormField expected;
expected.name = ASCIIToUTF16("element");
expected.value = ASCIIToUTF16("value");
expected.form_control_type = ASCIIToUTF16("text");
expected.max_length = WebInputElement::defaultMaxLength();
EXPECT_FORM_FIELD_EQUALS(expected, result);
}
// We should be able to extract a text field with maxlength specified.
TEST_F(FormManagerTest, WebFormControlElementToFormFieldMaxLength) {
LoadHTML("<INPUT type=\"text\" id=\"element\" value=\"value\""
" maxlength=\"5\"/>");
WebFrame* frame = GetMainFrame();
ASSERT_NE(static_cast<WebFrame*>(NULL), frame);
WebElement web_element = frame->document().getElementById("element");
WebFormControlElement element = web_element.to<WebFormControlElement>();
FormField result;
FormManager::WebFormControlElementToFormField(element,
FormManager::EXTRACT_VALUE,
&result);
FormField expected;
expected.name = ASCIIToUTF16("element");
expected.value = ASCIIToUTF16("value");
expected.form_control_type = ASCIIToUTF16("text");
expected.max_length = 5;
EXPECT_FORM_FIELD_EQUALS(expected, result);
}
// We should be able to extract a text field that has been autofilled.
TEST_F(FormManagerTest, WebFormControlElementToFormFieldAutofilled) {
LoadHTML("<INPUT type=\"text\" id=\"element\" value=\"value\"/>");
WebFrame* frame = GetMainFrame();
ASSERT_NE(static_cast<WebFrame*>(NULL), frame);
WebElement web_element = frame->document().getElementById("element");
WebInputElement element = web_element.to<WebInputElement>();
element.setAutofilled(true);
FormField result;
FormManager::WebFormControlElementToFormField(element,
FormManager::EXTRACT_VALUE,
&result);
FormField expected;
expected.name = ASCIIToUTF16("element");
expected.value = ASCIIToUTF16("value");
expected.form_control_type = ASCIIToUTF16("text");
expected.max_length = WebInputElement::defaultMaxLength();
expected.is_autofilled = true;
EXPECT_FORM_FIELD_EQUALS(expected, result);
}
// We should be able to extract a <select> field.
TEST_F(FormManagerTest, WebFormControlElementToFormFieldSelect) {
LoadHTML("<SELECT id=\"element\"/>"
" <OPTION value=\"CA\">California</OPTION>"
" <OPTION value=\"TX\">Texas</OPTION>"
"</SELECT>");
WebFrame* frame = GetMainFrame();
ASSERT_NE(static_cast<WebFrame*>(NULL), frame);
WebElement web_element = frame->document().getElementById("element");
WebFormControlElement element = web_element.to<WebFormControlElement>();
FormField result1;
FormManager::WebFormControlElementToFormField(element,
FormManager::EXTRACT_VALUE,
&result1);
FormField expected;
expected.name = ASCIIToUTF16("element");
expected.max_length = 0;
expected.form_control_type = ASCIIToUTF16("select-one");
expected.value = ASCIIToUTF16("CA");
EXPECT_FORM_FIELD_EQUALS(expected, result1);
FormField result2;
FormManager::WebFormControlElementToFormField(
element,
static_cast<FormManager::ExtractMask>(FormManager::EXTRACT_VALUE |
FormManager::EXTRACT_OPTION_TEXT),
&result2);
expected.value = ASCIIToUTF16("California");
EXPECT_FORM_FIELD_EQUALS(expected, result2);
FormField result3;
FormManager::WebFormControlElementToFormField(element,
FormManager::EXTRACT_OPTIONS,
&result3);
expected.value = string16();
EXPECT_FORM_FIELD_EQUALS(expected, result3);
ASSERT_EQ(2U, result3.option_values.size());
ASSERT_EQ(2U, result3.option_contents.size());
EXPECT_EQ(ASCIIToUTF16("CA"), result3.option_values[0]);
EXPECT_EQ(ASCIIToUTF16("California"), result3.option_contents[0]);
EXPECT_EQ(ASCIIToUTF16("TX"), result3.option_values[1]);
EXPECT_EQ(ASCIIToUTF16("Texas"), result3.option_contents[1]);
}
// We should not extract the value for non-text and non-select fields.
TEST_F(FormManagerTest, WebFormControlElementToFormFieldInvalidType) {
LoadHTML("<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
" <INPUT type=\"hidden\" id=\"hidden\" value=\"apple\"/>"
" <INPUT type=\"password\" id=\"password\" value=\"secret\"/>"
" <INPUT type=\"checkbox\" id=\"checkbox\" value=\"mail\"/>"
" <INPUT type=\"radio\" id=\"radio\" value=\"male\"/>"
" <INPUT type=\"submit\" id=\"submit\" value=\"Send\"/>"
"</FORM>");
WebFrame* frame = GetMainFrame();
ASSERT_NE(static_cast<WebFrame*>(NULL), frame);
WebElement web_element = frame->document().getElementById("hidden");
WebFormControlElement element = web_element.to<WebFormControlElement>();
FormField result;
FormManager::WebFormControlElementToFormField(element,
FormManager::EXTRACT_VALUE,
&result);
FormField expected;
expected.max_length = 0;
expected.name = ASCIIToUTF16("hidden");
expected.form_control_type = ASCIIToUTF16("hidden");
EXPECT_FORM_FIELD_EQUALS(expected, result);
web_element = frame->document().getElementById("password");
element = web_element.to<WebFormControlElement>();
FormManager::WebFormControlElementToFormField(element,
FormManager::EXTRACT_VALUE,
&result);
expected.name = ASCIIToUTF16("password");
expected.form_control_type = ASCIIToUTF16("password");
EXPECT_FORM_FIELD_EQUALS(expected, result);
web_element = frame->document().getElementById("checkbox");
element = web_element.to<WebFormControlElement>();
FormManager::WebFormControlElementToFormField(element,
FormManager::EXTRACT_VALUE,
&result);
expected.name = ASCIIToUTF16("checkbox");
expected.form_control_type = ASCIIToUTF16("checkbox");
EXPECT_FORM_FIELD_EQUALS(expected, result);
web_element = frame->document().getElementById("radio");
element = web_element.to<WebFormControlElement>();
FormManager::WebFormControlElementToFormField(element,
FormManager::EXTRACT_VALUE,
&result);
expected.name = ASCIIToUTF16("radio");
expected.form_control_type = ASCIIToUTF16("radio");
EXPECT_FORM_FIELD_EQUALS(expected, result);
web_element = frame->document().getElementById("submit");
element = web_element.to<WebFormControlElement>();
FormManager::WebFormControlElementToFormField(element,
FormManager::EXTRACT_VALUE,
&result);
expected.name = ASCIIToUTF16("submit");
expected.form_control_type = ASCIIToUTF16("submit");
EXPECT_FORM_FIELD_EQUALS(expected, result);
}
// We should be able to extract the autocompletetype attribute.
TEST_F(FormManagerTest, WebFormControlElementToFormFieldAutocompletetype) {
std::string html =
"<INPUT type=\"text\" id=\"absent\"/>"
"<INPUT type=\"text\" id=\"empty\" x-autocompletetype=\"\"/>"
"<INPUT type=\"text\" id=\"whitespace\" x-autocompletetype=\" \"/>"
"<INPUT type=\"text\" id=\"regular\" x-autocompletetype=\"email\"/>"
"<INPUT type=\"text\" id=\"multi-valued\" "
" x-autocompletetype=\"x-confirm-email email\"/>"
"<INPUT type=\"text\" id=\"unprefixed\" autocompletetype=\"email\"/>"
"<SELECT id=\"select\" x-autocompletetype=\"state\"/>"
" <OPTION value=\"CA\">California</OPTION>"
" <OPTION value=\"TX\">Texas</OPTION>"
"</SELECT>";
html +=
"<INPUT type=\"text\" id=\"malicious\" x-autocompletetype=\"" +
std::string(10000, 'x') + "\"/>";
LoadHTML(html.c_str());
WebFrame* frame = GetMainFrame();
ASSERT_NE(static_cast<WebFrame*>(NULL), frame);
// An absent attribute is equivalent to an empty one.
WebElement web_element = frame->document().getElementById("absent");
WebFormControlElement element = web_element.to<WebFormControlElement>();
FormField result1;
FormManager::WebFormControlElementToFormField(element,
FormManager::EXTRACT_NONE,
&result1);
FormField expected;
expected.name = ASCIIToUTF16("absent");
expected.form_control_type = ASCIIToUTF16("text");
expected.autocomplete_type = string16();
expected.max_length = WebInputElement::defaultMaxLength();
EXPECT_FORM_FIELD_EQUALS(expected, result1);
web_element = frame->document().getElementById("empty");
element = web_element.to<WebFormControlElement>();
FormField result2;
FormManager::WebFormControlElementToFormField(element,
FormManager::EXTRACT_NONE,
&result2);
expected.name = ASCIIToUTF16("empty");
expected.form_control_type = ASCIIToUTF16("text");
expected.autocomplete_type = string16();
expected.max_length = WebInputElement::defaultMaxLength();
EXPECT_FORM_FIELD_EQUALS(expected, result2);
// The renderer should trim whitespace.
web_element = frame->document().getElementById("whitespace");
element = web_element.to<WebFormControlElement>();
FormField result3;
FormManager::WebFormControlElementToFormField(element,
FormManager::EXTRACT_NONE,
&result3);
expected.name = ASCIIToUTF16("whitespace");
expected.form_control_type = ASCIIToUTF16("text");
expected.autocomplete_type = string16();
expected.max_length = WebInputElement::defaultMaxLength();
EXPECT_FORM_FIELD_EQUALS(expected, result3);
// Common case: exactly one type specified.
web_element = frame->document().getElementById("regular");
element = web_element.to<WebFormControlElement>();
FormField result4;
FormManager::WebFormControlElementToFormField(element,
FormManager::EXTRACT_NONE,
&result4);
expected.name = ASCIIToUTF16("regular");
expected.form_control_type = ASCIIToUTF16("text");
expected.autocomplete_type = ASCIIToUTF16("email");
expected.max_length = WebInputElement::defaultMaxLength();
EXPECT_FORM_FIELD_EQUALS(expected, result4);
// Verify that we correctly extract fallback types as well.
web_element = frame->document().getElementById("multi-valued");
element = web_element.to<WebFormControlElement>();
FormField result5;
FormManager::WebFormControlElementToFormField(element,
FormManager::EXTRACT_NONE,
&result5);
expected.name = ASCIIToUTF16("multi-valued");
expected.form_control_type = ASCIIToUTF16("text");
expected.autocomplete_type = ASCIIToUTF16("x-confirm-email email");
expected.max_length = WebInputElement::defaultMaxLength();
EXPECT_FORM_FIELD_EQUALS(expected, result5);
// The attribute is not yet part of the HTML standard, so we only recognize
// the prefixed version -- 'x-autocompletetype' -- and not the unprefixed one.
web_element = frame->document().getElementById("unprefixed");
element = web_element.to<WebFormControlElement>();
FormField result6;
FormManager::WebFormControlElementToFormField(element,
FormManager::EXTRACT_NONE,
&result6);
expected.name = ASCIIToUTF16("unprefixed");
expected.form_control_type = ASCIIToUTF16("text");
expected.autocomplete_type = string16();
expected.max_length = WebInputElement::defaultMaxLength();
EXPECT_FORM_FIELD_EQUALS(expected, result6);
// <select> elements should behave no differently from text fields here.
web_element = frame->document().getElementById("select");
element = web_element.to<WebFormControlElement>();
FormField result7;
FormManager::WebFormControlElementToFormField(element,
FormManager::EXTRACT_NONE,
&result7);
expected.name = ASCIIToUTF16("select");
expected.form_control_type = ASCIIToUTF16("select-one");
expected.autocomplete_type = ASCIIToUTF16("state");
expected.max_length = 0;
EXPECT_FORM_FIELD_EQUALS(expected, result7);
// Very long attribute values should be replaced by a default string, to
// prevent malicious websites from DOSing the browser process.
web_element = frame->document().getElementById("malicious");
element = web_element.to<WebFormControlElement>();
FormField result8;
FormManager::WebFormControlElementToFormField(element,
FormManager::EXTRACT_NONE,
&result8);
expected.name = ASCIIToUTF16("malicious");
expected.form_control_type = ASCIIToUTF16("text");
expected.autocomplete_type = ASCIIToUTF16("x-max-data-length-exceeded");
expected.max_length = WebInputElement::defaultMaxLength();
EXPECT_FORM_FIELD_EQUALS(expected, result8);
}
TEST_F(FormManagerTest, WebFormElementToFormData) {
LoadHTML("<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
" <INPUT type=\"text\" id=\"firstname\" value=\"John\"/>"
" <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>"
" <SELECT id=\"state\"/>"
" <OPTION value=\"CA\">California</OPTION>"
" <OPTION value=\"TX\">Texas</OPTION>"
" </SELECT>"
// The below inputs should be ignored
" <INPUT type=\"hidden\" id=\"notvisible\" value=\"apple\"/>"
" <INPUT type=\"password\" id=\"password\" value=\"secret\"/>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
"</FORM>");
WebFrame* frame = GetMainFrame();
ASSERT_NE(static_cast<WebFrame*>(NULL), frame);
WebVector<WebFormElement> forms;
frame->document().forms(forms);
ASSERT_EQ(1U, forms.size());
FormData form;
EXPECT_TRUE(FormManager::WebFormElementToFormData(forms[0],
FormManager::REQUIRE_NONE,
FormManager::EXTRACT_VALUE,
&form));
EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
EXPECT_EQ(GURL(frame->document().url()), form.origin);
EXPECT_EQ(GURL("http://cnn.com"), form.action);
const std::vector<FormField>& fields = form.fields;
ASSERT_EQ(3U, fields.size());
FormField expected;
expected.name = ASCIIToUTF16("firstname");
expected.value = ASCIIToUTF16("John");
expected.form_control_type = ASCIIToUTF16("text");
expected.max_length = WebInputElement::defaultMaxLength();
EXPECT_FORM_FIELD_EQUALS(expected, fields[0]);
expected.name = ASCIIToUTF16("lastname");
expected.value = ASCIIToUTF16("Smith");
expected.form_control_type = ASCIIToUTF16("text");
expected.max_length = WebInputElement::defaultMaxLength();
EXPECT_FORM_FIELD_EQUALS(expected, fields[1]);
expected.name = ASCIIToUTF16("state");
expected.value = ASCIIToUTF16("CA");
expected.form_control_type = ASCIIToUTF16("select-one");
expected.max_length = 0;
EXPECT_FORM_FIELD_EQUALS(expected, fields[2]);
}
TEST_F(FormManagerTest, ExtractForms) {
ExpectJohnSmithLabels(
"<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
" First name: <INPUT type=\"text\" id=\"firstname\" value=\"John\"/>"
" Last name: <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>"
" Email: <INPUT type=\"text\" id=\"email\" value=\"john@example.com\"/>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
"</FORM>");
}
TEST_F(FormManagerTest, ExtractMultipleForms) {
LoadHTML("<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
" <INPUT type=\"text\" id=\"firstname\" value=\"John\"/>"
" <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>"
" <INPUT type=\"text\" id=\"email\" value=\"john@example.com\"/>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
"</FORM>"
"<FORM name=\"TestForm2\" action=\"http://zoo.com\" method=\"post\">"
" <INPUT type=\"text\" id=\"firstname\" value=\"Jack\"/>"
" <INPUT type=\"text\" id=\"lastname\" value=\"Adams\"/>"
" <INPUT type=\"text\" id=\"email\" value=\"jack@example.com\"/>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
"</FORM>");
WebFrame* web_frame = GetMainFrame();
ASSERT_NE(static_cast<WebFrame*>(NULL), web_frame);
FormManager form_manager;
std::vector<FormData> forms;
form_manager.ExtractForms(web_frame, &forms);
ASSERT_EQ(2U, forms.size());
// First form.
const FormData& form = forms[0];
EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
EXPECT_EQ(GURL(web_frame->document().url()), form.origin);
EXPECT_EQ(GURL("http://cnn.com"), form.action);
const std::vector<FormField>& fields = form.fields;
ASSERT_EQ(3U, fields.size());
FormField expected;
expected.form_control_type = ASCIIToUTF16("text");
expected.max_length = WebInputElement::defaultMaxLength();
expected.name = ASCIIToUTF16("firstname");
expected.value = ASCIIToUTF16("John");
EXPECT_FORM_FIELD_EQUALS(expected, fields[0]);
expected.name = ASCIIToUTF16("lastname");
expected.value = ASCIIToUTF16("Smith");
EXPECT_FORM_FIELD_EQUALS(expected, fields[1]);
expected.name = ASCIIToUTF16("email");
expected.value = ASCIIToUTF16("john@example.com");
EXPECT_FORM_FIELD_EQUALS(expected, fields[2]);
// Second form.
const FormData& form2 = forms[1];
EXPECT_EQ(ASCIIToUTF16("TestForm2"), form2.name);
EXPECT_EQ(GURL(web_frame->document().url()), form2.origin);
EXPECT_EQ(GURL("http://zoo.com"), form2.action);
const std::vector<FormField>& fields2 = form2.fields;
ASSERT_EQ(3U, fields2.size());
expected.name = ASCIIToUTF16("firstname");
expected.value = ASCIIToUTF16("Jack");
EXPECT_FORM_FIELD_EQUALS(expected, fields2[0]);
expected.name = ASCIIToUTF16("lastname");
expected.value = ASCIIToUTF16("Adams");
EXPECT_FORM_FIELD_EQUALS(expected, fields2[1]);
expected.name = ASCIIToUTF16("email");
expected.value = ASCIIToUTF16("jack@example.com");
EXPECT_FORM_FIELD_EQUALS(expected, fields2[2]);
}
// We should not extract a form if it has too few fillable fields.
TEST_F(FormManagerTest, ExtractFormsTooFewFields) {
LoadHTML("<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
" <INPUT type=\"text\" id=\"firstname\" value=\"John\"/>"
" <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
"</FORM>");
WebFrame* web_frame = GetMainFrame();
ASSERT_NE(static_cast<WebFrame*>(NULL), web_frame);
FormManager form_manager;
std::vector<FormData> forms;
form_manager.ExtractForms(web_frame, &forms);
EXPECT_EQ(0U, forms.size());
}
TEST_F(FormManagerTest, WebFormElementToFormDataAutocomplete) {
{
// Form is not auto-completable due to autocomplete=off.
LoadHTML("<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\""
" autocomplete=off>"
" <INPUT type=\"text\" id=\"firstname\" value=\"John\"/>"
" <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>"
" <INPUT type=\"text\" id=\"email\" value=\"john@example.com\"/>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
"</FORM>");
WebFrame* web_frame = GetMainFrame();
ASSERT_NE(static_cast<WebFrame*>(NULL), web_frame);
WebVector<WebFormElement> web_forms;
web_frame->document().forms(web_forms);
ASSERT_EQ(1U, web_forms.size());
WebFormElement web_form = web_forms[0];
FormData form;
EXPECT_TRUE(FormManager::WebFormElementToFormData(
web_form, FormManager::REQUIRE_NONE, FormManager::EXTRACT_NONE, &form));
EXPECT_FALSE(FormManager::WebFormElementToFormData(
web_form, FormManager::REQUIRE_AUTOCOMPLETE, FormManager::EXTRACT_NONE,
&form));
}
{
// The firstname element is not auto-completable due to autocomplete=off.
LoadHTML("<FORM name=\"TestForm\" action=\"http://abc.com\" "
" method=\"post\">"
" <INPUT type=\"text\" id=\"firstname\" value=\"John\""
" autocomplete=off>"
" <INPUT type=\"text\" id=\"middlename\" value=\"Jack\"/>"
" <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>"
" <INPUT type=\"text\" id=\"email\" value=\"john@example.com\"/>"
" <INPUT type=\"submit\" name=\"reply\" value=\"Send\"/>"
"</FORM>");
WebFrame* web_frame = GetMainFrame();
ASSERT_NE(static_cast<WebFrame*>(NULL), web_frame);
WebVector<WebFormElement> web_forms;
web_frame->document().forms(web_forms);
ASSERT_EQ(1U, web_forms.size());
WebFormElement web_form = web_forms[0];
FormData form;
EXPECT_TRUE(FormManager::WebFormElementToFormData(
web_form, FormManager::REQUIRE_AUTOCOMPLETE, FormManager::EXTRACT_VALUE,
&form));
EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
EXPECT_EQ(GURL(web_frame->document().url()), form.origin);
EXPECT_EQ(GURL("http://abc.com"), form.action);
const std::vector<FormField>& fields = form.fields;
ASSERT_EQ(3U, fields.size());
FormField expected;
expected.form_control_type = ASCIIToUTF16("text");
expected.max_length = WebInputElement::defaultMaxLength();
expected.name = ASCIIToUTF16("middlename");
expected.value = ASCIIToUTF16("Jack");
EXPECT_FORM_FIELD_EQUALS(expected, fields[0]);
expected.name = ASCIIToUTF16("lastname");
expected.value = ASCIIToUTF16("Smith");
EXPECT_FORM_FIELD_EQUALS(expected, fields[1]);
expected.name = ASCIIToUTF16("email");
expected.value = ASCIIToUTF16("john@example.com");
EXPECT_FORM_FIELD_EQUALS(expected, fields[2]);
}
}
TEST_F(FormManagerTest, WebFormElementToFormDataEnabled) {
// The firstname element is not enabled due to disabled being set.
LoadHTML("<FORM name=\"TestForm\" action=\"http://xyz.com\" method=\"post\">"
" <INPUT disabled type=\"text\" id=\"firstname\" value=\"John\"/>"
" <INPUT type=\"text\" id=\"middlename\" value=\"Jack\"/>"
" <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>"
" <INPUT type=\"text\" id=\"email\" value=\"jack@example.com\"/>"
" <INPUT type=\"submit\" name=\"submit\" value=\"Send\"/>"
"</FORM>");
WebFrame* web_frame = GetMainFrame();
ASSERT_NE(static_cast<WebFrame*>(NULL), web_frame);
WebVector<WebFormElement> web_forms;
web_frame->document().forms(web_forms);
ASSERT_EQ(1U, web_forms.size());
WebFormElement web_form = web_forms[0];
FormData form;
EXPECT_TRUE(FormManager::WebFormElementToFormData(
web_form, FormManager::REQUIRE_ENABLED, FormManager::EXTRACT_VALUE,
&form));
EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
EXPECT_EQ(GURL(web_frame->document().url()), form.origin);
EXPECT_EQ(GURL("http://xyz.com"), form.action);
const std::vector<FormField>& fields = form.fields;
ASSERT_EQ(3U, fields.size());
FormField expected;
expected.form_control_type = ASCIIToUTF16("text");
expected.max_length = WebInputElement::defaultMaxLength();
expected.name = ASCIIToUTF16("middlename");
expected.value = ASCIIToUTF16("Jack");
EXPECT_FORM_FIELD_EQUALS(expected, fields[0]);
expected.name = ASCIIToUTF16("lastname");
expected.value = ASCIIToUTF16("Smith");
EXPECT_FORM_FIELD_EQUALS(expected, fields[1]);
expected.name = ASCIIToUTF16("email");
expected.value = ASCIIToUTF16("jack@example.com");
EXPECT_FORM_FIELD_EQUALS(expected, fields[2]);
}
TEST_F(FormManagerTest, FindForm) {
LoadHTML("<FORM name=\"TestForm\" action=\"http://buh.com\" method=\"post\">"
" <INPUT type=\"text\" id=\"firstname\" value=\"John\"/>"
" <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>"
" <INPUT type=\"text\" id=\"email\" value=\"john@example.com\"/>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
"</FORM>");
WebFrame* web_frame = GetMainFrame();
ASSERT_NE(static_cast<WebFrame*>(NULL), web_frame);
FormManager form_manager;
std::vector<FormData> forms;
form_manager.ExtractForms(web_frame, &forms);
ASSERT_EQ(1U, forms.size());
// Get the input element we want to find.
WebElement element = web_frame->document().getElementById("firstname");
WebInputElement input_element = element.to<WebInputElement>();
// Find the form and verify it's the correct form.
FormData form;
EXPECT_TRUE(form_manager.FindFormWithFormControlElement(input_element,
&form));
EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
EXPECT_EQ(GURL(web_frame->document().url()), form.origin);
EXPECT_EQ(GURL("http://buh.com"), form.action);
const std::vector<FormField>& fields = form.fields;
ASSERT_EQ(3U, fields.size());
FormField expected;
expected.form_control_type = ASCIIToUTF16("text");
expected.max_length = WebInputElement::defaultMaxLength();
expected.name = ASCIIToUTF16("firstname");
expected.value = ASCIIToUTF16("John");
EXPECT_FORM_FIELD_EQUALS(expected, fields[0]);
expected.name = ASCIIToUTF16("lastname");
expected.value = ASCIIToUTF16("Smith");
EXPECT_FORM_FIELD_EQUALS(expected, fields[1]);
expected.name = ASCIIToUTF16("email");
expected.value = ASCIIToUTF16("john@example.com");
EXPECT_FORM_FIELD_EQUALS(expected, fields[2]);
}
TEST_F(FormManagerTest, FillForm) {
LoadHTML("<FORM name=\"TestForm\" action=\"http://buh.com\" method=\"post\">"
" <INPUT type=\"text\" id=\"firstname\"/>"
" <INPUT type=\"text\" id=\"lastname\"/>"
" <INPUT type=\"hidden\" id=\"imhidden\"/>"
" <INPUT type=\"text\" id=\"notempty\" value=\"Hi\"/>"
" <INPUT type=\"text\" autocomplete=\"off\" id=\"noautocomplete\"/>"
" <INPUT type=\"text\" disabled=\"disabled\" id=\"notenabled\"/>"
" <INPUT type=\"text\" readonly id=\"readonly\"/>"
" <INPUT type=\"text\" style=\"visibility: hidden\""
" id=\"invisible\"/>"
" <INPUT type=\"text\" style=\"display: none\" id=\"displaynone\"/>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
"</FORM>");
WebFrame* web_frame = GetMainFrame();
ASSERT_NE(static_cast<WebFrame*>(NULL), web_frame);
FormManager form_manager;
std::vector<FormData> forms;
form_manager.ExtractForms(web_frame, &forms);
ASSERT_EQ(1U, forms.size());
// Get the input element we want to find.
WebElement element = web_frame->document().getElementById("firstname");
WebInputElement input_element = element.to<WebInputElement>();
// Find the form that contains the input element.
FormData form;
EXPECT_TRUE(form_manager.FindFormWithFormControlElement(input_element,
&form));
EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
EXPECT_EQ(GURL(web_frame->document().url()), form.origin);
EXPECT_EQ(GURL("http://buh.com"), form.action);
const std::vector<FormField>& fields = form.fields;
ASSERT_EQ(8U, fields.size());
FormField expected;
expected.form_control_type = ASCIIToUTF16("text");
expected.max_length = WebInputElement::defaultMaxLength();
expected.name = ASCIIToUTF16("firstname");
expected.value = string16();
EXPECT_FORM_FIELD_EQUALS(expected, fields[0]);
expected.name = ASCIIToUTF16("lastname");
expected.value = string16();
EXPECT_FORM_FIELD_EQUALS(expected, fields[1]);
expected.name = ASCIIToUTF16("notempty");
expected.value = ASCIIToUTF16("Hi");
EXPECT_FORM_FIELD_EQUALS(expected, fields[2]);
expected.name = ASCIIToUTF16("noautocomplete");
expected.value = string16();
EXPECT_FORM_FIELD_EQUALS(expected, fields[3]);
expected.name = ASCIIToUTF16("notenabled");
expected.value = string16();
EXPECT_FORM_FIELD_EQUALS(expected, fields[4]);
expected.name = ASCIIToUTF16("readonly");
expected.value = string16();
EXPECT_FORM_FIELD_EQUALS(expected, fields[5]);
expected.name = ASCIIToUTF16("invisible");
expected.value = string16();
EXPECT_FORM_FIELD_EQUALS(expected, fields[6]);
expected.name = ASCIIToUTF16("displaynone");
expected.value = string16();
EXPECT_FORM_FIELD_EQUALS(expected, fields[7]);
// Fill the form.
form.fields[0].value = ASCIIToUTF16("Wyatt");
form.fields[1].value = ASCIIToUTF16("Earp");
form.fields[2].value = ASCIIToUTF16("Alpha");
form.fields[3].value = ASCIIToUTF16("Beta");
form.fields[4].value = ASCIIToUTF16("Gamma");
form.fields[5].value = ASCIIToUTF16("Delta");
form.fields[6].value = ASCIIToUTF16("Epsilon");
form.fields[7].value = ASCIIToUTF16("Zeta");
form_manager.FillForm(form, input_element);
// Verify the filled elements.
WebDocument document = web_frame->document();
WebInputElement firstname =
document.getElementById("firstname").to<WebInputElement>();
EXPECT_TRUE(firstname.isAutofilled());
EXPECT_EQ(ASCIIToUTF16("Wyatt"), firstname.value());
EXPECT_EQ(5, firstname.selectionStart());
EXPECT_EQ(5, firstname.selectionEnd());
WebInputElement lastname =
document.getElementById("lastname").to<WebInputElement>();
EXPECT_TRUE(lastname.isAutofilled());
EXPECT_EQ(ASCIIToUTF16("Earp"), lastname.value());
// Non-empty fields are not filled.
WebInputElement notempty =
document.getElementById("notempty").to<WebInputElement>();
EXPECT_FALSE(notempty.isAutofilled());
EXPECT_EQ(ASCIIToUTF16("Hi"), notempty.value());
// autocomplete=off fields are not filled.
WebInputElement noautocomplete =
document.getElementById("noautocomplete").to<WebInputElement>();
EXPECT_FALSE(noautocomplete.isAutofilled());
EXPECT_TRUE(noautocomplete.value().isEmpty());
// Disabled fields are not filled.
WebInputElement notenabled =
document.getElementById("notenabled").to<WebInputElement>();
EXPECT_FALSE(notenabled.isAutofilled());
EXPECT_TRUE(notenabled.value().isEmpty());
// Read-only fields are not filled.
WebInputElement readonly =
document.getElementById("readonly").to<WebInputElement>();
EXPECT_FALSE(readonly.isAutofilled());
EXPECT_TRUE(readonly.value().isEmpty());
// |visibility:hidden| fields are not filled.
WebInputElement invisible =
document.getElementById("invisible").to<WebInputElement>();
EXPECT_FALSE(invisible.isAutofilled());
EXPECT_TRUE(invisible.value().isEmpty());
// |display:none| fields are not filled.
WebInputElement display_none =
document.getElementById("displaynone").to<WebInputElement>();
EXPECT_FALSE(display_none.isAutofilled());
EXPECT_TRUE(display_none.value().isEmpty());
}
TEST_F(FormManagerTest, PreviewForm) {
LoadHTML("<FORM name=\"TestForm\" action=\"http://buh.com\" method=\"post\">"
" <INPUT type=\"text\" id=\"firstname\"/>"
" <INPUT type=\"text\" id=\"lastname\"/>"
" <INPUT type=\"text\" id=\"notempty\" value=\"Hi\"/>"
" <INPUT type=\"text\" autocomplete=\"off\" id=\"noautocomplete\"/>"
" <INPUT type=\"text\" disabled=\"disabled\" id=\"notenabled\"/>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
"</FORM>");
WebFrame* web_frame = GetMainFrame();
ASSERT_NE(static_cast<WebFrame*>(NULL), web_frame);
FormManager form_manager;
std::vector<FormData> forms;
form_manager.ExtractForms(web_frame, &forms);
ASSERT_EQ(1U, forms.size());
// Get the input element we want to find.
WebElement element = web_frame->document().getElementById("firstname");
WebInputElement input_element = element.to<WebInputElement>();
// Find the form that contains the input element.
FormData form;
EXPECT_TRUE(form_manager.FindFormWithFormControlElement(input_element,
&form));
EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
EXPECT_EQ(GURL(web_frame->document().url()), form.origin);
EXPECT_EQ(GURL("http://buh.com"), form.action);
const std::vector<FormField>& fields = form.fields;
ASSERT_EQ(5U, fields.size());
FormField expected;
expected.form_control_type = ASCIIToUTF16("text");
expected.max_length = WebInputElement::defaultMaxLength();
expected.name = ASCIIToUTF16("firstname");
expected.value = string16();
EXPECT_FORM_FIELD_EQUALS(expected, fields[0]);
expected.name = ASCIIToUTF16("lastname");
expected.value = string16();
EXPECT_FORM_FIELD_EQUALS(expected, fields[1]);
expected.name = ASCIIToUTF16("notempty");
expected.value = ASCIIToUTF16("Hi");
EXPECT_FORM_FIELD_EQUALS(expected, fields[2]);
expected.name = ASCIIToUTF16("noautocomplete");
expected.value = string16();
EXPECT_FORM_FIELD_EQUALS(expected, fields[3]);
expected.name = ASCIIToUTF16("notenabled");
expected.value = string16();
EXPECT_FORM_FIELD_EQUALS(expected, fields[4]);
// Preview the form.
form.fields[0].value = ASCIIToUTF16("Wyatt");
form.fields[1].value = ASCIIToUTF16("Earp");
form.fields[2].value = ASCIIToUTF16("Alpha");
form.fields[3].value = ASCIIToUTF16("Beta");
form.fields[4].value = ASCIIToUTF16("Gamma");
form_manager.PreviewForm(form, input_element);
// Verify the previewed elements.
WebDocument document = web_frame->document();
WebInputElement firstname =
document.getElementById("firstname").to<WebInputElement>();
EXPECT_TRUE(firstname.isAutofilled());
EXPECT_EQ(ASCIIToUTF16("Wyatt"), firstname.suggestedValue());
EXPECT_EQ(0, firstname.selectionStart());
EXPECT_EQ(5, firstname.selectionEnd());
WebInputElement lastname =
document.getElementById("lastname").to<WebInputElement>();
EXPECT_TRUE(lastname.isAutofilled());
EXPECT_EQ(ASCIIToUTF16("Earp"), lastname.suggestedValue());
// Non-empty fields are not previewed.
WebInputElement notempty =
document.getElementById("notempty").to<WebInputElement>();
EXPECT_FALSE(notempty.isAutofilled());
EXPECT_TRUE(notempty.suggestedValue().isEmpty());
// autocomplete=off fields are not previewed.
WebInputElement noautocomplete =
document.getElementById("noautocomplete").to<WebInputElement>();
EXPECT_FALSE(noautocomplete.isAutofilled());
EXPECT_TRUE(noautocomplete.suggestedValue().isEmpty());
// Disabled fields are not previewed.
WebInputElement notenabled =
document.getElementById("notenabled").to<WebInputElement>();
EXPECT_FALSE(notenabled.isAutofilled());
EXPECT_TRUE(notenabled.suggestedValue().isEmpty());
}
TEST_F(FormManagerTest, Labels) {
ExpectJohnSmithLabels(
"<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
" <LABEL for=\"firstname\"> First name: </LABEL>"
" <INPUT type=\"text\" id=\"firstname\" value=\"John\"/>"
" <LABEL for=\"lastname\"> Last name: </LABEL>"
" <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>"
" <LABEL for=\"email\"> Email: </LABEL>"
" <INPUT type=\"text\" id=\"email\" value=\"john@example.com\"/>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
"</FORM>");
}
TEST_F(FormManagerTest, LabelsWithSpans) {
ExpectJohnSmithLabels(
"<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
" <LABEL for=\"firstname\"><span>First name: </span></LABEL>"
" <INPUT type=\"text\" id=\"firstname\" value=\"John\"/>"
" <LABEL for=\"lastname\"><span>Last name: </span></LABEL>"
" <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>"
" <LABEL for=\"email\"><span>Email: </span></LABEL>"
" <INPUT type=\"text\" id=\"email\" value=\"john@example.com\"/>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
"</FORM>");
}
// This test is different from FormManagerTest.Labels in that the label elements
// for= attribute is set to the name of the form control element it is a label
// for instead of the id of the form control element. This is invalid because
// the for= attribute must be set to the id of the form control element;
// however, current label parsing code will extract the text from the previous
// label element and apply it to the following input field.
TEST_F(FormManagerTest, InvalidLabels) {
ExpectJohnSmithLabels(
"<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
" <LABEL for=\"firstname\"> First name: </LABEL>"
" <INPUT type=\"text\" name=\"firstname\" value=\"John\"/>"
" <LABEL for=\"lastname\"> Last name: </LABEL>"
" <INPUT type=\"text\" name=\"lastname\" value=\"Smith\"/>"
" <LABEL for=\"email\"> Email: </LABEL>"
" <INPUT type=\"text\" name=\"email\" value=\"john@example.com\"/>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
"</FORM>");
}
// This test has three form control elements, only one of which has a label
// element associated with it.
TEST_F(FormManagerTest, OneLabelElement) {
ExpectJohnSmithLabels(
"<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
" First name:"
" <INPUT type=\"text\" id=\"firstname\" value=\"John\"/>"
" <LABEL for=\"lastname\">Last name: </LABEL>"
" <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>"
" Email:"
" <INPUT type=\"text\" id=\"email\" value=\"john@example.com\"/>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
"</FORM>");
}
TEST_F(FormManagerTest, LabelsInferredFromText) {
ExpectJohnSmithLabels(
"<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
" First name:"
" <INPUT type=\"text\" id=\"firstname\" value=\"John\"/>"
" Last name:"
" <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>"
" Email:"
" <INPUT type=\"text\" id=\"email\" value=\"john@example.com\"/>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
"</FORM>");
}
TEST_F(FormManagerTest, LabelsInferredFromParagraph) {
ExpectJohnSmithLabels(
"<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
" <P>First name:</P><INPUT type=\"text\" "
" id=\"firstname\" value=\"John\"/>"
" <P>Last name:</P>"
" <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>"
" <P>Email:</P>"
" <INPUT type=\"text\" id=\"email\" value=\"john@example.com\"/>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
"</FORM>");
}
TEST_F(FormManagerTest, LabelsInferredFromBold) {
ExpectJohnSmithLabels(
"<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
" <B>First name:</B><INPUT type=\"text\" "
" id=\"firstname\" value=\"John\"/>"
" <B>Last name:</B>"
" <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>"
" <B>Email:</B>"
" <INPUT type=\"text\" id=\"email\" value=\"john@example.com\"/>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
"</FORM>");
}
TEST_F(FormManagerTest, LabelsInferredPriorToImgOrBr) {
ExpectJohnSmithLabels(
"<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
" First name:<IMG/><INPUT type=\"text\" "
" id=\"firstname\" value=\"John\"/>"
" Last name:<IMG/>"
" <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>"
" Email:<BR/>"
" <INPUT type=\"text\" id=\"email\" value=\"john@example.com\"/>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
"</FORM>");
}
TEST_F(FormManagerTest, LabelsInferredFromTableCell) {
ExpectJohnSmithLabels(
"<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
"<TABLE>"
" <TR>"
" <TD>First name:</TD>"
" <TD><INPUT type=\"text\" id=\"firstname\" value=\"John\"/></TD>"
" </TR>"
" <TR>"
" <TD>Last name:</TD>"
" <TD><INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/></TD>"
" </TR>"
" <TR>"
" <TD>Email:</TD>"
" <TD><INPUT type=\"text\" id=\"email\""
" value=\"john@example.com\"/></TD>"
" </TR>"
" <TR>"
" <TD></TD>"
" <TD>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
" </TD>"
" </TR>"
"</TABLE>"
"</FORM>");
}
TEST_F(FormManagerTest, LabelsInferredFromTableCellTH) {
ExpectJohnSmithLabels(
"<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
"<TABLE>"
" <TR>"
" <TH>First name:</TH>"
" <TD><INPUT type=\"text\" id=\"firstname\" value=\"John\"/></TD>"
" </TR>"
" <TR>"
" <TH>Last name:</TH>"
" <TD><INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/></TD>"
" </TR>"
" <TR>"
" <TH>Email:</TH>"
" <TD><INPUT type=\"text\" id=\"email\""
" value=\"john@example.com\"/></TD>"
" </TR>"
" <TR>"
" <TD></TD>"
" <TD>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
" </TD>"
" </TR>"
"</TABLE>"
"</FORM>");
}
TEST_F(FormManagerTest, LabelsInferredFromTableCellNested) {
std::vector<string16> labels, names, values;
labels.push_back(ASCIIToUTF16("First name: Bogus"));
names.push_back(ASCIIToUTF16("firstname"));
values.push_back(ASCIIToUTF16("John"));
labels.push_back(ASCIIToUTF16("Last name:"));
names.push_back(ASCIIToUTF16("lastname"));
values.push_back(ASCIIToUTF16("Smith"));
labels.push_back(ASCIIToUTF16("Email:"));
names.push_back(ASCIIToUTF16("email"));
values.push_back(ASCIIToUTF16("john@example.com"));
ExpectLabels(
"<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
"<TABLE>"
" <TR>"
" <TD>"
" <FONT>"
" First name:"
" </FONT>"
" <FONT>"
" Bogus"
" </FONT>"
" </TD>"
" <TD>"
" <FONT>"
" <INPUT type=\"text\" id=\"firstname\" value=\"John\"/>"
" </FONT>"
" </TD>"
" </TR>"
" <TR>"
" <TD>"
" <FONT>"
" Last name:"
" </FONT>"
" </TD>"
" <TD>"
" <FONT>"
" <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>"
" </FONT>"
" </TD>"
" </TR>"
" <TR>"
" <TD>"
" <FONT>"
" Email:"
" </FONT>"
" </TD>"
" <TD>"
" <FONT>"
" <INPUT type=\"text\" id=\"email\" value=\"john@example.com\"/>"
" </FONT>"
" </TD>"
" </TR>"
" <TR>"
" <TD></TD>"
" <TD>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
" </TD>"
" </TR>"
"</TABLE>"
"</FORM>",
labels, names, values);
}
TEST_F(FormManagerTest, LabelsInferredFromTableEmptyTDs) {
std::vector<string16> labels, names, values;
labels.push_back(ASCIIToUTF16("* First Name"));
names.push_back(ASCIIToUTF16("firstname"));
values.push_back(ASCIIToUTF16("John"));
labels.push_back(ASCIIToUTF16("* Last Name"));
names.push_back(ASCIIToUTF16("lastname"));
values.push_back(ASCIIToUTF16("Smith"));
labels.push_back(ASCIIToUTF16("* Email"));
names.push_back(ASCIIToUTF16("email"));
values.push_back(ASCIIToUTF16("john@example.com"));
ExpectLabels(
"<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
"<TABLE>"
" <TR>"
" <TD>"
" <SPAN>*</SPAN>"
" <B>First Name</B>"
" </TD>"
" <TD></TD>"
" <TD>"
" <INPUT type=\"text\" id=\"firstname\" value=\"John\"/>"
" </TD>"
" </TR>"
" <TR>"
" <TD>"
" <SPAN>*</SPAN>"
" <B>Last Name</B>"
" </TD>"
" <TD></TD>"
" <TD>"
" <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>"
" </TD>"
" </TR>"
" <TR>"
" <TD>"
" <SPAN>*</SPAN>"
" <B>Email</B>"
" </TD>"
" <TD></TD>"
" <TD>"
" <INPUT type=\"text\" id=\"email\" value=\"john@example.com\"/>"
" </TD>"
" </TR>"
" <TR>"
" <TD></TD>"
" <TD>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
" </TD>"
" </TR>"
"</TABLE>"
"</FORM>",
labels, names, values);
}
TEST_F(FormManagerTest, LabelsInferredFromPreviousTD) {
std::vector<string16> labels, names, values;
labels.push_back(ASCIIToUTF16("* First Name"));
names.push_back(ASCIIToUTF16("firstname"));
values.push_back(ASCIIToUTF16("John"));
labels.push_back(ASCIIToUTF16("* Last Name"));
names.push_back(ASCIIToUTF16("lastname"));
values.push_back(ASCIIToUTF16("Smith"));
labels.push_back(ASCIIToUTF16("* Email"));
names.push_back(ASCIIToUTF16("email"));
values.push_back(ASCIIToUTF16("john@example.com"));
ExpectLabels(
"<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
"<TABLE>"
" <TR>"
" <TD>* First Name</TD>"
" <TD>"
" Bogus"
" <INPUT type=\"hidden\"/>"
" <INPUT type=\"text\" id=\"firstname\" value=\"John\"/>"
" </TD>"
" </TR>"
" <TR>"
" <TD>* Last Name</TD>"
" <TD>"
" <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>"
" </TD>"
" </TR>"
" <TR>"
" <TD>* Email</TD>"
" <TD>"
" <INPUT type=\"text\" id=\"email\" value=\"john@example.com\"/>"
" </TD>"
" </TR>"
" <TR>"
" <TD></TD>"
" <TD>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
" </TD>"
" </TR>"
"</TABLE>"
"</FORM>",
labels, names, values);
}
// <script>, <noscript> and <option> tags are excluded when the labels are
// inferred.
// Also <!-- comment --> is excluded.
TEST_F(FormManagerTest, LabelsInferredFromTableWithSpecialElements) {
std::vector<string16> labels, names, values, control_types;
labels.push_back(ASCIIToUTF16("* First Name"));
names.push_back(ASCIIToUTF16("firstname"));
values.push_back(ASCIIToUTF16("John"));
control_types.push_back(ASCIIToUTF16("text"));
labels.push_back(ASCIIToUTF16("* Middle Name"));
names.push_back(ASCIIToUTF16("middlename"));
values.push_back(ASCIIToUTF16("Joe"));
control_types.push_back(ASCIIToUTF16("text"));
labels.push_back(ASCIIToUTF16("* Last Name"));
names.push_back(ASCIIToUTF16("lastname"));
values.push_back(ASCIIToUTF16("Smith"));
control_types.push_back(ASCIIToUTF16("text"));
labels.push_back(ASCIIToUTF16("* Country"));
names.push_back(ASCIIToUTF16("country"));
values.push_back(ASCIIToUTF16("US"));
control_types.push_back(ASCIIToUTF16("select-one"));
labels.push_back(ASCIIToUTF16("* Email"));
names.push_back(ASCIIToUTF16("email"));
values.push_back(ASCIIToUTF16("john@example.com"));
control_types.push_back(ASCIIToUTF16("text"));
ExpectLabelsAndTypes(
"<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
"<TABLE>"
" <TR>"
" <TD>"
" <SPAN>*</SPAN>"
" <B>First Name</B>"
" </TD>"
" <TD>"
" <SCRIPT> <!-- function test() { alert('ignored as label'); } -->"
" </SCRIPT>"
" <INPUT type=\"text\" id=\"firstname\" value=\"John\"/>"
" </TD>"
" </TR>"
" <TR>"
" <TD>"
" <SPAN>*</SPAN>"
" <B>Middle Name</B>"
" </TD>"
" <TD>"
" <NOSCRIPT>"
" <P>Bad</P>"
" </NOSCRIPT>"
" <INPUT type=\"text\" id=\"middlename\" value=\"Joe\"/>"
" </TD>"
" </TR>"
" <TR>"
" <TD>"
" <SPAN>*</SPAN>"
" <B>Last Name</B>"
" </TD>"
" <TD>"
" <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>"
" </TD>"
" </TR>"
" <TR>"
" <TD>"
" <SPAN>*</SPAN>"
" <B>Country</B>"
" </TD>"
" <TD>"
" <SELECT id=\"country\">"
" <OPTION VALUE=\"US\">The value should be ignored as label."
" </OPTION>"
" <OPTION VALUE=\"JP\">JAPAN</OPTION>"
" </SELECT>"
" </TD>"
" </TR>"
" <TR>"
" <TD>"
" <SPAN>*</SPAN>"
" <B>Email</B>"
" </TD>"
" <TD>"
" <!-- This comment should be ignored as inferred label.-->"
" <INPUT type=\"text\" id=\"email\" value=\"john@example.com\"/>"
" </TD>"
" </TR>"
" <TR>"
" <TD></TD>"
" <TD>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
" </TD>"
" </TR>"
"</TABLE>"
"</FORM>",
labels, names, values, control_types);
}
TEST_F(FormManagerTest, LabelsInferredFromTableLabels) {
ExpectJohnSmithLabels(
"<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
"<TABLE>"
" <TR>"
" <TD>"
" <LABEL>First name:</LABEL>"
" <INPUT type=\"text\" id=\"firstname\" value=\"John\"/>"
" </TD>"
" </TR>"
" <TR>"
" <TD>"
" <LABEL>Last name:</LABEL>"
" <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>"
" </TD>"
" </TR>"
" <TR>"
" <TD>"
" <LABEL>Email:</LABEL>"
" <INPUT type=\"text\" id=\"email\" value=\"john@example.com\"/>"
" </TD>"
" </TR>"
"</TABLE>"
"<INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
"</FORM>");
}
TEST_F(FormManagerTest, LabelsInferredFromTableTDInterveningElements) {
ExpectJohnSmithLabels(
"<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
"<TABLE>"
" <TR>"
" <TD>"
" First name:"
" <BR>"
" <INPUT type=\"text\" id=\"firstname\" value=\"John\"/>"
" </TD>"
" </TR>"
" <TR>"
" <TD>"
" Last name:"
" <BR>"
" <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>"
" </TD>"
" </TR>"
" <TR>"
" <TD>"
" Email:"
" <BR>"
" <INPUT type=\"text\" id=\"email\" value=\"john@example.com\"/>"
" </TD>"
" </TR>"
"</TABLE>"
"<INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
"</FORM>");
}
// Verify that we correctly infer labels when the label text spans multiple
// adjacent HTML elements, not separated by whitespace.
TEST_F(FormManagerTest, LabelsInferredFromTableAdjacentElements) {
std::vector<string16> labels, names, values;
labels.push_back(ASCIIToUTF16("*First Name"));
names.push_back(ASCIIToUTF16("firstname"));
values.push_back(ASCIIToUTF16("John"));
labels.push_back(ASCIIToUTF16("*Last Name"));
names.push_back(ASCIIToUTF16("lastname"));
values.push_back(ASCIIToUTF16("Smith"));
labels.push_back(ASCIIToUTF16("*Email"));
names.push_back(ASCIIToUTF16("email"));
values.push_back(ASCIIToUTF16("john@example.com"));
ExpectLabels(
"<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
"<TABLE>"
" <TR>"
" <TD>"
" <SPAN>*</SPAN><B>First Name</B>"
" </TD>"
" <TD>"
" <INPUT type=\"text\" id=\"firstname\" value=\"John\"/>"
" </TD>"
" </TR>"
" <TR>"
" <TD>"
" <SPAN>*</SPAN><B>Last Name</B>"
" </TD>"
" <TD>"
" <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>"
" </TD>"
" </TR>"
" <TR>"
" <TD>"
" <SPAN>*</SPAN><B>Email</B>"
" </TD>"
" <TD>"
" <INPUT type=\"text\" id=\"email\" value=\"john@example.com\"/>"
" </TD>"
" </TR>"
" <TR>"
" <TD>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
" </TD>"
" </TR>"
"</TABLE>"
"</FORM>",
labels, names, values);
}
// Verify that we correctly infer labels when the label text resides in the
// previous row.
TEST_F(FormManagerTest, LabelsInferredFromTableRow) {
std::vector<string16> labels, names, values;
labels.push_back(ASCIIToUTF16("*First Name *Last Name *Email"));
names.push_back(ASCIIToUTF16("firstname"));
values.push_back(ASCIIToUTF16("John"));
labels.push_back(ASCIIToUTF16("*First Name *Last Name *Email"));
names.push_back(ASCIIToUTF16("lastname"));
values.push_back(ASCIIToUTF16("Smith"));
labels.push_back(ASCIIToUTF16("*First Name *Last Name *Email"));
names.push_back(ASCIIToUTF16("email"));
values.push_back(ASCIIToUTF16("john@example.com"));
ExpectLabels(
"<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
"<TABLE>"
" <TR>"
" <TD>*First Name</TD>"
" <TD>*Last Name</TD>"
" <TD>*Email</TD>"
" </TR>"
" <TR>"
" <TD>"
" <INPUT type=\"text\" id=\"firstname\" value=\"John\"/>"
" </TD>"
" <TD>"
" <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>"
" </TD>"
" <TD>"
" <INPUT type=\"text\" id=\"email\" value=\"john@example.com\"/>"
" </TD>"
" </TR>"
" <TR>"
" <TD>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
" </TD>"
" </TR>"
"</TABLE>",
labels, names, values);
}
// Verify that we correctly infer labels when enclosed within a list item.
TEST_F(FormManagerTest, LabelsInferredFromListItem) {
std::vector<string16> labels, names, values;
labels.push_back(ASCIIToUTF16("* Home Phone"));
names.push_back(ASCIIToUTF16("areacode"));
values.push_back(ASCIIToUTF16("415"));
labels.push_back(ASCIIToUTF16("* Home Phone"));
names.push_back(ASCIIToUTF16("prefix"));
values.push_back(ASCIIToUTF16("555"));
labels.push_back(ASCIIToUTF16("* Home Phone"));
names.push_back(ASCIIToUTF16("suffix"));
values.push_back(ASCIIToUTF16("1212"));
ExpectLabels(
"<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
"<DIV>"
" <LI>"
" <SPAN>Bogus</SPAN>"
" </LI>"
" <LI>"
" <LABEL><EM>*</EM> Home Phone</LABEL>"
" <INPUT type=\"text\" id=\"areacode\" value=\"415\"/>"
" <INPUT type=\"text\" id=\"prefix\" value=\"555\"/>"
" <INPUT type=\"text\" id=\"suffix\" value=\"1212\"/>"
" </LI>"
" <LI>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
" </LI>"
"</DIV>"
"</FORM>",
labels, names, values);
}
TEST_F(FormManagerTest, LabelsInferredFromDefinitionList) {
std::vector<string16> labels, names, values;
labels.push_back(ASCIIToUTF16("* First name: Bogus"));
names.push_back(ASCIIToUTF16("firstname"));
values.push_back(ASCIIToUTF16("John"));
labels.push_back(ASCIIToUTF16("Last name:"));
names.push_back(ASCIIToUTF16("lastname"));
values.push_back(ASCIIToUTF16("Smith"));
labels.push_back(ASCIIToUTF16("Email:"));
names.push_back(ASCIIToUTF16("email"));
values.push_back(ASCIIToUTF16("john@example.com"));
ExpectLabels(
"<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
"<DL>"
" <DT>"
" <SPAN>"
" *"
" </SPAN>"
" <SPAN>"
" First name:"
" </SPAN>"
" <SPAN>"
" Bogus"
" </SPAN>"
" </DT>"
" <DD>"
" <FONT>"
" <INPUT type=\"text\" id=\"firstname\" value=\"John\"/>"
" </FONT>"
" </DD>"
" <DT>"
" <SPAN>"
" Last name:"
" </SPAN>"
" </DT>"
" <DD>"
" <FONT>"
" <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>"
" </FONT>"
" </DD>"
" <DT>"
" <SPAN>"
" Email:"
" </SPAN>"
" </DT>"
" <DD>"
" <FONT>"
" <INPUT type=\"text\" id=\"email\" value=\"john@example.com\"/>"
" </FONT>"
" </DD>"
" <DT></DT>"
" <DD>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
" </DD>"
"</DL>"
"</FORM>",
labels, names, values);
}
TEST_F(FormManagerTest, LabelsInferredWithSameName) {
std::vector<string16> labels, names, values;
labels.push_back(ASCIIToUTF16("Address Line 1:"));
names.push_back(ASCIIToUTF16("Address"));
values.push_back(string16());
labels.push_back(ASCIIToUTF16("Address Line 2:"));
names.push_back(ASCIIToUTF16("Address"));
values.push_back(string16());
labels.push_back(ASCIIToUTF16("Address Line 3:"));
names.push_back(ASCIIToUTF16("Address"));
values.push_back(string16());
ExpectLabels(
"<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
" Address Line 1:"
" <INPUT type=\"text\" name=\"Address\"/>"
" Address Line 2:"
" <INPUT type=\"text\" name=\"Address\"/>"
" Address Line 3:"
" <INPUT type=\"text\" name=\"Address\"/>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
"</FORM>",
labels, names, values);
}
TEST_F(FormManagerTest, LabelsInferredWithImageTags) {
std::vector<string16> labels, names, values;
labels.push_back(ASCIIToUTF16("Phone:"));
names.push_back(ASCIIToUTF16("dayphone1"));
values.push_back(string16());
labels.push_back(ASCIIToUTF16("-"));
names.push_back(ASCIIToUTF16("dayphone2"));
values.push_back(string16());
labels.push_back(ASCIIToUTF16("-"));
names.push_back(ASCIIToUTF16("dayphone3"));
values.push_back(string16());
labels.push_back(ASCIIToUTF16("ext.:"));
names.push_back(ASCIIToUTF16("dayphone4"));
values.push_back(string16());
labels.push_back(string16());
names.push_back(ASCIIToUTF16("dummy"));
values.push_back(string16());
ExpectLabels(
"<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
" Phone:"
" <input type=\"text\" name=\"dayphone1\">"
" <img/>"
" -"
" <img/>"
" <input type=\"text\" name=\"dayphone2\">"
" <img/>"
" -"
" <img/>"
" <input type=\"text\" name=\"dayphone3\">"
" ext.:"
" <input type=\"text\" name=\"dayphone4\">"
" <input type=\"text\" name=\"dummy\">"
" <input type=\"submit\" name=\"reply-send\" value=\"Send\">"
"</FORM>",
labels, names, values);
}
TEST_F(FormManagerTest, LabelsInferredFromDivTable) {
ExpectJohnSmithLabels(
"<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
"<DIV>First name:<BR>"
" <SPAN>"
" <INPUT type=\"text\" name=\"firstname\" value=\"John\">"
" </SPAN>"
"</DIV>"
"<DIV>Last name:<BR>"
" <SPAN>"
" <INPUT type=\"text\" name=\"lastname\" value=\"Smith\">"
" </SPAN>"
"</DIV>"
"<DIV>Email:<BR>"
" <SPAN>"
" <INPUT type=\"text\" name=\"email\" value=\"john@example.com\">"
" </SPAN>"
"</DIV>"
"<input type=\"submit\" name=\"reply-send\" value=\"Send\">"
"</FORM>");
}
TEST_F(FormManagerTest, LabelsInferredFromDivSiblingTable) {
ExpectJohnSmithLabels(
"<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
"<DIV>First name:</DIV>"
"<DIV>"
" <SPAN>"
" <INPUT type=\"text\" name=\"firstname\" value=\"John\">"
" </SPAN>"
"</DIV>"
"<DIV>Last name:</DIV>"
"<DIV>"
" <SPAN>"
" <INPUT type=\"text\" name=\"lastname\" value=\"Smith\">"
" </SPAN>"
"</DIV>"
"<DIV>Email:</DIV>"
"<DIV>"
" <SPAN>"
" <INPUT type=\"text\" name=\"email\" value=\"john@example.com\">"
" </SPAN>"
"</DIV>"
"<input type=\"submit\" name=\"reply-send\" value=\"Send\">"
"</FORM>");
}
TEST_F(FormManagerTest, LabelsInferredFromDefinitionListRatherThanDivTable) {
ExpectJohnSmithLabels(
"<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
"<DIV>This is not a label.<BR>"
"<DL>"
" <DT>"
" <SPAN>"
" First name:"
" </SPAN>"
" </DT>"
" <DD>"
" <FONT>"
" <INPUT type=\"text\" id=\"firstname\" value=\"John\"/>"
" </FONT>"
" </DD>"
" <DT>"
" <SPAN>"
" Last name:"
" </SPAN>"
" </DT>"
" <DD>"
" <FONT>"
" <INPUT type=\"text\" id=\"lastname\" value=\"Smith\"/>"
" </FONT>"
" </DD>"
" <DT>"
" <SPAN>"
" Email:"
" </SPAN>"
" </DT>"
" <DD>"
" <FONT>"
" <INPUT type=\"text\" id=\"email\" value=\"john@example.com\"/>"
" </FONT>"
" </DD>"
" <DT></DT>"
" <DD>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
" </DD>"
"</DL>"
"</DIV>"
"</FORM>");
}
TEST_F(FormManagerTest, FillFormMaxLength) {
LoadHTML("<FORM name=\"TestForm\" action=\"http://buh.com\" method=\"post\">"
" <INPUT type=\"text\" id=\"firstname\" maxlength=\"5\"/>"
" <INPUT type=\"text\" id=\"lastname\" maxlength=\"7\"/>"
" <INPUT type=\"text\" id=\"email\" maxlength=\"9\"/>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
"</FORM>");
WebFrame* web_frame = GetMainFrame();
ASSERT_NE(static_cast<WebFrame*>(NULL), web_frame);
FormManager form_manager;
std::vector<FormData> forms;
form_manager.ExtractForms(web_frame, &forms);
ASSERT_EQ(1U, forms.size());
// Get the input element we want to find.
WebElement element = web_frame->document().getElementById("firstname");
WebInputElement input_element = element.to<WebInputElement>();
// Find the form that contains the input element.
FormData form;
EXPECT_TRUE(form_manager.FindFormWithFormControlElement(input_element,
&form));
EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
EXPECT_EQ(GURL(web_frame->document().url()), form.origin);
EXPECT_EQ(GURL("http://buh.com"), form.action);
const std::vector<FormField>& fields = form.fields;
ASSERT_EQ(3U, fields.size());
FormField expected;
expected.form_control_type = ASCIIToUTF16("text");
expected.name = ASCIIToUTF16("firstname");
expected.max_length = 5;
expected.is_autofilled = false;
EXPECT_FORM_FIELD_EQUALS(expected, fields[0]);
expected.name = ASCIIToUTF16("lastname");
expected.max_length = 7;
expected.is_autofilled = false;
EXPECT_FORM_FIELD_EQUALS(expected, fields[1]);
expected.name = ASCIIToUTF16("email");
expected.max_length = 9;
expected.is_autofilled = false;
EXPECT_FORM_FIELD_EQUALS(expected, fields[2]);
// Fill the form.
form.fields[0].value = ASCIIToUTF16("Brother");
form.fields[1].value = ASCIIToUTF16("Jonathan");
form.fields[2].value = ASCIIToUTF16("brotherj@example.com");
form_manager.FillForm(form, WebNode());
// Find the newly-filled form that contains the input element.
FormData form2;
EXPECT_TRUE(form_manager.FindFormWithFormControlElement(input_element,
&form2));
EXPECT_EQ(ASCIIToUTF16("TestForm"), form2.name);
EXPECT_EQ(GURL(web_frame->document().url()), form2.origin);
EXPECT_EQ(GURL("http://buh.com"), form2.action);
const std::vector<FormField>& fields2 = form2.fields;
ASSERT_EQ(3U, fields2.size());
expected.form_control_type = ASCIIToUTF16("text");
expected.name = ASCIIToUTF16("firstname");
expected.value = ASCIIToUTF16("Broth");
expected.max_length = 5;
expected.is_autofilled = true;
EXPECT_FORM_FIELD_EQUALS(expected, fields2[0]);
expected.name = ASCIIToUTF16("lastname");
expected.value = ASCIIToUTF16("Jonatha");
expected.max_length = 7;
expected.is_autofilled = true;
EXPECT_FORM_FIELD_EQUALS(expected, fields2[1]);
expected.name = ASCIIToUTF16("email");
expected.value = ASCIIToUTF16("brotherj@");
expected.max_length = 9;
expected.is_autofilled = true;
EXPECT_FORM_FIELD_EQUALS(expected, fields2[2]);
}
// This test uses negative values of the maxlength attribute for input elements.
// In this case, the maxlength of the input elements is set to the default
// maxlength (defined in WebKit.)
TEST_F(FormManagerTest, FillFormNegativeMaxLength) {
LoadHTML("<FORM name=\"TestForm\" action=\"http://buh.com\" method=\"post\">"
" <INPUT type=\"text\" id=\"firstname\" maxlength=\"-1\"/>"
" <INPUT type=\"text\" id=\"lastname\" maxlength=\"-10\"/>"
" <INPUT type=\"text\" id=\"email\" maxlength=\"-13\"/>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
"</FORM>");
WebFrame* web_frame = GetMainFrame();
ASSERT_NE(static_cast<WebFrame*>(NULL), web_frame);
FormManager form_manager;
std::vector<FormData> forms;
form_manager.ExtractForms(web_frame, &forms);
ASSERT_EQ(1U, forms.size());
// Get the input element we want to find.
WebElement element = web_frame->document().getElementById("firstname");
WebInputElement input_element = element.to<WebInputElement>();
// Find the form that contains the input element.
FormData form;
EXPECT_TRUE(form_manager.FindFormWithFormControlElement(input_element,
&form));
EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
EXPECT_EQ(GURL(web_frame->document().url()), form.origin);
EXPECT_EQ(GURL("http://buh.com"), form.action);
const std::vector<FormField>& fields = form.fields;
ASSERT_EQ(3U, fields.size());
FormField expected;
expected.form_control_type = ASCIIToUTF16("text");
expected.max_length = WebInputElement::defaultMaxLength();
expected.name = ASCIIToUTF16("firstname");
EXPECT_FORM_FIELD_EQUALS(expected, fields[0]);
expected.name = ASCIIToUTF16("lastname");
EXPECT_FORM_FIELD_EQUALS(expected, fields[1]);
expected.name = ASCIIToUTF16("email");
EXPECT_FORM_FIELD_EQUALS(expected, fields[2]);
// Fill the form.
form.fields[0].value = ASCIIToUTF16("Brother");
form.fields[1].value = ASCIIToUTF16("Jonathan");
form.fields[2].value = ASCIIToUTF16("brotherj@example.com");
form_manager.FillForm(form, WebNode());
// Find the newly-filled form that contains the input element.
FormData form2;
EXPECT_TRUE(form_manager.FindFormWithFormControlElement(input_element,
&form2));
EXPECT_EQ(ASCIIToUTF16("TestForm"), form2.name);
EXPECT_EQ(GURL(web_frame->document().url()), form2.origin);
EXPECT_EQ(GURL("http://buh.com"), form2.action);
const std::vector<FormField>& fields2 = form2.fields;
ASSERT_EQ(3U, fields2.size());
expected.name = ASCIIToUTF16("firstname");
expected.value = ASCIIToUTF16("Brother");
EXPECT_FORM_FIELD_EQUALS(expected, fields[0]);
expected.name = ASCIIToUTF16("lastname");
expected.value = ASCIIToUTF16("Jonathan");
EXPECT_FORM_FIELD_EQUALS(expected, fields[1]);
expected.name = ASCIIToUTF16("email");
expected.value = ASCIIToUTF16("brotherj@example.com");
EXPECT_FORM_FIELD_EQUALS(expected, fields[2]);
}
// This test sends a FormData object to FillForm with more fields than are in
// the cached WebFormElement. In this case, we only fill out the fields that
// match between the FormData object and the WebFormElement.
TEST_F(FormManagerTest, FillFormMoreFormDataFields) {
LoadHTML("<FORM name=\"TestForm\" action=\"http://buh.com\" method=\"post\">"
" <INPUT type=\"text\" id=\"firstname\"/>"
" <INPUT type=\"text\" id=\"middlename\"/>"
" <INPUT type=\"text\" id=\"lastname\"/>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
"</FORM>");
WebFrame* web_frame = GetMainFrame();
ASSERT_NE(static_cast<WebFrame*>(NULL), web_frame);
FormManager form_manager;
std::vector<FormData> forms;
form_manager.ExtractForms(web_frame, &forms);
ASSERT_EQ(1U, forms.size());
// After the field modification, the fields in |form| will look like:
// prefix
// firstname
// hidden
// middlename
// second
// lastname
// postfix
FormData* form = &forms[0];
FormField field1;
field1.name = ASCIIToUTF16("prefix");
field1.form_control_type = ASCIIToUTF16("text");
field1.max_length = WebInputElement::defaultMaxLength();
form->fields.insert(form->fields.begin(), field1);
FormField field2;
field2.name = ASCIIToUTF16("hidden");
field2.form_control_type = ASCIIToUTF16("text");
field2.max_length = WebInputElement::defaultMaxLength();
form->fields.insert(form->fields.begin() + 2, field2);
FormField field3;
field3.name = ASCIIToUTF16("second");
field3.form_control_type = ASCIIToUTF16("text");
field3.max_length = WebInputElement::defaultMaxLength();
form->fields.insert(form->fields.begin() + 4, field3);
FormField field4;
field4.name = ASCIIToUTF16("postfix");
field4.form_control_type = ASCIIToUTF16("text");
field4.max_length = WebInputElement::defaultMaxLength();
form->fields.insert(form->fields.begin() + 6, field4);
// Fill the form.
form->fields[0].value = ASCIIToUTF16("Alpha");
form->fields[1].value = ASCIIToUTF16("Brother");
form->fields[2].value = ASCIIToUTF16("Abracadabra");
form->fields[3].value = ASCIIToUTF16("Joseph");
form->fields[4].value = ASCIIToUTF16("Beta");
form->fields[5].value = ASCIIToUTF16("Jonathan");
form->fields[6].value = ASCIIToUTF16("Omega");
form_manager.FillForm(*form, WebNode());
// Get the input element we want to find.
WebElement element = web_frame->document().getElementById("firstname");
WebInputElement input_element = element.to<WebInputElement>();
// Find the newly-filled form that contains the input element.
FormData form2;
EXPECT_TRUE(form_manager.FindFormWithFormControlElement(input_element,
&form2));
EXPECT_EQ(ASCIIToUTF16("TestForm"), form2.name);
EXPECT_EQ(GURL(web_frame->document().url()), form2.origin);
EXPECT_EQ(GURL("http://buh.com"), form2.action);
const std::vector<FormField>& fields = form2.fields;
ASSERT_EQ(3U, fields.size());
FormField expected;
expected.form_control_type = ASCIIToUTF16("text");
expected.max_length = WebInputElement::defaultMaxLength();
expected.is_autofilled = true;
expected.name = ASCIIToUTF16("firstname");
expected.value = ASCIIToUTF16("Brother");
EXPECT_FORM_FIELD_EQUALS(expected, fields[0]);
expected.name = ASCIIToUTF16("middlename");
expected.value = ASCIIToUTF16("Joseph");
EXPECT_FORM_FIELD_EQUALS(expected, fields[1]);
expected.name = ASCIIToUTF16("lastname");
expected.value = ASCIIToUTF16("Jonathan");
EXPECT_FORM_FIELD_EQUALS(expected, fields[2]);
}
// This test sends a FormData object to FillForm with fewer fields than are in
// the cached WebFormElement. In this case, we only fill out the fields that
// match between the FormData object and the WebFormElement.
TEST_F(FormManagerTest, FillFormFewerFormDataFields) {
LoadHTML("<FORM name=\"TestForm\" action=\"http://buh.com\" method=\"post\">"
" <INPUT type=\"text\" id=\"prefix\"/>"
" <INPUT type=\"text\" id=\"firstname\"/>"
" <INPUT type=\"text\" id=\"hidden\"/>"
" <INPUT type=\"text\" id=\"middlename\"/>"
" <INPUT type=\"text\" id=\"second\"/>"
" <INPUT type=\"text\" id=\"lastname\"/>"
" <INPUT type=\"text\" id=\"postfix\"/>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
"</FORM>");
WebFrame* web_frame = GetMainFrame();
ASSERT_NE(static_cast<WebFrame*>(NULL), web_frame);
FormManager form_manager;
std::vector<FormData> forms;
form_manager.ExtractForms(web_frame, &forms);
ASSERT_EQ(1U, forms.size());
// After the field modification, the fields in |form| will look like:
// firstname
// middlename
// lastname
FormData* form = &forms[0];
form->fields.erase(form->fields.begin());
form->fields.erase(form->fields.begin() + 1);
form->fields.erase(form->fields.begin() + 2);
form->fields.erase(form->fields.begin() + 3);
// Fill the form.
form->fields[0].value = ASCIIToUTF16("Brother");
form->fields[1].value = ASCIIToUTF16("Joseph");
form->fields[2].value = ASCIIToUTF16("Jonathan");
form_manager.FillForm(*form, WebNode());
// Get the input element we want to find.
WebElement element = web_frame->document().getElementById("firstname");
WebInputElement input_element = element.to<WebInputElement>();
// Find the newly-filled form that contains the input element.
FormData form2;
EXPECT_TRUE(form_manager.FindFormWithFormControlElement(input_element,
&form2));
EXPECT_EQ(ASCIIToUTF16("TestForm"), form2.name);
EXPECT_EQ(GURL(web_frame->document().url()), form2.origin);
EXPECT_EQ(GURL("http://buh.com"), form2.action);
const std::vector<FormField>& fields = form2.fields;
ASSERT_EQ(7U, fields.size());
FormField expected;
expected.form_control_type = ASCIIToUTF16("text");
expected.max_length = WebInputElement::defaultMaxLength();
expected.name = ASCIIToUTF16("prefix");
expected.value = string16();
expected.is_autofilled = false;
EXPECT_FORM_FIELD_EQUALS(expected, fields[0]);
expected.name = ASCIIToUTF16("firstname");
expected.value = ASCIIToUTF16("Brother");
expected.is_autofilled = true;
EXPECT_FORM_FIELD_EQUALS(expected, fields[1]);
expected.name = ASCIIToUTF16("hidden");
expected.value = string16();
expected.is_autofilled = false;
EXPECT_FORM_FIELD_EQUALS(expected, fields[2]);
expected.name = ASCIIToUTF16("middlename");
expected.value = ASCIIToUTF16("Joseph");
expected.is_autofilled = true;
EXPECT_FORM_FIELD_EQUALS(expected, fields[3]);
expected.name = ASCIIToUTF16("second");
expected.value = string16();
expected.is_autofilled = false;
EXPECT_FORM_FIELD_EQUALS(expected, fields[4]);
expected.name = ASCIIToUTF16("lastname");
expected.value = ASCIIToUTF16("Jonathan");
expected.is_autofilled = true;
EXPECT_FORM_FIELD_EQUALS(expected, fields[5]);
expected.name = ASCIIToUTF16("postfix");
expected.value = string16();
expected.is_autofilled = false;
EXPECT_FORM_FIELD_EQUALS(expected, fields[6]);
}
// This test sends a FormData object to FillForm with a field changed from
// those in the cached WebFormElement. In this case, we only fill out the
// fields that match between the FormData object and the WebFormElement.
TEST_F(FormManagerTest, FillFormChangedFormDataFields) {
LoadHTML("<FORM name=\"TestForm\" action=\"http://buh.com\" method=\"post\">"
" <INPUT type=\"text\" id=\"firstname\"/>"
" <INPUT type=\"text\" id=\"middlename\"/>"
" <INPUT type=\"text\" id=\"lastname\"/>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
"</FORM>");
WebFrame* web_frame = GetMainFrame();
ASSERT_NE(static_cast<WebFrame*>(NULL), web_frame);
FormManager form_manager;
std::vector<FormData> forms;
form_manager.ExtractForms(web_frame, &forms);
ASSERT_EQ(1U, forms.size());
// After the field modification, the fields in |form| will look like:
// firstname
// middlename
// lastname
FormData* form = &forms[0];
// Fill the form.
form->fields[0].value = ASCIIToUTF16("Brother");
form->fields[1].value = ASCIIToUTF16("Joseph");
form->fields[2].value = ASCIIToUTF16("Jonathan");
// Alter the label and name used for matching.
form->fields[1].label = ASCIIToUTF16("bogus");
form->fields[1].name = ASCIIToUTF16("bogus");
form_manager.FillForm(*form, WebNode());
// Get the input element we want to find.
WebElement element = web_frame->document().getElementById("firstname");
WebInputElement input_element = element.to<WebInputElement>();
// Find the newly-filled form that contains the input element.
FormData form2;
EXPECT_TRUE(form_manager.FindFormWithFormControlElement(input_element,
&form2));
EXPECT_EQ(ASCIIToUTF16("TestForm"), form2.name);
EXPECT_EQ(GURL(web_frame->document().url()), form2.origin);
EXPECT_EQ(GURL("http://buh.com"), form2.action);
const std::vector<FormField>& fields = form2.fields;
ASSERT_EQ(3U, fields.size());
FormField expected;
expected.form_control_type = ASCIIToUTF16("text");
expected.max_length = WebInputElement::defaultMaxLength();
expected.name = ASCIIToUTF16("firstname");
expected.value = ASCIIToUTF16("Brother");
expected.is_autofilled = true;
EXPECT_FORM_FIELD_EQUALS(expected, fields[0]);
expected.name = ASCIIToUTF16("middlename");
expected.value = ASCIIToUTF16("");
expected.is_autofilled = false;
EXPECT_FORM_FIELD_EQUALS(expected, fields[1]);
expected.name = ASCIIToUTF16("lastname");
expected.value = ASCIIToUTF16("Jonathan");
expected.is_autofilled = true;
EXPECT_FORM_FIELD_EQUALS(expected, fields[2]);
}
// This test sends a FormData object to FillForm with fewer fields than are in
// the cached WebFormElement. In this case, we only fill out the fields that
// match between the FormData object and the WebFormElement.
TEST_F(FormManagerTest, FillFormExtraFieldInCache) {
LoadHTML("<FORM name=\"TestForm\" action=\"http://buh.com\" method=\"post\">"
" <INPUT type=\"text\" id=\"firstname\"/>"
" <INPUT type=\"text\" id=\"middlename\"/>"
" <INPUT type=\"text\" id=\"lastname\"/>"
" <INPUT type=\"text\" id=\"postfix\"/>"
" <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\"/>"
"</FORM>");
WebFrame* web_frame = GetMainFrame();
ASSERT_NE(static_cast<WebFrame*>(NULL), web_frame);
FormManager form_manager;
std::vector<FormData> forms;
form_manager.ExtractForms(web_frame, &forms);
ASSERT_EQ(1U, forms.size());
// After the field modification, the fields in |form| will look like:
// firstname
// middlename
// lastname
FormData* form = &forms[0];
form->fields.pop_back();
// Fill the form.
form->fields[0].value = ASCIIToUTF16("Brother");
form->fields[1].value = ASCIIToUTF16("Joseph");
form->fields[2].value = ASCIIToUTF16("Jonathan");
form_manager.FillForm(*form, WebNode());
// Get the input element we want to find.
WebElement element = web_frame->document().getElementById("firstname");
WebInputElement input_element = element.to<WebInputElement>();
// Find the newly-filled form that contains the input element.
FormData form2;
EXPECT_TRUE(form_manager.FindFormWithFormControlElement(input_element,
&form2));
EXPECT_EQ(ASCIIToUTF16("TestForm"), form2.name);
EXPECT_EQ(GURL(web_frame->document().url()), form2.origin);
EXPECT_EQ(GURL("http://buh.com"), form2.action);
const std::vector<FormField>& fields = form2.fields;
ASSERT_EQ(4U, fields.size());
FormField expected;
expected.form_control_type = ASCIIToUTF16("text");
expected.max_length = WebInputElement::defaultMaxLength();
expected.name = ASCIIToUTF16("firstname");
expected.value = ASCIIToUTF16("Brother");
expected.is_autofilled = true;
EXPECT_FORM_FIELD_EQUALS(expected, fields[0]);
expected.name = ASCIIToUTF16("middlename");
expected.value = ASCIIToUTF16("Joseph");
expected.is_autofilled = true;
EXPECT_FORM_FIELD_EQUALS(expected, fields[1]);
expected.name = ASCIIToUTF16("lastname");
expected.value = ASCIIToUTF16("Jonathan");
expected.is_autofilled = true;
EXPECT_FORM_FIELD_EQUALS(expected, fields[2]);
expected.name = ASCIIToUTF16("postfix");
expected.value = string16();
expected.is_autofilled = false;
EXPECT_FORM_FIELD_EQUALS(expected, fields[3]);
}
TEST_F(FormManagerTest, FillFormEmptyName) {
LoadHTML("<FORM name=\"TestForm\" action=\"http://buh.com\" method=\"post\">"
" <INPUT type=\"text\" id=\"firstname\"/>"
" <INPUT type=\"text\" id=\"lastname\"/>"
" <INPUT type=\"text\" id=\"email\"/>"
" <INPUT type=\"submit\" value=\"Send\"/>"
"</FORM>");
WebFrame* web_frame = GetMainFrame();
ASSERT_NE(static_cast<WebFrame*>(NULL), web_frame);
FormManager form_manager;
std::vector<FormData> forms;
form_manager.ExtractForms(web_frame, &forms);
ASSERT_EQ(1U, forms.size());
// Get the input element we want to find.
WebElement element = web_frame->document().getElementById("firstname");
WebInputElement input_element = element.to<WebInputElement>();
// Find the form that contains the input element.
FormData form;
EXPECT_TRUE(form_manager.FindFormWithFormControlElement(input_element,
&form));
EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
EXPECT_EQ(GURL(web_frame->document().url()), form.origin);
EXPECT_EQ(GURL("http://buh.com"), form.action);
const std::vector<FormField>& fields = form.fields;
ASSERT_EQ(3U, fields.size());
FormField expected;
expected.form_control_type = ASCIIToUTF16("text");
expected.max_length = WebInputElement::defaultMaxLength();
expected.name = ASCIIToUTF16("firstname");
EXPECT_FORM_FIELD_EQUALS(expected, fields[0]);
expected.name = ASCIIToUTF16("lastname");
EXPECT_FORM_FIELD_EQUALS(expected, fields[1]);
expected.name = ASCIIToUTF16("email");
EXPECT_FORM_FIELD_EQUALS(expected, fields[2]);
// Fill the form.
form.fields[0].value = ASCIIToUTF16("Wyatt");
form.fields[1].value = ASCIIToUTF16("Earp");
form.fields[2].value = ASCIIToUTF16("wyatt@example.com");
form_manager.FillForm(form, WebNode());
// Find the newly-filled form that contains the input element.
FormData form2;
EXPECT_TRUE(form_manager.FindFormWithFormControlElement(input_element,
&form2));
EXPECT_EQ(ASCIIToUTF16("TestForm"), form2.name);
EXPECT_EQ(GURL(web_frame->document().url()), form2.origin);
EXPECT_EQ(GURL("http://buh.com"), form2.action);
const std::vector<FormField>& fields2 = form2.fields;
ASSERT_EQ(3U, fields2.size());
expected.form_control_type = ASCIIToUTF16("text");
expected.max_length = WebInputElement::defaultMaxLength();
expected.name = ASCIIToUTF16("firstname");
expected.value = ASCIIToUTF16("Wyatt");
EXPECT_FORM_FIELD_EQUALS(expected, fields[0]);
expected.name = ASCIIToUTF16("lastname");
expected.value = ASCIIToUTF16("Earp");
EXPECT_FORM_FIELD_EQUALS(expected, fields[1]);
expected.name = ASCIIToUTF16("email");
expected.value = ASCIIToUTF16("wyatt@example.com");
EXPECT_FORM_FIELD_EQUALS(expected, fields[2]);
}
TEST_F(FormManagerTest, FillFormEmptyFormNames) {
LoadHTML("<FORM action=\"http://buh.com\" method=\"post\">"
" <INPUT type=\"text\" id=\"firstname\"/>"
" <INPUT type=\"text\" id=\"middlename\"/>"
" <INPUT type=\"text\" id=\"lastname\"/>"
" <INPUT type=\"submit\" value=\"Send\"/>"
"</FORM>"
"<FORM action=\"http://abc.com\" method=\"post\">"
" <INPUT type=\"text\" id=\"apple\"/>"
" <INPUT type=\"text\" id=\"banana\"/>"
" <INPUT type=\"text\" id=\"cantelope\"/>"
" <INPUT type=\"submit\" value=\"Send\"/>"
"</FORM>");
WebFrame* web_frame = GetMainFrame();
ASSERT_NE(static_cast<WebFrame*>(NULL), web_frame);
FormManager form_manager;
std::vector<FormData> forms;
form_manager.ExtractForms(web_frame, &forms);
ASSERT_EQ(2U, forms.size());
// Get the input element we want to find.
WebElement element = web_frame->document().getElementById("apple");
WebInputElement input_element = element.to<WebInputElement>();
// Find the form that contains the input element.
FormData form;
EXPECT_TRUE(form_manager.FindFormWithFormControlElement(input_element,
&form));
EXPECT_EQ(string16(), form.name);
EXPECT_EQ(GURL(web_frame->document().url()), form.origin);
EXPECT_EQ(GURL("http://abc.com"), form.action);
const std::vector<FormField>& fields = form.fields;
ASSERT_EQ(3U, fields.size());
FormField expected;
expected.form_control_type = ASCIIToUTF16("text");
expected.max_length = WebInputElement::defaultMaxLength();
expected.name = ASCIIToUTF16("apple");
expected.is_autofilled = false;
EXPECT_FORM_FIELD_EQUALS(expected, fields[0]);
expected.name = ASCIIToUTF16("banana");
expected.is_autofilled = false;
EXPECT_FORM_FIELD_EQUALS(expected, fields[1]);
expected.name = ASCIIToUTF16("cantelope");
expected.is_autofilled = false;
EXPECT_FORM_FIELD_EQUALS(expected, fields[2]);
// Fill the form.
form.fields[0].value = ASCIIToUTF16("Red");
form.fields[1].value = ASCIIToUTF16("Yellow");
form.fields[2].value = ASCIIToUTF16("Also Yellow");
form_manager.FillForm(form, WebNode());
// Find the newly-filled form that contains the input element.
FormData form2;
EXPECT_TRUE(form_manager.FindFormWithFormControlElement(input_element,
&form2));
EXPECT_EQ(string16(), form2.name);
EXPECT_EQ(GURL(web_frame->document().url()), form2.origin);
EXPECT_EQ(GURL("http://abc.com"), form2.action);
const std::vector<FormField>& fields2 = form2.fields;
ASSERT_EQ(3U, fields2.size());
expected.name = ASCIIToUTF16("apple");
expected.value = ASCIIToUTF16("Red");
expected.is_autofilled = true;
EXPECT_FORM_FIELD_EQUALS(expected, fields2[0]);
expected.name = ASCIIToUTF16("banana");
expected.value = ASCIIToUTF16("Yellow");
expected.is_autofilled = true;
EXPECT_FORM_FIELD_EQUALS(expected, fields2[1]);
expected.name = ASCIIToUTF16("cantelope");
expected.value = ASCIIToUTF16("Also Yellow");
expected.is_autofilled = true;
EXPECT_FORM_FIELD_EQUALS(expected, fields2[2]);
}
TEST_F(FormManagerTest, ThreePartPhone) {
LoadHTML("<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
" Phone:"
" <input type=\"text\" name=\"dayphone1\">"
" -"
" <input type=\"text\" name=\"dayphone2\">"
" -"
" <input type=\"text\" name=\"dayphone3\">"
" ext.:"
" <input type=\"text\" name=\"dayphone4\">"
" <input type=\"submit\" name=\"reply-send\" value=\"Send\">"
"</FORM>");
WebFrame* frame = GetMainFrame();
ASSERT_NE(static_cast<WebFrame*>(NULL), frame);
WebVector<WebFormElement> forms;
frame->document().forms(forms);
ASSERT_EQ(1U, forms.size());
FormData form;
EXPECT_TRUE(FormManager::WebFormElementToFormData(forms[0],
FormManager::REQUIRE_NONE,
FormManager::EXTRACT_VALUE,
&form));
EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
EXPECT_EQ(GURL(frame->document().url()), form.origin);
EXPECT_EQ(GURL("http://cnn.com"), form.action);
const std::vector<FormField>& fields = form.fields;
ASSERT_EQ(4U, fields.size());
FormField expected;
expected.form_control_type = ASCIIToUTF16("text");
expected.max_length = WebInputElement::defaultMaxLength();
expected.label = ASCIIToUTF16("Phone:");
expected.name = ASCIIToUTF16("dayphone1");
EXPECT_FORM_FIELD_EQUALS(expected, fields[0]);
expected.label = ASCIIToUTF16("-");
expected.name = ASCIIToUTF16("dayphone2");
EXPECT_FORM_FIELD_EQUALS(expected, fields[1]);
expected.label = ASCIIToUTF16("-");
expected.name = ASCIIToUTF16("dayphone3");
EXPECT_FORM_FIELD_EQUALS(expected, fields[2]);
expected.label = ASCIIToUTF16("ext.:");
expected.name = ASCIIToUTF16("dayphone4");
EXPECT_FORM_FIELD_EQUALS(expected, fields[3]);
}
TEST_F(FormManagerTest, MaxLengthFields) {
LoadHTML("<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">"
" Phone:"
" <input type=\"text\" maxlength=\"3\" name=\"dayphone1\">"
" -"
" <input type=\"text\" maxlength=\"3\" name=\"dayphone2\">"
" -"
" <input type=\"text\" maxlength=\"4\" size=\"5\""
" name=\"dayphone3\">"
" ext.:"
" <input type=\"text\" maxlength=\"5\" name=\"dayphone4\">"
" <input type=\"text\" name=\"default1\">"
" <input type=\"text\" maxlength=\"-1\" name=\"invalid1\">"
" <input type=\"submit\" name=\"reply-send\" value=\"Send\">"
"</FORM>");
WebFrame* frame = GetMainFrame();
ASSERT_NE(static_cast<WebFrame*>(NULL), frame);
WebVector<WebFormElement> forms;
frame->document().forms(forms);
ASSERT_EQ(1U, forms.size());
FormData form;
EXPECT_TRUE(FormManager::WebFormElementToFormData(forms[0],
FormManager::REQUIRE_NONE,
FormManager::EXTRACT_VALUE,
&form));
EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name);
EXPECT_EQ(GURL(frame->document().url()), form.origin);
EXPECT_EQ(GURL("http://cnn.com"), form.action);
const std::vector<FormField>& fields = form.fields;
ASSERT_EQ(6U, fields.size());
FormField expected;
expected.form_control_type = ASCIIToUTF16("text");
expected.label = ASCIIToUTF16("Phone:");
expected.name = ASCIIToUTF16("dayphone1");
expected.max_length = 3;
EXPECT_FORM_FIELD_EQUALS(expected, fields[0]);
expected.label = ASCIIToUTF16("-");
expected.name = ASCIIToUTF16("dayphone2");
expected.max_length = 3;
EXPECT_FORM_FIELD_EQUALS(expected, fields[1]);
expected.label = ASCIIToUTF16("-");
expected.name = ASCIIToUTF16("dayphone3");
expected.max_length = 4;
EXPECT_FORM_FIELD_EQUALS(expected, fields[2]);
expected.label = ASCIIToUTF16("ext.:");
expected.name = ASCIIToUTF16("dayphone4");
expected.max_length = 5;
EXPECT_FORM_FIELD_EQUALS(expected, fields[3]);
// When unspecified |size|, default is returned.
expected.label = string16();
expected.name = ASCIIToUTF16("default1");
expected.max_length = WebInputElement::defaultMaxLength();
EXPECT_FORM_FIELD_EQUALS(expected, fields[4]);
// When invalid |size|, default is returned.
expected.label = string16();
expected.name = ASCIIToUTF16("invalid1");
expected.max_length = WebInputElement::defaultMaxLength();
EXPECT_FORM_FIELD_EQUALS(expected, fields[5]);
}
// This test re-creates the experience of typing in a field then selecting a
// profile from the Autofill suggestions popup. The field that is being typed
// into should be filled even though it's not technically empty.
TEST_F(FormManagerTest, FillFormNonEmptyField) {
LoadHTML("<FORM name=\"TestForm\" action=\"http://buh.com\" method=\"post\">"