Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(423)

Side by Side Diff: chrome/renderer/autofill/password_generation_agent_browsertest.cc

Issue 2216463002: [Autofill] Migrate ContentPasswordManagerDriver<-->Password{Autofill,Generation}Agent IPCs to mojo. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix win trybots Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <string.h> 5 #include <string.h>
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "base/macros.h" 9 #include "base/macros.h"
10 #include "base/run_loop.h"
10 #include "base/strings/utf_string_conversions.h" 11 #include "base/strings/utf_string_conversions.h"
11 #include "base/test/histogram_tester.h" 12 #include "base/test/histogram_tester.h"
12 #include "chrome/renderer/autofill/password_generation_test_utils.h" 13 #include "chrome/renderer/autofill/password_generation_test_utils.h"
13 #include "chrome/test/base/chrome_render_view_test.h" 14 #include "chrome/test/base/chrome_render_view_test.h"
14 #include "components/autofill/content/common/autofill_messages.h" 15 #include "components/autofill/content/common/autofill_messages.h"
15 #include "components/autofill/content/renderer/autofill_agent.h" 16 #include "components/autofill/content/renderer/autofill_agent.h"
16 #include "components/autofill/content/renderer/test_password_generation_agent.h" 17 #include "components/autofill/content/renderer/test_password_generation_agent.h"
17 #include "components/autofill/core/common/form_data.h" 18 #include "components/autofill/core/common/form_data.h"
18 #include "components/autofill/core/common/password_generation_util.h" 19 #include "components/autofill/core/common/password_generation_util.h"
20 #include "content/public/renderer/render_frame.h"
21 #include "content/public/renderer/render_view.h"
22 #include "mojo/public/cpp/bindings/binding_set.h"
23 #include "services/shell/public/cpp/interface_provider.h"
19 #include "testing/gtest/include/gtest/gtest.h" 24 #include "testing/gtest/include/gtest/gtest.h"
20 #include "third_party/WebKit/public/platform/WebString.h" 25 #include "third_party/WebKit/public/platform/WebString.h"
21 #include "third_party/WebKit/public/web/WebDocument.h" 26 #include "third_party/WebKit/public/web/WebDocument.h"
22 #include "third_party/WebKit/public/web/WebLocalFrame.h" 27 #include "third_party/WebKit/public/web/WebLocalFrame.h"
23 #include "third_party/WebKit/public/web/WebWidget.h" 28 #include "third_party/WebKit/public/web/WebWidget.h"
24 #include "ui/events/keycodes/keyboard_codes.h" 29 #include "ui/events/keycodes/keyboard_codes.h"
25 30
26 using blink::WebDocument; 31 using blink::WebDocument;
27 using blink::WebElement; 32 using blink::WebElement;
28 using blink::WebInputElement; 33 using blink::WebInputElement;
29 using blink::WebNode; 34 using blink::WebNode;
30 using blink::WebString; 35 using blink::WebString;
31 36
37 namespace {
38
39 class FakeContentPasswordManagerDriver
vabr (Chromium) 2016/08/09 17:36:17 Would it make sense to separate the definition of
leonhsl(Using Gerrit) 2016/08/10 13:22:02 Yeah agree. Put FakeContentPasswordManagerDriver i
40 : public autofill::mojom::PasswordManagerDriver {
41 public:
42 FakeContentPasswordManagerDriver() {}
43
44 ~FakeContentPasswordManagerDriver() override {}
45
46 void BindRequest(autofill::mojom::PasswordManagerDriverRequest request) {
47 bindings_.AddBinding(this, std::move(request));
48 }
49
50 bool called_save_generation_field() const {
51 return called_save_generation_field_;
52 }
53
54 const base::Optional<base::string16>& save_generation_field() const {
55 return save_generation_field_;
56 }
57
58 void reset_save_generation_field() {
59 called_save_generation_field_ = false;
60 save_generation_field_ = base::nullopt;
61 }
62
63 bool called_password_no_longer_generated() const {
64 return called_password_no_longer_generated_;
65 }
66
67 void reset_called_password_no_longer_generated() {
68 called_password_no_longer_generated_ = false;
69 }
70
71 bool called_presave_generated_password() const {
72 return called_presave_generated_password_;
73 }
74
75 void reset_called_presave_generated_password() {
76 called_presave_generated_password_ = false;
77 }
78
79 private:
80 // mojom::PasswordManagerDriver:
81 void PasswordFormsParsed(
82 const std::vector<autofill::PasswordForm>& forms) override {}
83
84 void PasswordFormsRendered(
85 const std::vector<autofill::PasswordForm>& visible_forms,
86 bool did_stop_loading) override {}
87
88 void PasswordFormSubmitted(
89 const autofill::PasswordForm& password_form) override {}
90
91 void InPageNavigation(const autofill::PasswordForm& password_form) override {}
92
93 void PresaveGeneratedPassword(
94 const autofill::PasswordForm& password_form) override {
95 called_presave_generated_password_ = true;
96 }
97
98 void PasswordNoLongerGenerated(
99 const autofill::PasswordForm& password_form) override {
100 called_password_no_longer_generated_ = true;
101 }
102
103 void ShowPasswordSuggestions(int key,
104 base::i18n::TextDirection text_direction,
105 const base::string16& typed_username,
106 int options,
107 const gfx::RectF& bounds) override {}
108
109 void PasswordAutofillAgentConstructed() override {}
110
111 void RecordSavePasswordProgress(const std::string& log) override {}
112
113 void SaveGenerationFieldDetectedByClassifier(
114 const autofill::PasswordForm& password_form,
115 const base::string16& generation_field) override {
116 called_save_generation_field_ = true;
117 save_generation_field_ = generation_field;
118 }
119
120 // Records whether SaveGenerationFieldDetectedByClassifier() gets called.
121 bool called_save_generation_field_ = false;
122 // Records data received via SaveGenerationFieldDetectedByClassifier() call.
123 base::Optional<base::string16> save_generation_field_;
124 // Records whether PasswordNoLongerGenerated() gets called.
125 bool called_password_no_longer_generated_ = false;
126 // Records whether PresaveGeneratedPassword() gets called.
127 bool called_presave_generated_password_ = false;
128
129 mojo::BindingSet<autofill::mojom::PasswordManagerDriver> bindings_;
130 };
131
132 } // namespace
133
32 namespace autofill { 134 namespace autofill {
33 135
34 class PasswordGenerationAgentTest : public ChromeRenderViewTest { 136 class PasswordGenerationAgentTest : public ChromeRenderViewTest {
35 public: 137 public:
36 PasswordGenerationAgentTest() {} 138 PasswordGenerationAgentTest() {}
37 139
140 void RegisterMainFrameRemoteInterfaces() override {
141 // We only use the fake driver for main frame
142 // because our test cases only involve the main frame.
143 shell::InterfaceProvider* remote_interfaces =
144 view_->GetMainRenderFrame()->GetRemoteInterfaces();
145 shell::InterfaceProvider::TestApi test_api(remote_interfaces);
146 test_api.SetBinderForName(
147 mojom::PasswordManagerDriver::Name_,
148 base::Bind(&PasswordGenerationAgentTest::BindPasswordManagerDriver,
149 base::Unretained(this)));
150 }
151
38 void TearDown() override { 152 void TearDown() override {
39 LoadHTML(""); 153 LoadHTML("");
40 ChromeRenderViewTest::TearDown(); 154 ChromeRenderViewTest::TearDown();
41 } 155 }
42 156
43 void LoadHTMLWithUserGesture(const char* html) { 157 void LoadHTMLWithUserGesture(const char* html) {
44 LoadHTML(html); 158 LoadHTML(html);
45 159
46 // Enable show-ime event when element is focused by indicating that a user 160 // Enable show-ime event when element is focused by indicating that a user
47 // gesture has been processed since load. 161 // gesture has been processed since load.
(...skipping 18 matching lines...) Expand all
66 AutofillHostMsg_ShowPasswordGenerationPopup::ID); 180 AutofillHostMsg_ShowPasswordGenerationPopup::ID);
67 if (available) 181 if (available)
68 ASSERT_TRUE(message); 182 ASSERT_TRUE(message);
69 else 183 else
70 ASSERT_FALSE(message); 184 ASSERT_FALSE(message);
71 185
72 render_thread_->sink().ClearMessages(); 186 render_thread_->sink().ClearMessages();
73 } 187 }
74 188
75 void AllowToRunFormClassifier() { 189 void AllowToRunFormClassifier() {
76 AutofillMsg_AllowToRunFormClassifier msg(0); 190 password_generation_->AllowToRunFormClassifier();
77 static_cast<IPC::Listener*>(password_generation_)->OnMessageReceived(msg);
78 } 191 }
79 192
80 void ExpectFormClassifierVoteReceived( 193 void ExpectFormClassifierVoteReceived(
81 bool received, 194 bool received,
82 const base::string16& expected_generation_element) { 195 const base::string16& expected_generation_element) {
83 const IPC::Message* message = 196 base::RunLoop().RunUntilIdle();
84 render_thread_->sink().GetFirstMessageMatching(
85 AutofillHostMsg_SaveGenerationFieldDetectedByClassifier::ID);
86 if (received) { 197 if (received) {
87 ASSERT_TRUE(message); 198 ASSERT_TRUE(fake_driver_.called_save_generation_field());
88 std::tuple<autofill::PasswordForm, base::string16> actual_parameters; 199 EXPECT_EQ(expected_generation_element,
89 AutofillHostMsg_SaveGenerationFieldDetectedByClassifier::Read( 200 fake_driver_.save_generation_field());
90 message, &actual_parameters);
91 EXPECT_EQ(expected_generation_element, std::get<1>(actual_parameters));
92 } else { 201 } else {
93 ASSERT_FALSE(message); 202 ASSERT_FALSE(fake_driver_.called_save_generation_field());
94 } 203 }
95 204
96 render_thread_->sink().ClearMessages(); 205 fake_driver_.reset_save_generation_field();
97 } 206 }
98 207
99 void ShowGenerationPopUpManually(const char* element_id) { 208 void ShowGenerationPopUpManually(const char* element_id) {
100 FocusField(element_id); 209 FocusField(element_id);
101 AutofillMsg_UserTriggeredGeneratePassword msg(0); 210 password_generation_->UserTriggeredGeneratePassword();
102 static_cast<IPC::Listener*>(password_generation_)->OnMessageReceived(msg);
103 } 211 }
104 212
213 void BindPasswordManagerDriver(mojo::ScopedMessagePipeHandle handle) {
214 fake_driver_.BindRequest(
215 mojo::MakeRequest<mojom::PasswordManagerDriver>(std::move(handle)));
216 }
217
218 FakeContentPasswordManagerDriver fake_driver_;
219
105 private: 220 private:
106 DISALLOW_COPY_AND_ASSIGN(PasswordGenerationAgentTest); 221 DISALLOW_COPY_AND_ASSIGN(PasswordGenerationAgentTest);
107 }; 222 };
108 223
109 const char kSigninFormHTML[] = 224 const char kSigninFormHTML[] =
110 "<FORM name = 'blah' action = 'http://www.random.com/'> " 225 "<FORM name = 'blah' action = 'http://www.random.com/'> "
111 " <INPUT type = 'text' id = 'username'/> " 226 " <INPUT type = 'text' id = 'username'/> "
112 " <INPUT type = 'password' id = 'password'/> " 227 " <INPUT type = 'password' id = 'password'/> "
113 " <INPUT type = 'button' id = 'dummy'/> " 228 " <INPUT type = 'button' id = 'dummy'/> "
114 " <INPUT type = 'submit' value = 'LOGIN' />" 229 " <INPUT type = 'submit' value = 'LOGIN' />"
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 WebInputElement first_password_element = element.to<WebInputElement>(); 396 WebInputElement first_password_element = element.to<WebInputElement>();
282 element = document.getElementById(WebString::fromUTF8("second_password")); 397 element = document.getElementById(WebString::fromUTF8("second_password"));
283 ASSERT_FALSE(element.isNull()); 398 ASSERT_FALSE(element.isNull());
284 WebInputElement second_password_element = element.to<WebInputElement>(); 399 WebInputElement second_password_element = element.to<WebInputElement>();
285 400
286 // Both password fields should be empty. 401 // Both password fields should be empty.
287 EXPECT_TRUE(first_password_element.value().isNull()); 402 EXPECT_TRUE(first_password_element.value().isNull());
288 EXPECT_TRUE(second_password_element.value().isNull()); 403 EXPECT_TRUE(second_password_element.value().isNull());
289 404
290 base::string16 password = base::ASCIIToUTF16("random_password"); 405 base::string16 password = base::ASCIIToUTF16("random_password");
291 AutofillMsg_GeneratedPasswordAccepted msg(0, password); 406 password_generation_->GeneratedPasswordAccepted(password);
292 static_cast<IPC::Listener*>(password_generation_)->OnMessageReceived(msg);
293 407
294 // Password fields are filled out and set as being autofilled. 408 // Password fields are filled out and set as being autofilled.
295 EXPECT_EQ(password, first_password_element.value()); 409 EXPECT_EQ(password, first_password_element.value());
296 EXPECT_EQ(password, second_password_element.value()); 410 EXPECT_EQ(password, second_password_element.value());
297 EXPECT_TRUE(first_password_element.isAutofilled()); 411 EXPECT_TRUE(first_password_element.isAutofilled());
298 EXPECT_TRUE(second_password_element.isAutofilled()); 412 EXPECT_TRUE(second_password_element.isAutofilled());
299 413
300 // Make sure onchange events are called. 414 // Make sure onchange events are called.
301 int first_onchange_called = -1; 415 int first_onchange_called = -1;
302 int second_onchange_called = -1; 416 int second_onchange_called = -1;
(...skipping 25 matching lines...) Expand all
328 WebDocument document = GetMainFrame()->document(); 442 WebDocument document = GetMainFrame()->document();
329 WebElement element = 443 WebElement element =
330 document.getElementById(WebString::fromUTF8("first_password")); 444 document.getElementById(WebString::fromUTF8("first_password"));
331 ASSERT_FALSE(element.isNull()); 445 ASSERT_FALSE(element.isNull());
332 WebInputElement first_password_element = element.to<WebInputElement>(); 446 WebInputElement first_password_element = element.to<WebInputElement>();
333 element = document.getElementById(WebString::fromUTF8("second_password")); 447 element = document.getElementById(WebString::fromUTF8("second_password"));
334 ASSERT_FALSE(element.isNull()); 448 ASSERT_FALSE(element.isNull());
335 WebInputElement second_password_element = element.to<WebInputElement>(); 449 WebInputElement second_password_element = element.to<WebInputElement>();
336 450
337 base::string16 password = base::ASCIIToUTF16("random_password"); 451 base::string16 password = base::ASCIIToUTF16("random_password");
338 AutofillMsg_GeneratedPasswordAccepted msg(0, password); 452 password_generation_->GeneratedPasswordAccepted(password);
339 static_cast<IPC::Listener*>(password_generation_)->OnMessageReceived(msg);
340 453
341 // Passwords start out the same. 454 // Passwords start out the same.
342 EXPECT_EQ(password, first_password_element.value()); 455 EXPECT_EQ(password, first_password_element.value());
343 EXPECT_EQ(password, second_password_element.value()); 456 EXPECT_EQ(password, second_password_element.value());
344 457
345 // After editing the first field they are still the same. 458 // After editing the first field they are still the same.
346 std::string edited_password_ascii = "edited_password"; 459 std::string edited_password_ascii = "edited_password";
347 SimulateUserInputChangeForElement(&first_password_element, 460 SimulateUserInputChangeForElement(&first_password_element,
348 edited_password_ascii); 461 edited_password_ascii);
349 base::string16 edited_password = base::ASCIIToUTF16(edited_password_ascii); 462 base::string16 edited_password = base::ASCIIToUTF16(edited_password_ascii);
350 EXPECT_EQ(edited_password, first_password_element.value()); 463 EXPECT_EQ(edited_password, first_password_element.value());
351 EXPECT_EQ(edited_password, second_password_element.value()); 464 EXPECT_EQ(edited_password, second_password_element.value());
352 465
353 // Clear any uninteresting sent messages. 466 // Clear any uninteresting sent messages.
354 render_thread_->sink().ClearMessages(); 467 render_thread_->sink().ClearMessages();
468 fake_driver_.reset_called_password_no_longer_generated();
355 469
356 // Verify that password mirroring works correctly even when the password 470 // Verify that password mirroring works correctly even when the password
357 // is deleted. 471 // is deleted.
358 SimulateUserInputChangeForElement(&first_password_element, std::string()); 472 SimulateUserInputChangeForElement(&first_password_element, std::string());
359 EXPECT_EQ(base::string16(), first_password_element.value()); 473 EXPECT_EQ(base::string16(), first_password_element.value());
360 EXPECT_EQ(base::string16(), second_password_element.value()); 474 EXPECT_EQ(base::string16(), second_password_element.value());
361 475
362 // Should have notified the browser that the password is no longer generated 476 // Should have notified the browser that the password is no longer generated
363 // and trigger generation again. 477 // and trigger generation again.
364 EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching( 478 base::RunLoop().RunUntilIdle();
365 AutofillHostMsg_PasswordNoLongerGenerated::ID)); 479 EXPECT_TRUE(fake_driver_.called_password_no_longer_generated());
366 EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching( 480 EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching(
367 AutofillHostMsg_ShowPasswordGenerationPopup::ID)); 481 AutofillHostMsg_ShowPasswordGenerationPopup::ID));
368 } 482 }
369 483
370 TEST_F(PasswordGenerationAgentTest, BlacklistedTest) { 484 TEST_F(PasswordGenerationAgentTest, BlacklistedTest) {
371 // Did not receive not blacklisted message. Don't show password generation 485 // Did not receive not blacklisted message. Don't show password generation
372 // icon. 486 // icon.
373 LoadHTMLWithUserGesture(kAccountCreationFormHTML); 487 LoadHTMLWithUserGesture(kAccountCreationFormHTML);
374 SetAccountCreationFormsDetectedMessage(password_generation_, 488 SetAccountCreationFormsDetectedMessage(password_generation_,
375 GetMainFrame()->document(), 0, 1); 489 GetMainFrame()->document(), 0, 1);
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 {kPasswordChangeFormHTML, "newpassword"}}; 757 {kPasswordChangeFormHTML, "newpassword"}};
644 for (auto& test_case : kTestCases) { 758 for (auto& test_case : kTestCases) {
645 SCOPED_TRACE(testing::Message("form: ") << test_case.form); 759 SCOPED_TRACE(testing::Message("form: ") << test_case.form);
646 LoadHTMLWithUserGesture(test_case.form); 760 LoadHTMLWithUserGesture(test_case.form);
647 // To be able to work with input elements outside <form>'s, use manual 761 // To be able to work with input elements outside <form>'s, use manual
648 // generation. 762 // generation.
649 ShowGenerationPopUpManually(test_case.generation_element); 763 ShowGenerationPopUpManually(test_case.generation_element);
650 ExpectGenerationAvailable(test_case.generation_element, true); 764 ExpectGenerationAvailable(test_case.generation_element, true);
651 765
652 base::string16 password = base::ASCIIToUTF16("random_password"); 766 base::string16 password = base::ASCIIToUTF16("random_password");
653 AutofillMsg_GeneratedPasswordAccepted msg(0, password); 767 password_generation_->GeneratedPasswordAccepted(password);
654 static_cast<IPC::Listener*>(password_generation_)->OnMessageReceived(msg); 768 base::RunLoop().RunUntilIdle();
655 EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching( 769 EXPECT_TRUE(fake_driver_.called_presave_generated_password());
656 AutofillHostMsg_PresaveGeneratedPassword::ID)); 770 fake_driver_.reset_called_presave_generated_password();
657 render_thread_->sink().ClearMessages();
658 771
659 FocusField(test_case.generation_element); 772 FocusField(test_case.generation_element);
660 SimulateUserTypingASCIICharacter('a', true); 773 SimulateUserTypingASCIICharacter('a', true);
661 EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching( 774 base::RunLoop().RunUntilIdle();
662 AutofillHostMsg_PresaveGeneratedPassword::ID)); 775 EXPECT_TRUE(fake_driver_.called_presave_generated_password());
663 render_thread_->sink().ClearMessages(); 776 fake_driver_.reset_called_presave_generated_password();
664 777
665 for (size_t i = 0; i < password.length(); ++i) 778 for (size_t i = 0; i < password.length(); ++i)
666 SimulateUserTypingASCIICharacter(ui::VKEY_BACK, false); 779 SimulateUserTypingASCIICharacter(ui::VKEY_BACK, false);
667 SimulateUserTypingASCIICharacter(ui::VKEY_BACK, true); 780 SimulateUserTypingASCIICharacter(ui::VKEY_BACK, true);
668 EXPECT_TRUE(render_thread_->sink().GetFirstMessageMatching( 781 base::RunLoop().RunUntilIdle();
669 AutofillHostMsg_PasswordNoLongerGenerated::ID)); 782 EXPECT_TRUE(fake_driver_.called_password_no_longer_generated());
670 render_thread_->sink().ClearMessages(); 783 fake_driver_.reset_called_password_no_longer_generated();
671 } 784 }
672 } 785 }
673 786
674 TEST_F(PasswordGenerationAgentTest, FormClassifierVotesSignupForm) { 787 TEST_F(PasswordGenerationAgentTest, FormClassifierVotesSignupForm) {
675 AllowToRunFormClassifier(); 788 AllowToRunFormClassifier();
676 LoadHTMLWithUserGesture(kAccountCreationFormHTML); 789 LoadHTMLWithUserGesture(kAccountCreationFormHTML);
677 ExpectFormClassifierVoteReceived(true /* vote is expected */, 790 ExpectFormClassifierVoteReceived(true /* vote is expected */,
678 base::ASCIIToUTF16("first_password")); 791 base::ASCIIToUTF16("first_password"));
679 } 792 }
680 793
681 TEST_F(PasswordGenerationAgentTest, FormClassifierVotesSigninForm) { 794 TEST_F(PasswordGenerationAgentTest, FormClassifierVotesSigninForm) {
682 AllowToRunFormClassifier(); 795 AllowToRunFormClassifier();
683 LoadHTMLWithUserGesture(kSigninFormHTML); 796 LoadHTMLWithUserGesture(kSigninFormHTML);
684 ExpectFormClassifierVoteReceived(true /* vote is expected */, 797 ExpectFormClassifierVoteReceived(true /* vote is expected */,
685 base::string16()); 798 base::string16());
686 } 799 }
687 800
688 TEST_F(PasswordGenerationAgentTest, FormClassifierDisabled) { 801 TEST_F(PasswordGenerationAgentTest, FormClassifierDisabled) {
689 LoadHTMLWithUserGesture(kSigninFormHTML); 802 LoadHTMLWithUserGesture(kSigninFormHTML);
690 ExpectFormClassifierVoteReceived(false /* vote is not expected */, 803 ExpectFormClassifierVoteReceived(false /* vote is not expected */,
691 base::string16()); 804 base::string16());
692 } 805 }
693 806
694 } // namespace autofill 807 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698