| Index: chrome/renderer/autofill/autofill_renderer_browsertest.cc
|
| diff --git a/chrome/renderer/autofill/autofill_renderer_browsertest.cc b/chrome/renderer/autofill/autofill_renderer_browsertest.cc
|
| index ead2cf8784e154147e025cd65e59bba79f854d6e..eee167a8d980523bedc3299b9a52eb838d7140ec 100644
|
| --- a/chrome/renderer/autofill/autofill_renderer_browsertest.cc
|
| +++ b/chrome/renderer/autofill/autofill_renderer_browsertest.cc
|
| @@ -12,12 +12,15 @@
|
| #include "base/strings/utf_string_conversions.h"
|
| #include "chrome/test/base/chrome_render_view_test.h"
|
| #include "chrome/test/base/ui_test_utils.h"
|
| -#include "components/autofill/content/common/autofill_messages.h"
|
| +#include "components/autofill/content/public/interfaces/autofill_driver.mojom.h"
|
| #include "components/autofill/content/renderer/autofill_agent.h"
|
| #include "components/autofill/core/common/form_data.h"
|
| #include "components/autofill/core/common/form_field_data.h"
|
| #include "content/public/common/content_switches.h"
|
| #include "content/public/renderer/render_frame.h"
|
| +#include "content/public/renderer/render_view.h"
|
| +#include "mojo/public/cpp/bindings/binding_set.h"
|
| +#include "services/shell/public/cpp/interface_provider.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
| #include "third_party/WebKit/public/platform/WebString.h"
|
| #include "third_party/WebKit/public/platform/WebURLRequest.h"
|
| @@ -41,19 +44,109 @@ using blink::WebVector;
|
|
|
| namespace autofill {
|
|
|
| +namespace {
|
| +
|
| +class FakeContentAutofillDriver : public mojom::AutofillDriver {
|
| + public:
|
| + FakeContentAutofillDriver() : called_field_change_(false) {}
|
| + ~FakeContentAutofillDriver() override {}
|
| +
|
| + void BindRequest(mojom::AutofillDriverRequest request) {
|
| + bindings_.AddBinding(this, std::move(request));
|
| + }
|
| +
|
| + bool called_field_change() const { return called_field_change_; }
|
| +
|
| + const std::vector<FormData>* forms() const { return forms_.get(); }
|
| +
|
| + void reset_forms() { return forms_.reset(); }
|
| +
|
| + private:
|
| + // mojom::AutofillDriver:
|
| + void FirstUserGestureObserved() override {}
|
| +
|
| + void FormsSeen(mojo::Array<FormData> forms,
|
| + base::TimeTicks timestamp) override {
|
| + // FormsSeen() could be called multiple times and sometimes even with empty
|
| + // forms array for main frame, but we're interested in only the first time
|
| + // call.
|
| + if (!forms_)
|
| + forms_.reset(new std::vector<FormData>(forms.PassStorage()));
|
| + }
|
| +
|
| + void WillSubmitForm(const FormData& form,
|
| + base::TimeTicks timestamp) override {}
|
| +
|
| + void FormSubmitted(const FormData& form) override {}
|
| +
|
| + void TextFieldDidChange(const FormData& form,
|
| + const FormFieldData& field,
|
| + base::TimeTicks timestamp) override {
|
| + called_field_change_ = true;
|
| + }
|
| +
|
| + void QueryFormFieldAutofill(int32_t id,
|
| + const FormData& form,
|
| + const FormFieldData& field,
|
| + const gfx::RectF& bounding_box) override {}
|
| +
|
| + void HidePopup() override {}
|
| +
|
| + void PingAck() override {}
|
| +
|
| + void FocusNoLongerOnForm() override {}
|
| +
|
| + void DidFillAutofillFormData(const FormData& form,
|
| + base::TimeTicks timestamp) override {}
|
| +
|
| + void DidPreviewAutofillFormData() override {}
|
| +
|
| + void DidEndTextFieldEditing() override {}
|
| +
|
| + void SetDataList(mojo::Array<mojo::String> values,
|
| + mojo::Array<mojo::String> labels) override {}
|
| +
|
| + // Records whether TextFieldDidChange() get called.
|
| + bool called_field_change_;
|
| + // Records data received via FormSeen() call.
|
| + std::unique_ptr<std::vector<FormData>> forms_;
|
| +
|
| + mojo::BindingSet<mojom::AutofillDriver> bindings_;
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| using AutofillQueryParam =
|
| std::tuple<int, autofill::FormData, autofill::FormFieldData, gfx::RectF>;
|
|
|
| class AutofillRendererTest : public ChromeRenderViewTest {
|
| public:
|
| AutofillRendererTest() {}
|
| +
|
| ~AutofillRendererTest() override {}
|
|
|
| protected:
|
| void SetUp() override {
|
| ChromeRenderViewTest::SetUp();
|
| +
|
| + // We only use the fake driver for main frame
|
| + // because our test cases only involve the main frame.
|
| + shell::InterfaceProvider* remote_interfaces =
|
| + view_->GetMainRenderFrame()->GetRemoteInterfaces();
|
| + shell::InterfaceProvider::TestApi test_api(remote_interfaces);
|
| + test_api.SetBinderForName(
|
| + mojom::AutofillDriver::Name_,
|
| + base::Bind(&AutofillRendererTest::BindAutofillDriver,
|
| + base::Unretained(this)));
|
| + }
|
| +
|
| + void BindAutofillDriver(mojo::ScopedMessagePipeHandle handle) {
|
| + fake_driver_.BindRequest(
|
| + mojo::MakeRequest<mojom::AutofillDriver>(std::move(handle)));
|
| }
|
|
|
| + FakeContentAutofillDriver fake_driver_;
|
| +
|
| private:
|
| DISALLOW_COPY_AND_ASSIGN(AutofillRendererTest);
|
| };
|
| @@ -71,13 +164,11 @@ TEST_F(AutofillRendererTest, SendForms) {
|
| " </select>"
|
| "</form>");
|
|
|
| + base::RunLoop run_loop;
|
| + run_loop.RunUntilIdle();
|
| // Verify that "FormsSeen" sends the expected number of fields.
|
| - const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
|
| - AutofillHostMsg_FormsSeen::ID);
|
| - ASSERT_NE(nullptr, message);
|
| - AutofillHostMsg_FormsSeen::Param params;
|
| - AutofillHostMsg_FormsSeen::Read(message, ¶ms);
|
| - std::vector<FormData> forms = std::get<0>(params);
|
| + ASSERT_TRUE(fake_driver_.forms());
|
| + std::vector<FormData> forms = *(fake_driver_.forms());
|
| ASSERT_EQ(1UL, forms.size());
|
| ASSERT_EQ(4UL, forms[0].fields.size());
|
|
|
| @@ -109,7 +200,7 @@ TEST_F(AutofillRendererTest, SendForms) {
|
| expected.max_length = 0;
|
| EXPECT_FORM_FIELD_DATA_EQUALS(expected, forms[0].fields[3]);
|
|
|
| - render_thread_->sink().ClearMessages();
|
| + fake_driver_.reset_forms();
|
|
|
| // Dynamically create a new form. A new message should be sent for it, but
|
| // not for the previous form.
|
| @@ -136,11 +227,8 @@ TEST_F(AutofillRendererTest, SendForms) {
|
| "document.body.appendChild(newForm);");
|
|
|
| WaitForAutofillDidAssociateFormControl();
|
| - message = render_thread_->sink().GetFirstMessageMatching(
|
| - AutofillHostMsg_FormsSeen::ID);
|
| - ASSERT_NE(nullptr, message);
|
| - AutofillHostMsg_FormsSeen::Read(message, ¶ms);
|
| - forms = std::get<0>(params);
|
| + ASSERT_TRUE(fake_driver_.forms());
|
| + forms = *(fake_driver_.forms());
|
| ASSERT_EQ(1UL, forms.size());
|
| ASSERT_EQ(3UL, forms[0].fields.size());
|
|
|
| @@ -166,13 +254,11 @@ TEST_F(AutofillRendererTest, EnsureNoFormSeenIfTooFewFields) {
|
| " <input type='text' id='middlename'/>"
|
| "</form>");
|
|
|
| + base::RunLoop run_loop;
|
| + run_loop.RunUntilIdle();
|
| // Verify that "FormsSeen" isn't sent, as there are too few fields.
|
| - const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
|
| - AutofillHostMsg_FormsSeen::ID);
|
| - ASSERT_NE(nullptr, message);
|
| - AutofillHostMsg_FormsSeen::Param params;
|
| - AutofillHostMsg_FormsSeen::Read(message, ¶ms);
|
| - const std::vector<FormData>& forms = std::get<0>(params);
|
| + ASSERT_TRUE(fake_driver_.forms());
|
| + const std::vector<FormData>& forms = *(fake_driver_.forms());
|
| ASSERT_EQ(0UL, forms.size());
|
| }
|
|
|
| @@ -199,26 +285,21 @@ TEST_F(AutofillRendererTest, DynamicallyAddedUnownedFormElements) {
|
| ASSERT_TRUE(base::ReadFileToString(test_path, &html_data));
|
| LoadHTML(html_data.c_str());
|
|
|
| + base::RunLoop run_loop;
|
| + run_loop.RunUntilIdle();
|
| // Verify that "FormsSeen" sends the expected number of fields.
|
| - const IPC::Message* message = render_thread_->sink().GetFirstMessageMatching(
|
| - AutofillHostMsg_FormsSeen::ID);
|
| - ASSERT_NE(nullptr, message);
|
| - AutofillHostMsg_FormsSeen::Param params;
|
| - AutofillHostMsg_FormsSeen::Read(message, ¶ms);
|
| - std::vector<FormData> forms = std::get<0>(params);
|
| + ASSERT_TRUE(fake_driver_.forms());
|
| + std::vector<FormData> forms = *(fake_driver_.forms());
|
| ASSERT_EQ(1UL, forms.size());
|
| ASSERT_EQ(7UL, forms[0].fields.size());
|
|
|
| - render_thread_->sink().ClearMessages();
|
| + fake_driver_.reset_forms();
|
|
|
| ExecuteJavaScriptForTests("AddFields()");
|
|
|
| WaitForAutofillDidAssociateFormControl();
|
| - message = render_thread_->sink().GetFirstMessageMatching(
|
| - AutofillHostMsg_FormsSeen::ID);
|
| - ASSERT_NE(nullptr, message);
|
| - AutofillHostMsg_FormsSeen::Read(message, ¶ms);
|
| - forms = std::get<0>(params);
|
| + ASSERT_TRUE(fake_driver_.forms());
|
| + forms = *(fake_driver_.forms());
|
| ASSERT_EQ(1UL, forms.size());
|
| ASSERT_EQ(9UL, forms[0].fields.size());
|
|
|
| @@ -250,17 +331,16 @@ TEST_F(AutofillRendererTest, IgnoreNonUserGestureTextFieldChanges) {
|
|
|
| // Not a user gesture, so no IPC message to browser.
|
| DisableUserGestureSimulationForAutofill();
|
| + ASSERT_FALSE(fake_driver_.called_field_change());
|
| full_name.setValue("Alice", true);
|
| GetMainFrame()->autofillClient()->textFieldDidChange(full_name);
|
| base::RunLoop().RunUntilIdle();
|
| - ASSERT_EQ(nullptr, render_thread_->sink().GetFirstMessageMatching(
|
| - AutofillHostMsg_TextFieldDidChange::ID));
|
| + ASSERT_FALSE(fake_driver_.called_field_change());
|
|
|
| // A user gesture will send a message to the browser.
|
| EnableUserGestureSimulationForAutofill();
|
| SimulateUserInputChangeForElement(&full_name, "Alice");
|
| - ASSERT_NE(nullptr, render_thread_->sink().GetFirstMessageMatching(
|
| - AutofillHostMsg_TextFieldDidChange::ID));
|
| + ASSERT_TRUE(fake_driver_.called_field_change());
|
| }
|
|
|
| } // namespace autofill
|
|
|