OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "base/macros.h" |
| 6 #include "base/strings/utf_string_conversions.h" |
| 7 #include "chrome/test/base/chrome_render_view_test.h" |
| 8 #include "components/autofill/content/renderer/form_classifier.h" |
| 9 #include "testing/gtest/include/gtest/gtest.h" |
| 10 #include "third_party/WebKit/public/web/WebDocument.h" |
| 11 #include "third_party/WebKit/public/web/WebFormElement.h" |
| 12 #include "third_party/WebKit/public/web/WebLocalFrame.h" |
| 13 |
| 14 namespace autofill { |
| 15 |
| 16 class FormClassifierTest : public ChromeRenderViewTest { |
| 17 public: |
| 18 FormClassifierTest() {} |
| 19 |
| 20 void TearDown() override { |
| 21 LoadHTML(""); |
| 22 ChromeRenderViewTest::TearDown(); |
| 23 } |
| 24 |
| 25 bool GetGenerationField(std::string* generation_field) { |
| 26 blink::WebDocument document = GetMainFrame()->document(); |
| 27 blink::WebFormElement form = |
| 28 document.getElementById("test_form").to<blink::WebFormElement>(); |
| 29 base::string16 generation_field16; |
| 30 bool generation_availalbe = |
| 31 ClassifyFormAndFindGenerationField(form, &generation_field16); |
| 32 *generation_field = base::UTF16ToUTF8(generation_field16); |
| 33 return generation_availalbe; |
| 34 } |
| 35 |
| 36 private: |
| 37 DISALLOW_COPY_AND_ASSIGN(FormClassifierTest); |
| 38 }; |
| 39 |
| 40 const char kSigninFormHTML[] = |
| 41 "<FORM id = 'test_form'> " |
| 42 " <SELECT id='account_type'>" |
| 43 " <OPTION value = 'personal'>" |
| 44 " <OPTION value = 'corporate'>" |
| 45 " </SELECT>" |
| 46 " <INPUT type = 'text' id = 'username'/>" |
| 47 " <INPUT type = 'password' id = 'password'/>" |
| 48 " <INPUT type = 'checkbox' id = 'remember_me'/>" |
| 49 " <INPUT type = 'checkbox' id = 'secure_login'/>" |
| 50 " <INPUT type = 'submit' id = 'signin' />" |
| 51 " <INPUT type = 'hidden' id = 'ignore_this' />" |
| 52 " <INPUT type = 'hidden' id = 'ignore_this_too' />" |
| 53 " <INPUT type = 'submit' id = 'submit' />" |
| 54 "</FORM>"; |
| 55 |
| 56 const char kSignupFormWithSeveralTextFieldsFormHTML[] = |
| 57 "<FORM id = 'test_form'> " |
| 58 " <INPUT type = 'text' id = 'full_name'/>" |
| 59 " <INPUT type = 'text' id = 'username'/>" |
| 60 " <INPUT type = 'password' id = 'password'/>" |
| 61 " <INPUT type = 'submit' id = 'submit' />" |
| 62 "</FORM>"; |
| 63 |
| 64 const char kSignupFormWithSeveralPasswordFieldsHTML[] = |
| 65 "<FORM id = 'test_form'> " |
| 66 " <INPUT type = 'text' id = 'username'/>" |
| 67 " <INPUT type = 'password' id = 'password'/>" |
| 68 " <INPUT type = 'password' id = 'confirm_password'/>" |
| 69 " <INPUT type = 'submit' id = 'submit' />" |
| 70 "</FORM>"; |
| 71 |
| 72 const char kSignupFormWithManyCheckboxesHTML[] = |
| 73 "<FORM id = 'test_form'> " |
| 74 " </SELECT>" |
| 75 " <INPUT type = 'text' id = 'username' />" |
| 76 " <INPUT type = 'password' id = 'password' />" |
| 77 " <INPUT type = 'checkbox' id = 'subscribe_science' />" |
| 78 " <INPUT type = 'checkbox' id = 'subscribe_music' />" |
| 79 " <INPUT type = 'checkbox' id = 'subscribe_sport' />" |
| 80 " <INPUT type = 'submit' id = 'submit' />" |
| 81 "</FORM>"; |
| 82 |
| 83 const char kSignupFormWithOtherFieldsHTML[] = |
| 84 "<FORM id = 'test_form'> " |
| 85 " <INPUT type = 'text' id = 'username' />" |
| 86 " <INPUT type = 'password' id = 'password' />" |
| 87 " <INPUT type = 'color' id = 'account_color' />" |
| 88 " <INPUT type = 'date' id = 'date_of_birth' />" |
| 89 " <INPUT type = 'submit' id = 'submit' />" |
| 90 "</FORM>"; |
| 91 |
| 92 const char kSignupFormWithTextFeatureInInputElementHTML[] = |
| 93 "<FORM id = 'test_form'> " |
| 94 " <INPUT type = 'text' id = 'username' class = 'sign-up_field' />" |
| 95 " <INPUT type = 'password' id = 'password' class = 'sign-up_field' />" |
| 96 " <INPUT type = 'submit' id = 'submit' />" |
| 97 "</FORM>"; |
| 98 |
| 99 const char kSignupFormWithTextFeatureInFormTagHTML[] = |
| 100 "<FORM id = 'test_form' some_attribute='sign_up_form' > " |
| 101 " <INPUT type = 'text' id = 'username' />" |
| 102 " <INPUT type = 'password' id = 'password' />" |
| 103 " <INPUT type = 'submit' id = 'submit' />" |
| 104 "</FORM>"; |
| 105 |
| 106 const char kSigninFormWithInvisibleFieldsHTML[] = |
| 107 "<FORM id = 'test_form'> " |
| 108 " <INPUT type = 'text' id = 'username' />" |
| 109 " <INPUT type = 'password' id = 'password' />" |
| 110 " <INPUT type = 'input' hidden id = 'hidden_field1' />" |
| 111 " <INPUT type = 'password' hidden id = 'hidden_field2'/>" |
| 112 " <INPUT type = 'submit' id = 'submit' />" |
| 113 "</FORM>"; |
| 114 |
| 115 const char kSignupFormWithSigninButtonHTML[] = |
| 116 "<FORM id = 'test_form' >" |
| 117 " <INPUT type = 'text' id = 'username' />" |
| 118 " <INPUT type = 'password' id = 'password' />" |
| 119 " <INPUT type = 'password' id = 'confirm_password' />" |
| 120 " <INPUT type = 'submit' id = 'submit' />" |
| 121 " <INPUT type = 'button' id = 'goto_signin_form' />" |
| 122 " <INPUT type = 'image' id = 'goto_auth_form' />" |
| 123 "</FORM>"; |
| 124 |
| 125 const char kSomeFormWithoutPasswordFields[] = |
| 126 "<FORM id = 'test_form' >" |
| 127 " <INPUT type = 'text' id = 'username' />" |
| 128 " <INPUT type = 'text' id = 'fullname' />" |
| 129 " <INPUT type = 'text' id = 'address' />" |
| 130 " <INPUT type = 'text' id = 'phone' />" |
| 131 " <INPUT type = 'submit' id = 'submit' />" |
| 132 "</FORM>"; |
| 133 |
| 134 const char kSignupFormWithSigninTextFeatureAndManyFieldsHTML[] = |
| 135 "<FORM id = 'test_form' class = 'log-on_container'> " |
| 136 " <INPUT type = 'text' id = 'fullname' />" |
| 137 " <INPUT type = 'text' id = 'username' />" |
| 138 " <INPUT type = 'password' id = 'password' />" |
| 139 " <INPUT type = 'submit' id = 'submit' />" |
| 140 "</FORM>"; |
| 141 |
| 142 const char kChangeFormWithTreePasswordFieldsHTML[] = |
| 143 "<FORM id = 'test_form' >" |
| 144 " <INPUT type = 'password' id = 'old_password' />" |
| 145 " <INPUT type = 'password' id = 'password' />" |
| 146 " <INPUT type = 'password' id = 'confirm_password' />" |
| 147 " <INPUT type = 'submit' id = 'submit' />" |
| 148 "</FORM>"; |
| 149 |
| 150 TEST_F(FormClassifierTest, SigninForm) { |
| 151 // Signin form with as many as possible visible elements, |
| 152 // i.e. if one more text/password/checkbox/other field is added, the form |
| 153 // will be recognized as a signup form. |
| 154 LoadHTML(kSigninFormHTML); |
| 155 std::string generation_field; |
| 156 EXPECT_FALSE(GetGenerationField(&generation_field)); |
| 157 } |
| 158 |
| 159 TEST_F(FormClassifierTest, SignupFormWithSeveralTextFields) { |
| 160 LoadHTML(kSignupFormWithSeveralTextFieldsFormHTML); |
| 161 std::string generation_field; |
| 162 EXPECT_TRUE(GetGenerationField(&generation_field)); |
| 163 EXPECT_EQ("password", generation_field); |
| 164 } |
| 165 |
| 166 TEST_F(FormClassifierTest, SignupFormWithSeveralPasswordFieldsHTML) { |
| 167 LoadHTML(kSignupFormWithSeveralPasswordFieldsHTML); |
| 168 std::string generation_field; |
| 169 EXPECT_TRUE(GetGenerationField(&generation_field)); |
| 170 EXPECT_EQ("password", generation_field); |
| 171 } |
| 172 |
| 173 TEST_F(FormClassifierTest, SignupFormWithManyCheckboxesHTML) { |
| 174 LoadHTML(kSignupFormWithManyCheckboxesHTML); |
| 175 std::string generation_field; |
| 176 EXPECT_TRUE(GetGenerationField(&generation_field)); |
| 177 EXPECT_EQ("password", generation_field); |
| 178 } |
| 179 |
| 180 TEST_F(FormClassifierTest, SignupFormWithOtherFieldsHTML) { |
| 181 LoadHTML(kSignupFormWithOtherFieldsHTML); |
| 182 std::string generation_field; |
| 183 EXPECT_TRUE(GetGenerationField(&generation_field)); |
| 184 EXPECT_EQ("password", generation_field); |
| 185 } |
| 186 |
| 187 TEST_F(FormClassifierTest, SignupFormWithTextFeatureInInputElementHTML) { |
| 188 LoadHTML(kSignupFormWithTextFeatureInInputElementHTML); |
| 189 std::string generation_field; |
| 190 EXPECT_TRUE(GetGenerationField(&generation_field)); |
| 191 EXPECT_EQ("password", generation_field); |
| 192 } |
| 193 |
| 194 TEST_F(FormClassifierTest, SigninFormWithTextFeatureInFormTagHTML) { |
| 195 LoadHTML(kSignupFormWithTextFeatureInFormTagHTML); |
| 196 std::string generation_field; |
| 197 EXPECT_TRUE(GetGenerationField(&generation_field)); |
| 198 EXPECT_EQ("password", generation_field); |
| 199 } |
| 200 |
| 201 TEST_F(FormClassifierTest, SigninFormWithInvisibleFieldsHTML) { |
| 202 LoadHTML(kSigninFormWithInvisibleFieldsHTML); |
| 203 std::string generation_field; |
| 204 EXPECT_FALSE(GetGenerationField(&generation_field)); |
| 205 } |
| 206 |
| 207 TEST_F(FormClassifierTest, SignupFormWithSigninButtonHTML) { |
| 208 LoadHTML(kSignupFormWithSigninButtonHTML); |
| 209 std::string generation_field; |
| 210 EXPECT_TRUE(GetGenerationField(&generation_field)); |
| 211 EXPECT_EQ("password", generation_field); |
| 212 } |
| 213 |
| 214 TEST_F(FormClassifierTest, SomeFormWithoutPasswordFields) { |
| 215 LoadHTML(kSomeFormWithoutPasswordFields); |
| 216 std::string generation_field; |
| 217 EXPECT_FALSE(GetGenerationField(&generation_field)); |
| 218 } |
| 219 |
| 220 TEST_F(FormClassifierTest, SignupFormWithSigninTextFeatureAndManyFieldsHTML) { |
| 221 // Even if there is signin text feature, the number of fields is more reliable |
| 222 // signal of signup form. So, this form should be classified as signup. |
| 223 LoadHTML(kSignupFormWithSigninTextFeatureAndManyFieldsHTML); |
| 224 std::string generation_field; |
| 225 EXPECT_TRUE(GetGenerationField(&generation_field)); |
| 226 EXPECT_EQ("password", generation_field); |
| 227 } |
| 228 |
| 229 TEST_F(FormClassifierTest, kChangeFormWithTreePasswordFieldsHTML) { |
| 230 LoadHTML(kChangeFormWithTreePasswordFieldsHTML); |
| 231 std::string generation_field; |
| 232 EXPECT_TRUE(GetGenerationField(&generation_field)); |
| 233 EXPECT_EQ("password", generation_field); |
| 234 } |
| 235 |
| 236 } // namespace autofill |
OLD | NEW |