blob: 399e4bf717fdfd9ed62e03c6c493231cf44364e1 [file] [log] [blame]
[email protected]e13549e2014-03-12 20:34:361// Copyright 2014 The Chromium Authors. All rights reserved.
[email protected]dbd4b1d2012-12-14 04:28:342// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Sebastien Marchandf1349f52019-01-25 03:16:415#include "base/bind.h"
avie4d7b6f2015-12-26 00:59:186#include "base/macros.h"
vabr55b61322016-04-04 14:08:397#include "base/memory/ref_counted.h"
[email protected]0b2f513b2013-04-05 20:13:238#include "chrome/browser/browser_process.h"
[email protected]dbd4b1d2012-12-14 04:28:349#include "chrome/browser/ui/browser.h"
10#include "chrome/browser/ui/browser_tabstrip.h"
[email protected]cc872372013-01-28 21:57:0711#include "chrome/browser/ui/tabs/tab_strip_model.h"
[email protected]dbd4b1d2012-12-14 04:28:3412#include "chrome/common/url_constants.h"
13#include "chrome/test/base/in_process_browser_test.h"
Mathieu Perreaulte83ab272017-08-08 15:55:3114#include "chrome/test/base/ui_test_utils.h"
[email protected]e13549e2014-03-12 20:34:3615#include "components/autofill/content/browser/content_autofill_driver.h"
estadeb1bc9bd2014-12-02 22:44:1116#include "components/autofill/content/browser/content_autofill_driver_factory.h"
[email protected]526a16b2013-06-20 11:44:3317#include "components/autofill/core/browser/autofill_manager.h"
[email protected]b4db6d42014-06-07 04:36:5818#include "components/autofill/core/browser/test_autofill_client.h"
Moe Ahmadi173b0a2b2018-08-03 17:35:5119#include "components/autofill/core/common/autofill_prefs.h"
maxbogueea16ff412016-10-28 16:35:2920#include "components/sync_preferences/testing_pref_service_syncable.h"
[email protected]dbd4b1d2012-12-14 04:28:3421#include "content/public/browser/navigation_controller.h"
jam72c9c6d2017-02-23 18:30:3622#include "content/public/browser/navigation_handle.h"
[email protected]dbd4b1d2012-12-14 04:28:3423#include "content/public/browser/page_navigator.h"
24#include "content/public/browser/web_contents.h"
[email protected]89f6b172013-06-16 03:06:4125#include "content/public/browser/web_contents_observer.h"
[email protected]dbd4b1d2012-12-14 04:28:3426#include "content/public/common/url_constants.h"
Mathieu Perreaulte83ab272017-08-08 15:55:3127#include "content/public/test/browser_test_utils.h"
[email protected]dbd4b1d2012-12-14 04:28:3428#include "content/public/test/test_utils.h"
Mathieu Perreaulte83ab272017-08-08 15:55:3129#include "net/dns/mock_host_resolver.h"
30#include "net/test/embedded_test_server/embedded_test_server.h"
[email protected]8ac8bfd2013-02-27 05:18:0831#include "testing/gmock/include/gmock/gmock.h"
[email protected]dbd4b1d2012-12-14 04:28:3432#include "testing/gtest/include/gtest/gtest.h"
tfarina3b0452d2014-12-31 15:20:0933#include "ui/gfx/geometry/rect.h"
[email protected]dbd4b1d2012-12-14 04:28:3434
[email protected]bfd4b812013-04-11 02:02:1135namespace autofill {
[email protected]dbd4b1d2012-12-14 04:28:3436namespace {
37
Mathieu Perreaulte83ab272017-08-08 15:55:3138const base::FilePath::CharType kDocRoot[] =
39 FILE_PATH_LITERAL("chrome/test/data");
40
[email protected]b4db6d42014-06-07 04:36:5841class MockAutofillClient : public TestAutofillClient {
[email protected]dbd4b1d2012-12-14 04:28:3442 public:
[email protected]b4db6d42014-06-07 04:36:5843 MockAutofillClient() {}
Daniel Cheng51249952018-04-27 06:48:5044 ~MockAutofillClient() override {}
[email protected]3ca73692013-03-07 21:31:3345
Daniel Cheng51249952018-04-27 06:48:5046 PrefService* GetPrefs() override { return &prefs_; }
[email protected]dbd4b1d2012-12-14 04:28:3447
[email protected]443e9312013-05-06 06:17:3448 user_prefs::PrefRegistrySyncable* GetPrefRegistry() {
[email protected]8ac8bfd2013-02-27 05:18:0849 return prefs_.registry();
[email protected]dbd4b1d2012-12-14 04:28:3450 }
51
Fabio Tirelo83662a22018-07-06 15:03:4852 MOCK_METHOD5(ShowAutofillPopup,
[email protected]8ac8bfd2013-02-27 05:18:0853 void(const gfx::RectF& element_bounds,
[email protected]46cb7e92013-06-12 15:32:3154 base::i18n::TextDirection text_direction,
brettw5f888152014-12-15 23:31:2655 const std::vector<autofill::Suggestion>& suggestions,
Fabio Tirelo83662a22018-07-06 15:03:4856 bool autoselect_first_suggestion,
[email protected]1f66a3892013-04-22 18:57:1457 base::WeakPtr<AutofillPopupDelegate> delegate));
[email protected]e37128f2013-02-15 17:48:3958
[email protected]8ac8bfd2013-02-27 05:18:0859 MOCK_METHOD0(HideAutofillPopup, void());
[email protected]e37128f2013-02-15 17:48:3960
61 private:
maxbogueea16ff412016-10-28 16:35:2962 sync_preferences::TestingPrefServiceSyncable prefs_;
[email protected]3ca73692013-03-07 21:31:3363
[email protected]b4db6d42014-06-07 04:36:5864 DISALLOW_COPY_AND_ASSIGN(MockAutofillClient);
[email protected]8ac8bfd2013-02-27 05:18:0865};
66
[email protected]e13549e2014-03-12 20:34:3667// Subclass ContentAutofillDriver so we can create an ContentAutofillDriver
68// instance.
69class TestContentAutofillDriver : public ContentAutofillDriver {
[email protected]8ac8bfd2013-02-27 05:18:0870 public:
estadeb1bc9bd2014-12-02 22:44:1171 TestContentAutofillDriver(content::RenderFrameHost* rfh,
[email protected]b4db6d42014-06-07 04:36:5872 AutofillClient* client)
michaelbai927a09ab02017-06-01 19:36:5773 : ContentAutofillDriver(rfh,
74 client,
75 g_browser_process->GetApplicationLocale(),
76 AutofillManager::ENABLE_AUTOFILL_DOWNLOAD_MANAGER,
77 nullptr) {}
Daniel Chenga542fca2014-10-21 09:51:2978 ~TestContentAutofillDriver() override {}
[email protected]8ac8bfd2013-02-27 05:18:0879
80 private:
[email protected]e13549e2014-03-12 20:34:3681 DISALLOW_COPY_AND_ASSIGN(TestContentAutofillDriver);
[email protected]dbd4b1d2012-12-14 04:28:3482};
83
84} // namespace
85
[email protected]e13549e2014-03-12 20:34:3686class ContentAutofillDriverBrowserTest : public InProcessBrowserTest,
87 public content::WebContentsObserver {
[email protected]dbd4b1d2012-12-14 04:28:3488 public:
[email protected]e13549e2014-03-12 20:34:3689 ContentAutofillDriverBrowserTest() {}
Daniel Cheng51249952018-04-27 06:48:5090 ~ContentAutofillDriverBrowserTest() override {}
[email protected]dbd4b1d2012-12-14 04:28:3491
thestig397accd2015-04-04 00:03:0492 void SetUpOnMainThread() override {
Sylvain Defresnecc71d242018-11-05 14:39:2293 autofill_client_ =
94 std::make_unique<testing::NiceMock<MockAutofillClient>>();
[email protected]12a46832014-05-09 13:35:5895 content::WebContents* web_contents =
96 browser()->tab_strip_model()->GetActiveWebContents();
97 ASSERT_TRUE(web_contents != NULL);
98 Observe(web_contents);
Sylvain Defresnecc71d242018-11-05 14:39:2299 prefs::RegisterProfilePrefs(autofill_client().GetPrefRegistry());
[email protected]8ac8bfd2013-02-27 05:18:08100
estadeb1bc9bd2014-12-02 22:44:11101 web_contents->RemoveUserData(
102 ContentAutofillDriverFactory::
103 kContentAutofillDriverFactoryWebContentsUserDataKey);
104 ContentAutofillDriverFactory::CreateForWebContentsAndDelegate(
Sylvain Defresnecc71d242018-11-05 14:39:22105 web_contents, &autofill_client(), "en-US",
estadeb1bc9bd2014-12-02 22:44:11106 AutofillManager::DISABLE_AUTOFILL_DOWNLOAD_MANAGER);
Mathieu Perreaulte83ab272017-08-08 15:55:31107
108 embedded_test_server()->AddDefaultHandlers(base::FilePath(kDocRoot));
109 // Serve both a.com and b.com (and any other domain).
110 host_resolver()->AddRule("*", "127.0.0.1");
111 ASSERT_TRUE(embedded_test_server()->Start());
112 }
113
114 void TearDownOnMainThread() override {
115 // Verify the expectations here, because closing the browser may incur
Sylvain Defresnecc71d242018-11-05 14:39:22116 // other calls in |autofill_client()| e.g., HideAutofillPopup.
117 testing::Mock::VerifyAndClearExpectations(&autofill_client());
[email protected]dbd4b1d2012-12-14 04:28:34118 }
119
Francois Dorayfe4a1772018-02-17 04:17:09120 void OnVisibilityChanged(content::Visibility visibility) override {
121 if (visibility == content::Visibility::HIDDEN &&
122 !web_contents_hidden_callback_.is_null()) {
[email protected]82ed5b12013-10-09 20:35:45123 web_contents_hidden_callback_.Run();
Francois Dorayfe4a1772018-02-17 04:17:09124 }
[email protected]82ed5b12013-10-09 20:35:45125 }
126
vabr393a31d2016-03-17 16:16:49127 void DidFinishNavigation(
128 content::NavigationHandle* navigation_handle) override {
jam72c9c6d2017-02-23 18:30:36129 if (!navigation_handle->HasCommitted())
130 return;
131
[email protected]82ed5b12013-10-09 20:35:45132 if (!nav_entry_committed_callback_.is_null())
133 nav_entry_committed_callback_.Run();
Mathieu Perreaulte83ab272017-08-08 15:55:31134
135 if (navigation_handle->IsSameDocument() &&
136 !same_document_navigation_callback_.is_null()) {
137 same_document_navigation_callback_.Run();
138 }
139
140 if (!navigation_handle->IsInMainFrame() &&
141 !subframe_navigation_callback_.is_null()) {
142 subframe_navigation_callback_.Run();
143 }
[email protected]82ed5b12013-10-09 20:35:45144 }
145
gogeraldd52275112018-09-21 02:17:22146 void GetElementFormAndFieldData(const std::vector<std::string>& selectors,
147 size_t expected_form_size) {
148 base::RunLoop run_loop;
149 ContentAutofillDriverFactory::FromWebContents(web_contents())
150 ->DriverForFrame(web_contents()->GetMainFrame())
151 ->GetAutofillAgent()
152 ->GetElementFormAndFieldData(
153 selectors,
154 base::BindOnce(
155 &ContentAutofillDriverBrowserTest::OnGetElementFormAndFieldData,
156 base::Unretained(this), run_loop.QuitClosure(),
157 expected_form_size));
158 run_loop.Run();
159 }
160
161 void OnGetElementFormAndFieldData(const base::Closure& done_callback,
162 size_t expected_form_size,
163 const autofill::FormData& form_data,
164 const autofill::FormFieldData& form_field) {
165 done_callback.Run();
166 if (expected_form_size) {
167 ASSERT_EQ(form_data.fields.size(), expected_form_size);
168 ASSERT_FALSE(form_field.label.empty());
169 } else {
170 ASSERT_EQ(form_data.fields.size(), expected_form_size);
171 ASSERT_TRUE(form_field.label.empty());
172 }
173 }
174
Sylvain Defresnecc71d242018-11-05 14:39:22175 testing::NiceMock<MockAutofillClient>& autofill_client() {
176 return *autofill_client_.get();
177 }
178
[email protected]dbd4b1d2012-12-14 04:28:34179 protected:
[email protected]82ed5b12013-10-09 20:35:45180 base::Closure web_contents_hidden_callback_;
181 base::Closure nav_entry_committed_callback_;
Mathieu Perreaulte83ab272017-08-08 15:55:31182 base::Closure same_document_navigation_callback_;
183 base::Closure subframe_navigation_callback_;
[email protected]82ed5b12013-10-09 20:35:45184
Sylvain Defresnecc71d242018-11-05 14:39:22185 std::unique_ptr<testing::NiceMock<MockAutofillClient>> autofill_client_;
[email protected]dbd4b1d2012-12-14 04:28:34186};
187
[email protected]e13549e2014-03-12 20:34:36188IN_PROC_BROWSER_TEST_F(ContentAutofillDriverBrowserTest,
[email protected]aa4a8022013-01-19 04:37:16189 SwitchTabAndHideAutofillPopup) {
Sylvain Defresnecc71d242018-11-05 14:39:22190 EXPECT_CALL(autofill_client(), HideAutofillPopup()).Times(1);
[email protected]8ac8bfd2013-02-27 05:18:08191
[email protected]82ed5b12013-10-09 20:35:45192 scoped_refptr<content::MessageLoopRunner> runner =
193 new content::MessageLoopRunner;
194 web_contents_hidden_callback_ = runner->QuitClosure();
[email protected]e13549e2014-03-12 20:34:36195 chrome::AddSelectedTabWithURL(browser(),
[email protected]8e09c7af2014-06-10 11:46:17196 GURL(url::kAboutBlankURL),
Sylvain Defresnec6ccc77d2014-09-19 10:19:35197 ui::PAGE_TRANSITION_AUTO_TOPLEVEL);
[email protected]82ed5b12013-10-09 20:35:45198 runner->Run();
199 web_contents_hidden_callback_.Reset();
[email protected]dbd4b1d2012-12-14 04:28:34200}
201
[email protected]e13549e2014-03-12 20:34:36202IN_PROC_BROWSER_TEST_F(ContentAutofillDriverBrowserTest,
Mathieu Perreaulte83ab272017-08-08 15:55:31203 SameDocumentNavigationHideAutofillPopup) {
204 ui_test_utils::NavigateToURL(
205 browser(),
206 embedded_test_server()->GetURL("/autofill/autofill_test_form.html"));
207
208 // The Autofill popup should be hidden for same document navigations. It may
209 // called twice because the zoom changed event may also fire for same-page
210 // navigations.
Sylvain Defresnecc71d242018-11-05 14:39:22211 EXPECT_CALL(autofill_client(), HideAutofillPopup())
212 .Times(testing::AtLeast(1));
[email protected]e37128f2013-02-15 17:48:39213
[email protected]82ed5b12013-10-09 20:35:45214 scoped_refptr<content::MessageLoopRunner> runner =
215 new content::MessageLoopRunner;
Mathieu Perreaulte83ab272017-08-08 15:55:31216 same_document_navigation_callback_ = runner->QuitClosure();
217 ui_test_utils::NavigateToURL(
218 browser(),
219 embedded_test_server()->GetURL("/autofill/autofill_test_form.html#foo"));
220 // This will block until a same document navigation is observed.
221 runner->Run();
222 same_document_navigation_callback_.Reset();
223}
224
225IN_PROC_BROWSER_TEST_F(ContentAutofillDriverBrowserTest,
226 SubframeNavigationDoesntHideAutofillPopup) {
227 // Main frame is on a.com, iframe is on b.com.
228 GURL url = embedded_test_server()->GetURL(
229 "a.com", "/autofill/cross_origin_iframe.html");
230 ui_test_utils::NavigateToURL(browser(), url);
231
232 // The Autofill popup should NOT be hidden for subframe navigations.
Sylvain Defresnecc71d242018-11-05 14:39:22233 EXPECT_CALL(autofill_client(), HideAutofillPopup()).Times(0);
Mathieu Perreaulte83ab272017-08-08 15:55:31234
235 scoped_refptr<content::MessageLoopRunner> runner =
236 new content::MessageLoopRunner;
237 subframe_navigation_callback_ = runner->QuitClosure();
238 GURL iframe_url = embedded_test_server()->GetURL(
239 "b.com", "/autofill/autofill_test_form.html");
240 EXPECT_TRUE(content::NavigateIframeToURL(
241 browser()->tab_strip_model()->GetActiveWebContents(), "crossFrame",
242 iframe_url));
243 // This will block until a subframe navigation is observed.
244 runner->Run();
245 subframe_navigation_callback_.Reset();
246}
247
248IN_PROC_BROWSER_TEST_F(ContentAutofillDriverBrowserTest,
249 TestPageNavigationHidingAutofillPopup) {
250 // HideAutofillPopup is called once for each navigation.
Sylvain Defresnecc71d242018-11-05 14:39:22251 EXPECT_CALL(autofill_client(), HideAutofillPopup()).Times(2);
Mathieu Perreaulte83ab272017-08-08 15:55:31252
253 scoped_refptr<content::MessageLoopRunner> runner =
254 new content::MessageLoopRunner;
[email protected]82ed5b12013-10-09 20:35:45255 nav_entry_committed_callback_ = runner->QuitClosure();
nick3b04f322016-08-31 19:29:19256 browser()->OpenURL(content::OpenURLParams(
257 GURL(chrome::kChromeUIBookmarksURL), content::Referrer(),
258 WindowOpenDisposition::CURRENT_TAB, ui::PAGE_TRANSITION_TYPED, false));
259 browser()->OpenURL(content::OpenURLParams(
260 GURL(chrome::kChromeUIAboutURL), content::Referrer(),
261 WindowOpenDisposition::CURRENT_TAB, ui::PAGE_TRANSITION_TYPED, false));
[email protected]82ed5b12013-10-09 20:35:45262 runner->Run();
263 nav_entry_committed_callback_.Reset();
[email protected]dbd4b1d2012-12-14 04:28:34264}
[email protected]bfd4b812013-04-11 02:02:11265
gogeraldd52275112018-09-21 02:17:22266IN_PROC_BROWSER_TEST_F(ContentAutofillDriverBrowserTest,
267 GetElementFormAndFieldData) {
268 ui_test_utils::NavigateToURL(
269 browser(), embedded_test_server()->GetURL(
270 "/autofill/autofill_assistant_test_form.html"));
271
272 std::vector<std::string> selectors;
273 selectors.emplace_back("#testformone");
274 selectors.emplace_back("#NAME_FIRST");
275 GetElementFormAndFieldData(selectors, /*expected_form_size=*/9u);
276
277 selectors.clear();
278 selectors.emplace_back("#testformtwo");
279 selectors.emplace_back("#NAME_FIRST");
280 GetElementFormAndFieldData(selectors, /*expected_form_size=*/7u);
281
282 // Multiple corresponding form fields.
283 selectors.clear();
284 selectors.emplace_back("#NAME_FIRST");
285 GetElementFormAndFieldData(selectors, /*expected_form_size=*/0u);
286
287 // No corresponding form field.
288 selectors.clear();
289 selectors.emplace_back("#whatever");
290 GetElementFormAndFieldData(selectors, /*expected_form_size=*/0u);
291}
292
[email protected]bfd4b812013-04-11 02:02:11293} // namespace autofill