OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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> | 5 #include <string> |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/files/file_util.h" | 8 #include "base/files/file_util.h" |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
10 #include "base/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
(...skipping 24 matching lines...) Expand all Loading... |
35 #include "components/autofill/core/browser/autofill_profile.h" | 35 #include "components/autofill/core/browser/autofill_profile.h" |
36 #include "components/autofill/core/browser/autofill_test_utils.h" | 36 #include "components/autofill/core/browser/autofill_test_utils.h" |
37 #include "components/autofill/core/browser/validation.h" | 37 #include "components/autofill/core/browser/validation.h" |
38 #include "components/translate/core/browser/translate_manager.h" | 38 #include "components/translate/core/browser/translate_manager.h" |
39 #include "content/public/browser/navigation_controller.h" | 39 #include "content/public/browser/navigation_controller.h" |
40 #include "content/public/browser/notification_observer.h" | 40 #include "content/public/browser/notification_observer.h" |
41 #include "content/public/browser/notification_registrar.h" | 41 #include "content/public/browser/notification_registrar.h" |
42 #include "content/public/browser/notification_service.h" | 42 #include "content/public/browser/notification_service.h" |
43 #include "content/public/browser/render_view_host.h" | 43 #include "content/public/browser/render_view_host.h" |
44 #include "content/public/browser/render_widget_host.h" | 44 #include "content/public/browser/render_widget_host.h" |
| 45 #include "content/public/browser/render_widget_host_view.h" |
45 #include "content/public/browser/web_contents.h" | 46 #include "content/public/browser/web_contents.h" |
46 #include "content/public/test/browser_test_utils.h" | 47 #include "content/public/test/browser_test_utils.h" |
47 #include "content/public/test/test_renderer_host.h" | 48 #include "content/public/test/test_renderer_host.h" |
48 #include "content/public/test/test_utils.h" | 49 #include "content/public/test/test_utils.h" |
49 #include "net/base/net_errors.h" | 50 #include "net/base/net_errors.h" |
| 51 #include "net/dns/mock_host_resolver.h" |
50 #include "net/test/embedded_test_server/embedded_test_server.h" | 52 #include "net/test/embedded_test_server/embedded_test_server.h" |
51 #include "net/url_request/test_url_fetcher_factory.h" | 53 #include "net/url_request/test_url_fetcher_factory.h" |
52 #include "net/url_request/url_request_status.h" | 54 #include "net/url_request/url_request_status.h" |
53 #include "testing/gmock/include/gmock/gmock.h" | 55 #include "testing/gmock/include/gmock/gmock.h" |
54 #include "testing/gtest/include/gtest/gtest.h" | 56 #include "testing/gtest/include/gtest/gtest.h" |
55 #include "ui/base/clipboard/scoped_clipboard_writer.h" | 57 #include "ui/base/clipboard/scoped_clipboard_writer.h" |
56 #include "ui/events/base_event_utils.h" | 58 #include "ui/events/base_event_utils.h" |
57 #include "ui/events/keycodes/keyboard_code_conversion.h" | 59 #include "ui/events/keycodes/keyboard_code_conversion.h" |
58 #include "ui/events/keycodes/keyboard_codes.h" | 60 #include "ui/events/keycodes/keyboard_codes.h" |
59 | 61 |
60 using base::ASCIIToUTF16; | 62 using base::ASCIIToUTF16; |
61 | 63 |
62 namespace autofill { | 64 namespace autofill { |
63 | 65 |
| 66 namespace { |
| 67 |
64 static const char kDataURIPrefix[] = "data:text/html;charset=utf-8,"; | 68 static const char kDataURIPrefix[] = "data:text/html;charset=utf-8,"; |
65 static const char kTestFormString[] = | 69 static const char kTestFormString[] = |
66 "<form action=\"http://www.example.com/\" method=\"POST\">" | 70 "<form action=\"http://www.example.com/\" method=\"POST\">" |
67 "<label for=\"firstname\">First name:</label>" | 71 "<label for=\"firstname\">First name:</label>" |
68 " <input type=\"text\" id=\"firstname\"" | 72 " <input type=\"text\" id=\"firstname\"" |
69 " onfocus=\"domAutomationController.send(true)\"><br>" | 73 " onfocus=\"domAutomationController.send(true)\"><br>" |
70 "<label for=\"lastname\">Last name:</label>" | 74 "<label for=\"lastname\">Last name:</label>" |
71 " <input type=\"text\" id=\"lastname\"><br>" | 75 " <input type=\"text\" id=\"lastname\"><br>" |
72 "<label for=\"address1\">Address line 1:</label>" | 76 "<label for=\"address1\">Address line 1:</label>" |
73 " <input type=\"text\" id=\"address1\"><br>" | 77 " <input type=\"text\" id=\"address1\"><br>" |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 loop_runner_->Run(); | 203 loop_runner_->Run(); |
200 } | 204 } |
201 | 205 |
202 private: | 206 private: |
203 scoped_refptr<content::MessageLoopRunner> loop_runner_; | 207 scoped_refptr<content::MessageLoopRunner> loop_runner_; |
204 bool waiting_for_text_change_; | 208 bool waiting_for_text_change_; |
205 | 209 |
206 DISALLOW_COPY_AND_ASSIGN(AutofillManagerTestDelegateImpl); | 210 DISALLOW_COPY_AND_ASSIGN(AutofillManagerTestDelegateImpl); |
207 }; | 211 }; |
208 | 212 |
| 213 // Searches all frames of |web_contents| and returns one called |name|. If |
| 214 // there are none, returns null, if there are more, returns an arbitrary one. |
| 215 content::RenderFrameHost* RenderFrameHostForName( |
| 216 content::WebContents* web_contents, |
| 217 const std::string& name) { |
| 218 for (content::RenderFrameHost* frame : web_contents->GetAllFrames()) { |
| 219 if (frame->GetFrameName() == name) |
| 220 return frame; |
| 221 } |
| 222 return nullptr; |
| 223 } |
| 224 |
| 225 } // namespace |
| 226 |
209 // AutofillInteractiveTest ---------------------------------------------------- | 227 // AutofillInteractiveTest ---------------------------------------------------- |
210 | 228 |
211 class AutofillInteractiveTest : public InProcessBrowserTest { | 229 class AutofillInteractiveTest : public InProcessBrowserTest { |
212 protected: | 230 protected: |
213 AutofillInteractiveTest() : | 231 AutofillInteractiveTest() : |
214 key_press_event_sink_( | 232 key_press_event_sink_( |
215 base::Bind(&AutofillInteractiveTest::HandleKeyPressEvent, | 233 base::Bind(&AutofillInteractiveTest::HandleKeyPressEvent, |
216 base::Unretained(this))) {} | 234 base::Unretained(this))) {} |
217 ~AutofillInteractiveTest() override {} | 235 ~AutofillInteractiveTest() override {} |
218 | 236 |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 test_delegate_.WaitForTextChange(); | 459 test_delegate_.WaitForTextChange(); |
442 } | 460 } |
443 | 461 |
444 bool HandleKeyPressEvent(const content::NativeWebKeyboardEvent& event) { | 462 bool HandleKeyPressEvent(const content::NativeWebKeyboardEvent& event) { |
445 return true; | 463 return true; |
446 } | 464 } |
447 | 465 |
448 void SendKeyToPopupAndWait(ui::DomKey key) { | 466 void SendKeyToPopupAndWait(ui::DomKey key) { |
449 ui::KeyboardCode key_code = ui::NonPrintableDomKeyToKeyboardCode(key); | 467 ui::KeyboardCode key_code = ui::NonPrintableDomKeyToKeyboardCode(key); |
450 ui::DomCode code = ui::UsLayoutKeyboardCodeToDomCode(key_code); | 468 ui::DomCode code = ui::UsLayoutKeyboardCodeToDomCode(key_code); |
451 SendKeyToPopupAndWait(key, code, key_code); | 469 SendKeyToPopupAndWait(key, code, key_code, |
| 470 GetRenderViewHost()->GetWidget()); |
452 } | 471 } |
453 | 472 |
454 void SendKeyToPopupAndWait(ui::DomKey key, | 473 void SendKeyToPopupAndWait(ui::DomKey key, |
455 ui::DomCode code, | 474 ui::DomCode code, |
456 ui::KeyboardCode key_code) { | 475 ui::KeyboardCode key_code, |
| 476 content::RenderWidgetHost* widget) { |
457 // Route popup-targeted key presses via the render view host. | 477 // Route popup-targeted key presses via the render view host. |
458 content::NativeWebKeyboardEvent event(blink::WebKeyboardEvent::RawKeyDown, | 478 content::NativeWebKeyboardEvent event(blink::WebKeyboardEvent::RawKeyDown, |
459 blink::WebInputEvent::NoModifiers, | 479 blink::WebInputEvent::NoModifiers, |
460 ui::EventTimeForNow()); | 480 ui::EventTimeForNow()); |
461 event.windowsKeyCode = key_code; | 481 event.windowsKeyCode = key_code; |
462 event.domCode = static_cast<int>(code); | 482 event.domCode = static_cast<int>(code); |
463 event.domKey = key; | 483 event.domKey = key; |
464 test_delegate_.Reset(); | 484 test_delegate_.Reset(); |
465 // Install the key press event sink to ensure that any events that are not | 485 // Install the key press event sink to ensure that any events that are not |
466 // handled by the installed callbacks do not end up crashing the test. | 486 // handled by the installed callbacks do not end up crashing the test. |
467 GetRenderViewHost()->GetWidget()->AddKeyPressEventCallback( | 487 widget->AddKeyPressEventCallback(key_press_event_sink_); |
468 key_press_event_sink_); | 488 widget->ForwardKeyboardEvent(event); |
469 GetRenderViewHost()->GetWidget()->ForwardKeyboardEvent(event); | |
470 test_delegate_.Wait(); | 489 test_delegate_.Wait(); |
471 GetRenderViewHost()->GetWidget()->RemoveKeyPressEventCallback( | 490 widget->RemoveKeyPressEventCallback(key_press_event_sink_); |
472 key_press_event_sink_); | |
473 } | 491 } |
474 | 492 |
475 void SendKeyToDataListPopup(ui::DomKey key) { | 493 void SendKeyToDataListPopup(ui::DomKey key) { |
476 ui::KeyboardCode key_code = ui::NonPrintableDomKeyToKeyboardCode(key); | 494 ui::KeyboardCode key_code = ui::NonPrintableDomKeyToKeyboardCode(key); |
477 ui::DomCode code = ui::UsLayoutKeyboardCodeToDomCode(key_code); | 495 ui::DomCode code = ui::UsLayoutKeyboardCodeToDomCode(key_code); |
478 SendKeyToDataListPopup(key, code, key_code); | 496 SendKeyToDataListPopup(key, code, key_code); |
479 } | 497 } |
480 | 498 |
481 // Datalist does not support autofill preview. There is no need to start | 499 // Datalist does not support autofill preview. There is no need to start |
482 // message loop for Datalist. | 500 // message loop for Datalist. |
(...skipping 1245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1728 GURL url = https_server.GetURL("/autofill/autofill_password_form.html"); | 1746 GURL url = https_server.GetURL("/autofill/autofill_password_form.html"); |
1729 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), url)); | 1747 ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), url)); |
1730 | 1748 |
1731 ASSERT_TRUE(content::ExecuteScript( | 1749 ASSERT_TRUE(content::ExecuteScript( |
1732 GetRenderViewHost(), | 1750 GetRenderViewHost(), |
1733 "document.getElementById('user').value = 'user';")); | 1751 "document.getElementById('user').value = 'user';")); |
1734 FocusFieldByName("password"); | 1752 FocusFieldByName("password"); |
1735 PasteStringAndWait("foobar"); | 1753 PasteStringAndWait("foobar"); |
1736 } | 1754 } |
1737 | 1755 |
| 1756 // An extension of the test fixture for tests with site isolation. |
| 1757 class AutofillInteractiveIsolationTest : public AutofillInteractiveTest { |
| 1758 protected: |
| 1759 void SendKeyToPopupAndWait(ui::DomKey key, |
| 1760 content::RenderWidgetHost* widget) { |
| 1761 ui::KeyboardCode key_code = ui::NonPrintableDomKeyToKeyboardCode(key); |
| 1762 ui::DomCode code = ui::UsLayoutKeyboardCodeToDomCode(key_code); |
| 1763 AutofillInteractiveTest::SendKeyToPopupAndWait(key, code, key_code, widget); |
| 1764 } |
| 1765 |
| 1766 private: |
| 1767 void SetUpCommandLine(base::CommandLine* command_line) override { |
| 1768 AutofillInteractiveTest::SetUpCommandLine(command_line); |
| 1769 // Append --site-per-process flag. |
| 1770 content::IsolateAllSitesForTesting(command_line); |
| 1771 } |
| 1772 }; |
| 1773 |
| 1774 IN_PROC_BROWSER_TEST_F(AutofillInteractiveIsolationTest, SimpleCrossSiteFill) { |
| 1775 // Ensure that |embedded_test_server()| serves both domains used below. |
| 1776 host_resolver()->AddRule("*", "127.0.0.1"); |
| 1777 |
| 1778 CreateTestProfile(); |
| 1779 |
| 1780 // Main frame is on a.com, iframe is on b.com. |
| 1781 GURL url = embedded_test_server()->GetURL( |
| 1782 "a.com", "/autofill/cross_origin_iframe.html"); |
| 1783 ui_test_utils::NavigateToURL(browser(), url); |
| 1784 GURL iframe_url = embedded_test_server()->GetURL( |
| 1785 "b.com", "/autofill/autofill_test_form.html"); |
| 1786 EXPECT_TRUE( |
| 1787 content::NavigateIframeToURL(GetWebContents(), "crossFrame", iframe_url)); |
| 1788 |
| 1789 // Let |test_delegate()| also observe autofill events in the iframe. |
| 1790 content::RenderFrameHost* cross_frame = |
| 1791 RenderFrameHostForName(GetWebContents(), "crossFrame"); |
| 1792 ASSERT_TRUE(cross_frame); |
| 1793 ContentAutofillDriver* cross_driver = |
| 1794 ContentAutofillDriverFactory::FromWebContents(GetWebContents()) |
| 1795 ->DriverForFrame(cross_frame); |
| 1796 ASSERT_TRUE(cross_driver); |
| 1797 cross_driver->autofill_manager()->SetTestDelegate(test_delegate()); |
| 1798 |
| 1799 // Focus the form in the iframe and simulate choosing a suggestion via |
| 1800 // keyboard. |
| 1801 std::string script_focus("document.getElementById('NAME_FIRST').focus();"); |
| 1802 ASSERT_TRUE(content::ExecuteScript(cross_frame, script_focus)); |
| 1803 SendKeyToPageAndWait(ui::DomKey::ARROW_DOWN); |
| 1804 content::RenderWidgetHost* widget = |
| 1805 cross_frame->GetView()->GetRenderWidgetHost(); |
| 1806 SendKeyToPopupAndWait(ui::DomKey::ARROW_DOWN, widget); |
| 1807 SendKeyToPopupAndWait(ui::DomKey::ENTER, widget); |
| 1808 |
| 1809 // Check that the suggestion was filled. |
| 1810 std::string value; |
| 1811 ASSERT_TRUE(content::ExecuteScriptAndExtractString( |
| 1812 cross_frame, |
| 1813 "window.domAutomationController.send(" |
| 1814 " document.getElementById('NAME_FIRST').value);", |
| 1815 &value)); |
| 1816 EXPECT_EQ("Milton", value); |
| 1817 } |
| 1818 |
1738 } // namespace autofill | 1819 } // namespace autofill |
OLD | NEW |