Chromium Code Reviews| Index: chrome/renderer/autofill/form_classifier_browsertest.cc |
| diff --git a/chrome/renderer/autofill/form_classifier_browsertest.cc b/chrome/renderer/autofill/form_classifier_browsertest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..8634221d7541a1627be5d07e93fbcf8335560696 |
| --- /dev/null |
| +++ b/chrome/renderer/autofill/form_classifier_browsertest.cc |
| @@ -0,0 +1,270 @@ |
| +// Copyright 2016 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 "base/macros.h" |
| +#include "base/strings/utf_string_conversions.h" |
| +#include "chrome/test/base/chrome_render_view_test.h" |
| +#include "components/autofill/content/renderer/form_classifier.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| +#include "third_party/WebKit/public/web/WebDocument.h" |
| +#include "third_party/WebKit/public/web/WebFormElement.h" |
| +#include "third_party/WebKit/public/web/WebLocalFrame.h" |
| + |
| +namespace autofill { |
| + |
| +class FormClassifierTest : public ChromeRenderViewTest { |
| + public: |
| + FormClassifierTest() {} |
| + |
| + void TearDown() override { |
| + LoadHTML(""); |
| + ChromeRenderViewTest::TearDown(); |
| + } |
| + |
| + bool GetGenerationField(std::string* generation_field) { |
| + blink::WebDocument document = GetMainFrame()->document(); |
| + blink::WebFormElement form = |
| + document.getElementById("test_form").to<blink::WebFormElement>(); |
| + base::string16 generation_field16; |
| + bool generation_availalbe = |
| + ClassifyFormAndFindGenerationField(form, &generation_field16); |
| + *generation_field = base::UTF16ToUTF8(generation_field16); |
| + return generation_availalbe; |
| + } |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(FormClassifierTest); |
| +}; |
| + |
| +const char kSigninFormHTML[] = |
| + "<FORM id = 'test_form'> " |
| + " <SELECT id='account_type'>" |
| + " <OPTION value = 'personal'>" |
| + " <OPTION value = 'corporate'>" |
| + " </SELECT>" |
| + " <INPUT type = 'text' id = 'username'/>" |
| + " <INPUT type = 'password' id = 'password'/>" |
| + " <INPUT type = 'checkbox' id = 'remember_me'/>" |
| + " <INPUT type = 'checkbox' id = 'secure_login'/>" |
| + " <INPUT type = 'submit' id = 'signin' />" |
| + " <INPUT type = 'hidden' id = 'ignore_this' />" |
| + " <INPUT type = 'hidden' id = 'ignore_this_too' />" |
| + " <INPUT type = 'submit' id = 'submit' />" |
| + "</FORM>"; |
| + |
| +const char kSignupFormWithSeveralTextFieldsFormHTML[] = |
| + "<FORM id = 'test_form'> " |
| + " <INPUT type = 'text' id = 'full_name'/>" |
| + " <INPUT type = 'text' id = 'username'/>" |
| + " <INPUT type = 'password' id = 'password'/>" |
| + " <INPUT type = 'submit' id = 'submit' />" |
| + "</FORM>"; |
| + |
| +const char kSignupFormWithSeveralPasswordFieldsHTML[] = |
| + "<FORM id = 'test_form'> " |
| + " <INPUT type = 'password' id = 'password'/>" |
| + " <INPUT type = 'password' id = 'confirm_password'/>" |
| + " <INPUT type = 'submit' id = 'submit' />" |
| + "</FORM>"; |
| + |
| +const char kSignupFormWithManyCheckboxesHTML[] = |
| + "<FORM id = 'test_form'> " |
| + " </SELECT>" |
| + " <INPUT type = 'text' id = 'username' />" |
| + " <INPUT type = 'password' id = 'password' />" |
| + " <INPUT type = 'checkbox' id = 'subscribe_science' />" |
| + " <INPUT type = 'checkbox' id = 'subscribe_music' />" |
| + " <INPUT type = 'checkbox' id = 'subscribe_sport' />" |
| + " <INPUT type = 'submit' id = 'submit' />" |
| + "</FORM>"; |
| + |
| +const char kSignupFormWithOtherFieldsHTML[] = |
| + "<FORM id = 'test_form'> " |
| + " <INPUT type = 'text' id = 'username' />" |
| + " <INPUT type = 'password' id = 'password' />" |
| + " <INPUT type = 'color' id = 'account_color' />" |
| + " <INPUT type = 'date' id = 'date_of_birth' />" |
| + " <INPUT type = 'submit' id = 'submit' />" |
| + "</FORM>"; |
| + |
| +const char kSigninFormWithTextFeatureInInputElementHTML[] = |
| + "<FORM id = 'test_form'> " |
| + " <INPUT type = 'text' id = 'username' class = 'sign-in_field' />" |
| + " <INPUT type = 'password' id = 'password' class = 'sign-in_field' />" |
| + " <INPUT type = 'submit' id = 'submit' />" |
| + "</FORM>"; |
| + |
| +const char kSigninFormWithTextFeatureInFormTagHTML[] = |
| + "<FORM id = 'test_form' some_attribute='auth_form' > " |
| + " <INPUT type = 'text' id = 'username' />" |
| + " <INPUT type = 'password' id = 'password' />" |
| + " <INPUT type = 'submit' id = 'submit' />" |
| + "</FORM>"; |
| + |
| +const char kSigninAndSignupFormsInOneDivHTML[] = |
| + "<DIV class = 'signup_signin_container'>" |
| + " <FORM id = 'test_form' class = 'unknown_form_type' > " |
| + " <INPUT type = 'text' id = 'username' />" |
| + " <INPUT type = 'password' id = 'password' />" |
| + " <INPUT type = 'submit' id = 'submit' />" |
| + " </FORM>" |
| + " <FORM id = 'another_form' class = 'unknown_form_type' > " |
| + " <INPUT type = 'text' id = 'username' />" |
| + " <INPUT type = 'password' id = 'password' />" |
| + " <INPUT type = 'submit' id = 'submit' />" |
| + " </FORM>" |
| + "</DIV>"; |
| + |
| +const char kSigninFormWithTextFeatureInEnclosingParentHTML[] = |
| + "<DIV id = 'signup_signin_container'>" |
| + " <DIV id = 'signin_wraper'>" |
| + " <FORM id = 'test_form' > " |
| + " <INPUT type = 'text' id = 'username' />" |
| + " <INPUT type = 'password' id = 'password' />" |
| + " <INPUT type = 'submit' id = 'submit' />" |
| + " </FORM>" |
| + " </DIV>" |
| + "</DIV>"; |
| + |
| +const char kSigninFormWithInvisibleFieldsHTML[] = |
| + "<FORM id = 'test_form'> " |
| + " <INPUT type = 'text' id = 'username' />" |
| + " <INPUT type = 'password' id = 'password' />" |
| + " <INPUT type = 'input' hidden id = 'hidden_field1' />" |
| + " <INPUT type = 'password' hidden id = 'hidden_field2'/>" |
| + " <INPUT type = 'submit' id = 'submit' />" |
| + "</FORM>"; |
| + |
| +const char kSignupFormWithSigninButtonHTML[] = |
| + "<FORM id = 'test_form' >" |
| + " <INPUT type = 'text' id = 'username' />" |
| + " <INPUT type = 'password' id = 'password' />" |
| + " <INPUT type = 'password' id = 'confirm_password' />" |
| + " <INPUT type = 'submit' id = 'submit' />" |
| + " <INPUT type = 'button' id = 'goto_signin_form' />" |
| + " <INPUT type = 'image' id = 'goto_auth_form' />" |
| + "</FORM>"; |
| + |
| +const char kSomeFormWithoutPasswordFields[] = |
| + "<FORM id = 'test_form' >" |
| + " <INPUT type = 'text' id = 'username' />" |
| + " <INPUT type = 'text' id = 'fullname' />" |
| + " <INPUT type = 'text' id = 'address' />" |
| + " <INPUT type = 'text' id = 'phone' />" |
| + " <INPUT type = 'submit' id = 'submit' />" |
| + "</FORM>"; |
| + |
| +const char kSignupFormWithSigninTextFeatureAndManyFieldsHTML[] = |
| + "<FORM id = 'test_form' class = 'log-on_container'> " |
| + " <INPUT type = 'text' id = 'fullname' />" |
| + " <INPUT type = 'text' id = 'username' />" |
| + " <INPUT type = 'password' id = 'password' />" |
| + " <INPUT type = 'submit' id = 'submit' />" |
| + "</FORM>"; |
| + |
| +const char kChangeFormWithTreePasswordFieldsHTML[] = |
| + "<FORM id = 'test_form' >" |
| + " <INPUT type = 'password' id = 'old_password' />" |
| + " <INPUT type = 'password' id = 'password' />" |
| + " <INPUT type = 'password' id = 'confirm_password' />" |
| + " <INPUT type = 'submit' id = 'submit' />" |
| + "</FORM>"; |
| + |
| +TEST_F(FormClassifierTest, SigninForm) { |
| + // Signin form with as many as possible visible elements, |
| + // i.e. if one more text/password/checkbox/other field is added, the form |
|
vabr (Chromium)
2016/06/10 13:22:11
nit: Please keep horizontal spaces to one characte
kolos1
2016/06/13 14:27:34
Removed double space.
Did I exceed 80 character
vabr (Chromium)
2016/06/13 16:01:57
No, you did not, quite the opposite :), which was
|
| + // will be recognized as a signup form. |
| + LoadHTML(kSigninFormHTML); |
| + std::string generation_field; |
| + EXPECT_FALSE(GetGenerationField(&generation_field)); |
| +} |
| + |
| +TEST_F(FormClassifierTest, SignupFormWithSeveralTextFields) { |
| + LoadHTML(kSignupFormWithSeveralTextFieldsFormHTML); |
| + std::string generation_field; |
| + EXPECT_TRUE(GetGenerationField(&generation_field)); |
| + EXPECT_EQ("password", generation_field); |
| +} |
| + |
| +TEST_F(FormClassifierTest, SignupFormWithSeveralPasswordFieldsHTML) { |
| + LoadHTML(kSignupFormWithSeveralPasswordFieldsHTML); |
| + std::string generation_field; |
| + EXPECT_TRUE(GetGenerationField(&generation_field)); |
| + EXPECT_EQ("password", generation_field); |
| +} |
| + |
| +TEST_F(FormClassifierTest, SignupFormWithManyCheckboxesHTML) { |
| + LoadHTML(kSignupFormWithManyCheckboxesHTML); |
| + std::string generation_field; |
| + EXPECT_TRUE(GetGenerationField(&generation_field)); |
| + EXPECT_EQ("password", generation_field); |
| +} |
| + |
| +TEST_F(FormClassifierTest, SignupFormWithOtherFieldsHTML) { |
| + LoadHTML(kSignupFormWithOtherFieldsHTML); |
| + std::string generation_field; |
| + EXPECT_TRUE(GetGenerationField(&generation_field)); |
| + EXPECT_EQ("password", generation_field); |
| +} |
| + |
| +TEST_F(FormClassifierTest, SigninFormWithTextFeatureInInputElementHTML) { |
| + LoadHTML(kSigninFormWithTextFeatureInInputElementHTML); |
| + std::string generation_field; |
| + EXPECT_FALSE(GetGenerationField(&generation_field)); |
| +} |
| + |
| +TEST_F(FormClassifierTest, SigninFormWithTextFeatureInFormTagHTML) { |
| + LoadHTML(kSigninFormWithTextFeatureInFormTagHTML); |
| + std::string generation_field; |
| + EXPECT_FALSE(GetGenerationField(&generation_field)); |
| +} |
| + |
| +TEST_F(FormClassifierTest, SigninAndSignupFormsInOneDivHTML) { |
| + LoadHTML(kSigninAndSignupFormsInOneDivHTML); |
| + std::string generation_field; |
| + EXPECT_FALSE(GetGenerationField(&generation_field)); |
| +} |
| + |
| +TEST_F(FormClassifierTest, SigninFormWithTextFeatureInEnclosingParentHTML) { |
| + LoadHTML(kSigninFormWithTextFeatureInEnclosingParentHTML); |
| + std::string generation_field; |
| + EXPECT_FALSE(GetGenerationField(&generation_field)); |
| +} |
| + |
| +TEST_F(FormClassifierTest, SigninFormWithInvisibleFieldsHTML) { |
| + LoadHTML(kSigninFormWithInvisibleFieldsHTML); |
| + std::string generation_field; |
| + EXPECT_FALSE(GetGenerationField(&generation_field)); |
| +} |
| + |
| +TEST_F(FormClassifierTest, SignupFormWithSigninButtonHTML) { |
| + LoadHTML(kSignupFormWithSigninButtonHTML); |
| + std::string generation_field; |
| + EXPECT_TRUE(GetGenerationField(&generation_field)); |
| + EXPECT_EQ("password", generation_field); |
| +} |
| + |
| +TEST_F(FormClassifierTest, SomeFormWithoutPasswordFields) { |
| + LoadHTML(kSomeFormWithoutPasswordFields); |
| + std::string generation_field; |
| + EXPECT_FALSE(GetGenerationField(&generation_field)); |
| +} |
| + |
| +TEST_F(FormClassifierTest, SignupFormWithSigninTextFeatureAndManyFieldsHTML) { |
| + // Even if there is signin text feature, the number of fields is more reliable |
| + // signal of signup form. So, this form should classified as signup. |
|
vabr (Chromium)
2016/06/10 13:22:11
typo: should classified -> should be classified
kolos1
2016/06/13 14:27:34
Done.
|
| + LoadHTML(kSignupFormWithSigninTextFeatureAndManyFieldsHTML); |
| + std::string generation_field; |
| + EXPECT_TRUE(GetGenerationField(&generation_field)); |
| + EXPECT_EQ("password", generation_field); |
| +} |
| + |
| +TEST_F(FormClassifierTest, kChangeFormWithTreePasswordFieldsHTML) { |
| + LoadHTML(kChangeFormWithTreePasswordFieldsHTML); |
| + std::string generation_field; |
| + EXPECT_TRUE(GetGenerationField(&generation_field)); |
| + EXPECT_EQ("password", generation_field); |
| +} |
| + |
| +} // namespace autofill |