// Copyright (c) 2010 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 "chrome/renderer/form_manager.h" #include "chrome/test/render_view_test.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/WebKit/WebKit/chromium/public/WebDocument.h" #include "third_party/WebKit/WebKit/chromium/public/WebElement.h" #include "third_party/WebKit/WebKit/chromium/public/WebInputElement.h" #include "third_party/WebKit/WebKit/chromium/public/WebString.h" using WebKit::WebElement; using WebKit::WebFrame; using WebKit::WebInputElement; using WebKit::WebString; class FormManagerTest : public RenderViewTest { public: FormManagerTest() {} }; TEST_F(FormManagerTest, ExtractForms) { 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_TRUE(web_frame); FormManager form_manager; form_manager.ExtractForms(web_frame); std::vector<FormData> forms; form_manager.GetForms(&forms, FormManager::REQUIRE_NONE); ASSERT_EQ(1U, forms.size()); const FormData& form = forms[0]; EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name); EXPECT_EQ(GURL(web_frame->url()), form.origin); EXPECT_EQ(GURL("http://cnn.com"), form.action); EXPECT_EQ(ASCIIToUTF16("reply-send"), form.submit); const std::vector<string16>& elements = form.elements; ASSERT_EQ(3U, elements.size()); EXPECT_EQ(ASCIIToUTF16("firstname"), elements[0]); EXPECT_EQ(ASCIIToUTF16("lastname"), elements[1]); EXPECT_EQ(ASCIIToUTF16("reply-send"), elements[2]); const std::vector<string16>& values = form.values; ASSERT_EQ(3U, values.size()); EXPECT_EQ(ASCIIToUTF16("John"), values[0]); EXPECT_EQ(ASCIIToUTF16("Smith"), values[1]); EXPECT_EQ(ASCIIToUTF16("Send"), values[2]); } TEST_F(FormManagerTest, ExtractMultipleForms) { LoadHTML("<FORM name=\"TestForm\" action=\"http://cnn.com\" method=\"post\">" " <INPUT type=\"text\" id=\"firstname\" value=\"John\">" " <INPUT type=\"submit\" name=\"reply-send\" value=\"Send\">" "</FORM>" "<FORM name=\"TestForm2\" action=\"http://zoo.com\" method=\"post\">" " <INPUT type=\"text\" id=\"lastname\" value=\"Smith\">" " <INPUT type=\"submit\" name=\"second\" value=\"Submit\">" "</FORM>"); WebFrame* web_frame = GetMainFrame(); ASSERT_TRUE(web_frame); FormManager form_manager; form_manager.ExtractForms(web_frame); std::vector<FormData> forms; form_manager.GetForms(&forms, FormManager::REQUIRE_NONE); ASSERT_EQ(2U, forms.size()); // First form. const FormData& form = forms[0]; EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name); EXPECT_EQ(GURL(web_frame->url()), form.origin); EXPECT_EQ(GURL("http://cnn.com"), form.action); EXPECT_EQ(ASCIIToUTF16("reply-send"), form.submit); const std::vector<string16>& elements = form.elements; ASSERT_EQ(2U, elements.size()); EXPECT_EQ(ASCIIToUTF16("firstname"), elements[0]); EXPECT_EQ(ASCIIToUTF16("reply-send"), elements[1]); const std::vector<string16>& values = form.values; ASSERT_EQ(2U, values.size()); EXPECT_EQ(ASCIIToUTF16("John"), values[0]); EXPECT_EQ(ASCIIToUTF16("Send"), values[1]); // Second form. const FormData& form2 = forms[1]; EXPECT_EQ(ASCIIToUTF16("TestForm2"), form2.name); EXPECT_EQ(GURL(web_frame->url()), form2.origin); EXPECT_EQ(GURL("http://zoo.com"), form2.action); EXPECT_EQ(ASCIIToUTF16("second"), form2.submit); const std::vector<string16>& elements2 = form2.elements; ASSERT_EQ(2U, elements2.size()); EXPECT_EQ(ASCIIToUTF16("lastname"), elements2[0]); EXPECT_EQ(ASCIIToUTF16("second"), elements2[1]); const std::vector<string16>& values2 = form2.values; ASSERT_EQ(2U, values2.size()); EXPECT_EQ(ASCIIToUTF16("Smith"), values2[0]); EXPECT_EQ(ASCIIToUTF16("Submit"), values2[1]); } TEST_F(FormManagerTest, GetFormsAutocomplete) { // 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=\"submit\" name=\"reply-send\" value=\"Send\">" "</FORM>"); WebFrame* web_frame = GetMainFrame(); ASSERT_TRUE(web_frame); FormManager form_manager; form_manager.ExtractForms(web_frame); // Verify that we did load the forms. std::vector<FormData> forms; form_manager.GetForms(&forms, FormManager::REQUIRE_NONE); ASSERT_EQ(1U, forms.size()); // autocomplete=off and we're requiring autocomplete, so no forms returned. forms.clear(); form_manager.GetForms(&forms, FormManager::REQUIRE_AUTOCOMPLETE); ASSERT_EQ(0U, forms.size()); // 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=\"lastname\" value=\"Smith\">" " <INPUT type=\"submit\" name=\"reply\" value=\"Send\">" "</FORM>"); web_frame = GetMainFrame(); ASSERT_TRUE(web_frame); form_manager.Reset(); form_manager.ExtractForms(web_frame); forms.clear(); form_manager.GetForms(&forms, FormManager::REQUIRE_AUTOCOMPLETE); ASSERT_EQ(1U, forms.size()); const FormData& form = forms[0]; EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name); EXPECT_EQ(GURL(web_frame->url()), form.origin); EXPECT_EQ(GURL("http://abc.com"), form.action); EXPECT_EQ(ASCIIToUTF16("reply"), form.submit); const std::vector<string16>& elements = form.elements; ASSERT_EQ(2U, elements.size()); EXPECT_EQ(ASCIIToUTF16("lastname"), elements[0]); EXPECT_EQ(ASCIIToUTF16("reply"), elements[1]); const std::vector<string16>& values = form.values; ASSERT_EQ(2U, values.size()); EXPECT_EQ(ASCIIToUTF16("Smith"), values[0]); EXPECT_EQ(ASCIIToUTF16("Send"), values[1]); } TEST_F(FormManagerTest, GetFormsElementsEnabled) { // 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=\"lastname\" value=\"Smith\">" " <INPUT type=\"submit\" name=\"submit\" value=\"Send\">" "</FORM>"); WebFrame* web_frame = GetMainFrame(); ASSERT_TRUE(web_frame); FormManager form_manager; form_manager.ExtractForms(web_frame); std::vector<FormData> forms; form_manager.GetForms(&forms, FormManager::REQUIRE_ELEMENTS_ENABLED); ASSERT_EQ(1U, forms.size()); const FormData& form = forms[0]; EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name); EXPECT_EQ(GURL(web_frame->url()), form.origin); EXPECT_EQ(GURL("http://xyz.com"), form.action); EXPECT_EQ(ASCIIToUTF16("submit"), form.submit); const std::vector<string16>& elements = form.elements; ASSERT_EQ(2U, elements.size()); EXPECT_EQ(ASCIIToUTF16("lastname"), elements[0]); EXPECT_EQ(ASCIIToUTF16("submit"), elements[1]); const std::vector<string16>& values = form.values; ASSERT_EQ(2U, values.size()); EXPECT_EQ(ASCIIToUTF16("Smith"), values[0]); EXPECT_EQ(ASCIIToUTF16("Send"), values[1]); } 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=\"submit\" name=\"reply-send\" value=\"Send\">" "</FORM>"); WebFrame* web_frame = GetMainFrame(); ASSERT_TRUE(web_frame); FormManager form_manager; form_manager.ExtractForms(web_frame); // Verify that we have the form. std::vector<FormData> forms; form_manager.GetForms(&forms, FormManager::REQUIRE_NONE); ASSERT_EQ(1U, forms.size()); // Get the input element we want to find. WebElement element = web_frame->document().getElementById(WebString::fromUTF8("firstname")); WebInputElement input_element = element.toElement<WebInputElement>(); // Find the form and verify it's the correct form. FormData form; EXPECT_TRUE(form_manager.FindForm(input_element, &form)); EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name); EXPECT_EQ(GURL(web_frame->url()), form.origin); EXPECT_EQ(GURL("http://buh.com"), form.action); EXPECT_EQ(ASCIIToUTF16("reply-send"), form.submit); const std::vector<string16>& elements = form.elements; ASSERT_EQ(3U, elements.size()); EXPECT_EQ(ASCIIToUTF16("firstname"), elements[0]); EXPECT_EQ(ASCIIToUTF16("lastname"), elements[1]); EXPECT_EQ(ASCIIToUTF16("reply-send"), elements[2]); const std::vector<string16>& values = form.values; ASSERT_EQ(3U, values.size()); EXPECT_EQ(ASCIIToUTF16("John"), values[0]); EXPECT_EQ(ASCIIToUTF16("Smith"), values[1]); EXPECT_EQ(ASCIIToUTF16("Send"), values[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=\"submit\" name=\"reply-send\" value=\"Send\">" "</FORM>"); WebFrame* web_frame = GetMainFrame(); ASSERT_TRUE(web_frame); FormManager form_manager; form_manager.ExtractForms(web_frame); // Verify that we have the form. std::vector<FormData> forms; form_manager.GetForms(&forms, FormManager::REQUIRE_NONE); ASSERT_EQ(1U, forms.size()); // Get the input element we want to find. WebElement element = web_frame->document().getElementById(WebString::fromUTF8("firstname")); WebInputElement input_element = element.toElement<WebInputElement>(); // Find the form that contains the input element. FormData form; EXPECT_TRUE(form_manager.FindForm(input_element, &form)); EXPECT_EQ(ASCIIToUTF16("TestForm"), form.name); EXPECT_EQ(GURL(web_frame->url()), form.origin); EXPECT_EQ(GURL("http://buh.com"), form.action); EXPECT_EQ(ASCIIToUTF16("reply-send"), form.submit); const std::vector<string16>& elements = form.elements; ASSERT_EQ(3U, elements.size()); EXPECT_EQ(ASCIIToUTF16("firstname"), elements[0]); EXPECT_EQ(ASCIIToUTF16("lastname"), elements[1]); EXPECT_EQ(ASCIIToUTF16("reply-send"), elements[2]); // Verify that the text fields have no values. const std::vector<string16>& values = form.values; ASSERT_EQ(3U, values.size()); EXPECT_EQ(string16(), values[0]); EXPECT_EQ(string16(), values[1]); EXPECT_EQ(ASCIIToUTF16("Send"), values[2]); // Fill the form. form.values[0] = ASCIIToUTF16("Wyatt"); form.values[1] = ASCIIToUTF16("Earp"); EXPECT_TRUE(form_manager.FillForm(form)); // Find the newly-filled form that contains the input element. FormData form2; EXPECT_TRUE(form_manager.FindForm(input_element, &form2)); EXPECT_EQ(ASCIIToUTF16("TestForm"), form2.name); EXPECT_EQ(GURL(web_frame->url()), form2.origin); EXPECT_EQ(GURL("http://buh.com"), form2.action); EXPECT_EQ(ASCIIToUTF16("reply-send"), form2.submit); const std::vector<string16>& elements2 = form2.elements; ASSERT_EQ(3U, elements2.size()); EXPECT_EQ(ASCIIToUTF16("firstname"), elements2[0]); EXPECT_EQ(ASCIIToUTF16("lastname"), elements2[1]); EXPECT_EQ(ASCIIToUTF16("reply-send"), elements2[2]); // Verify that the text fields have no values. const std::vector<string16>& values2 = form2.values; ASSERT_EQ(3U, values2.size()); EXPECT_EQ(ASCIIToUTF16("Wyatt"), values2[0]); EXPECT_EQ(ASCIIToUTF16("Earp"), values2[1]); EXPECT_EQ(ASCIIToUTF16("Send"), values2[2]); } TEST_F(FormManagerTest, Reset) { 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_TRUE(web_frame); FormManager form_manager; form_manager.ExtractForms(web_frame); std::vector<FormData> forms; form_manager.GetForms(&forms, FormManager::REQUIRE_NONE); ASSERT_EQ(1U, forms.size()); // There should be no forms after the call to Reset. form_manager.Reset(); forms.clear(); form_manager.GetForms(&forms, FormManager::REQUIRE_NONE); ASSERT_EQ(0U, forms.size()); }