OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <stdint.h> | 5 #include <stdint.h> |
6 | 6 |
7 #include "base/macros.h" | 7 #include "base/macros.h" |
8 #include "build/build_config.h" | 8 #include "build/build_config.h" |
9 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" | 9 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" |
10 #include "chrome/browser/extensions/browser_action_test_util.h" | 10 #include "chrome/browser/extensions/browser_action_test_util.h" |
11 #include "chrome/browser/extensions/extension_action.h" | 11 #include "chrome/browser/extensions/extension_action.h" |
12 #include "chrome/browser/extensions/extension_action_icon_factory.h" | 12 #include "chrome/browser/extensions/extension_action_icon_factory.h" |
13 #include "chrome/browser/extensions/extension_action_manager.h" | 13 #include "chrome/browser/extensions/extension_action_manager.h" |
14 #include "chrome/browser/extensions/extension_action_runner.h" | 14 #include "chrome/browser/extensions/extension_action_runner.h" |
15 #include "chrome/browser/extensions/extension_apitest.h" | 15 #include "chrome/browser/extensions/extension_apitest.h" |
16 #include "chrome/browser/extensions/extension_tab_util.h" | 16 #include "chrome/browser/extensions/extension_tab_util.h" |
17 #include "chrome/browser/extensions/extension_util.h" | 17 #include "chrome/browser/extensions/extension_util.h" |
18 #include "chrome/browser/profiles/profile.h" | 18 #include "chrome/browser/profiles/profile.h" |
19 #include "chrome/browser/ui/browser.h" | 19 #include "chrome/browser/ui/browser.h" |
20 #include "chrome/browser/ui/browser_commands.h" | 20 #include "chrome/browser/ui/browser_commands.h" |
21 #include "chrome/browser/ui/browser_finder.h" | 21 #include "chrome/browser/ui/browser_finder.h" |
22 #include "chrome/browser/ui/browser_navigator_params.h" | 22 #include "chrome/browser/ui/browser_navigator_params.h" |
23 #include "chrome/browser/ui/browser_window.h" | 23 #include "chrome/browser/ui/browser_window.h" |
24 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 24 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
25 #include "chrome/common/url_constants.h" | 25 #include "chrome/common/url_constants.h" |
26 #include "chrome/test/base/ui_test_utils.h" | 26 #include "chrome/test/base/ui_test_utils.h" |
27 #include "content/public/browser/browser_context.h" | |
27 #include "content/public/browser/notification_service.h" | 28 #include "content/public/browser/notification_service.h" |
28 #include "content/public/browser/render_frame_host.h" | 29 #include "content/public/browser/render_frame_host.h" |
29 #include "content/public/browser/web_contents.h" | 30 #include "content/public/browser/web_contents.h" |
30 #include "content/public/test/browser_test_utils.h" | 31 #include "content/public/test/browser_test_utils.h" |
32 #include "content/public/test/content_browser_test_utils.h" | |
33 #include "content/public/test/download_test_observer.h" | |
34 #include "content/public/test/test_utils.h" | |
31 #include "extensions/browser/extension_registry.h" | 35 #include "extensions/browser/extension_registry.h" |
32 #include "extensions/browser/extension_system.h" | 36 #include "extensions/browser/extension_system.h" |
33 #include "extensions/browser/notification_types.h" | 37 #include "extensions/browser/notification_types.h" |
34 #include "extensions/browser/process_manager.h" | 38 #include "extensions/browser/process_manager.h" |
35 #include "extensions/browser/test_extension_registry_observer.h" | 39 #include "extensions/browser/test_extension_registry_observer.h" |
36 #include "extensions/common/feature_switch.h" | 40 #include "extensions/common/feature_switch.h" |
37 #include "extensions/test/extension_test_message_listener.h" | 41 #include "extensions/test/extension_test_message_listener.h" |
38 #include "extensions/test/result_catcher.h" | 42 #include "extensions/test/result_catcher.h" |
39 #include "net/dns/mock_host_resolver.h" | 43 #include "net/dns/mock_host_resolver.h" |
40 #include "net/test/embedded_test_server/embedded_test_server.h" | 44 #include "net/test/embedded_test_server/embedded_test_server.h" |
45 #include "testing/gmock/include/gmock/gmock.h" | |
41 #include "ui/base/resource/resource_bundle.h" | 46 #include "ui/base/resource/resource_bundle.h" |
42 #include "ui/gfx/geometry/rect.h" | 47 #include "ui/gfx/geometry/rect.h" |
43 #include "ui/gfx/geometry/size.h" | 48 #include "ui/gfx/geometry/size.h" |
44 #include "ui/gfx/image/canvas_image_source.h" | 49 #include "ui/gfx/image/canvas_image_source.h" |
45 #include "ui/gfx/image/image_skia.h" | 50 #include "ui/gfx/image/image_skia.h" |
46 #include "ui/gfx/image/image_skia_operations.h" | 51 #include "ui/gfx/image/image_skia_operations.h" |
47 #include "ui/gfx/image/image_unittest_util.h" | 52 #include "ui/gfx/image/image_unittest_util.h" |
48 #include "ui/gfx/skia_util.h" | 53 #include "ui/gfx/skia_util.h" |
49 | 54 |
50 using content::WebContents; | 55 using content::WebContents; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
98 BrowserActionApiTest() {} | 103 BrowserActionApiTest() {} |
99 ~BrowserActionApiTest() override {} | 104 ~BrowserActionApiTest() override {} |
100 | 105 |
101 protected: | 106 protected: |
102 BrowserActionTestUtil* GetBrowserActionsBar() { | 107 BrowserActionTestUtil* GetBrowserActionsBar() { |
103 if (!browser_action_test_util_) | 108 if (!browser_action_test_util_) |
104 browser_action_test_util_.reset(new BrowserActionTestUtil(browser())); | 109 browser_action_test_util_.reset(new BrowserActionTestUtil(browser())); |
105 return browser_action_test_util_.get(); | 110 return browser_action_test_util_.get(); |
106 } | 111 } |
107 | 112 |
108 bool OpenPopup(int index) { | 113 WebContents* OpenPopup(int index) { |
109 ResultCatcher catcher; | 114 ResultCatcher catcher; |
110 content::WindowedNotificationObserver popup_observer( | 115 content::WindowedNotificationObserver popup_observer( |
111 content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME, | 116 content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME, |
112 content::NotificationService::AllSources()); | 117 content::NotificationService::AllSources()); |
113 GetBrowserActionsBar()->Press(index); | 118 GetBrowserActionsBar()->Press(index); |
114 popup_observer.Wait(); | 119 popup_observer.Wait(); |
115 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); | 120 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message(); |
116 return GetBrowserActionsBar()->HasPopup(); | 121 |
122 if (!GetBrowserActionsBar()->HasPopup()) | |
123 return nullptr; | |
124 | |
125 const auto& source = static_cast<const content::Source<WebContents>&>( | |
126 popup_observer.source()); | |
127 return source.ptr(); | |
117 } | 128 } |
118 | 129 |
119 ExtensionAction* GetBrowserAction(const Extension& extension) { | 130 ExtensionAction* GetBrowserAction(const Extension& extension) { |
120 return ExtensionActionManager::Get(browser()->profile())-> | 131 return ExtensionActionManager::Get(browser()->profile())-> |
121 GetBrowserAction(extension); | 132 GetBrowserAction(extension); |
122 } | 133 } |
123 | 134 |
124 private: | 135 private: |
125 std::unique_ptr<BrowserActionTestUtil> browser_action_test_util_; | 136 std::unique_ptr<BrowserActionTestUtil> browser_action_test_util_; |
126 | 137 |
(...skipping 660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
787 ExtensionTestMessageListener listener("ready", true); | 798 ExtensionTestMessageListener listener("ready", true); |
788 EXPECT_TRUE(LoadExtension( | 799 EXPECT_TRUE(LoadExtension( |
789 test_data_dir_.AppendASCII("browser_action/open_popup_on_reply"))); | 800 test_data_dir_.AppendASCII("browser_action/open_popup_on_reply"))); |
790 EXPECT_TRUE(listener.WaitUntilSatisfied()); | 801 EXPECT_TRUE(listener.WaitUntilSatisfied()); |
791 | 802 |
792 ResultCatcher catcher; | 803 ResultCatcher catcher; |
793 listener.Reply(std::string()); | 804 listener.Reply(std::string()); |
794 EXPECT_TRUE(catcher.GetNextResult()) << message_; | 805 EXPECT_TRUE(catcher.GetNextResult()) << message_; |
795 } | 806 } |
796 | 807 |
808 class NavigatingExtensionPopupBrowserTest : public BrowserActionApiTest { | |
809 public: | |
810 const Extension& popup_extension() { return *popup_extension_; } | |
811 const Extension& other_extension() { return *other_extension_; } | |
812 | |
813 void SetUpOnMainThread() override { | |
814 BrowserActionApiTest::SetUpOnMainThread(); | |
815 | |
816 host_resolver()->AddRule("*", "127.0.0.1"); | |
817 ASSERT_TRUE(embedded_test_server()->Start()); | |
818 | |
819 // Load an extension with a pop-up. | |
820 ASSERT_TRUE(popup_extension_ = LoadExtension(test_data_dir_.AppendASCII( | |
821 "browser_action/popup_with_form"))); | |
822 | |
823 // Load another extension (that we can try navigating to). | |
824 ASSERT_TRUE(other_extension_ = LoadExtension(test_data_dir_.AppendASCII( | |
825 "browser_action/popup_with_iframe"))); | |
826 } | |
827 | |
828 void VerifyNavigationResult(WebContents* popup, | |
829 GURL old_popup_url, | |
830 GURL target_url, | |
831 bool expecting_navigation_success) { | |
832 if (!popup) { | |
833 // If navigation ends up in a tab, then the tab will be focused and | |
834 // therefore the popup will be closed, destroying associated WebContents - | |
835 // don't do any verification in this case. | |
836 ADD_FAILURE() << "Navigation should not close extension pop-up"; | |
837 } else { | |
838 // If the extension popup is still opened, then wait until there is no | |
839 // load in progress, and verify whether the navigation succeeded or not. | |
840 LOG(INFO) << "Waiting until popup navigation stops..."; | |
Charlie Reis
2016/09/26 17:27:50
Did you mean to leave these LOG(INFO) statements i
Łukasz Anforowicz
2016/09/26 18:30:23
When I was working on the tests, I had them hang (
| |
841 WaitForLoadStop(popup); | |
842 if (expecting_navigation_success) { | |
843 EXPECT_EQ(target_url, popup->GetLastCommittedURL()) | |
844 << "Navigation to " << target_url.spec() | |
845 << " should succeed in an extension pop-up"; | |
846 } else { | |
847 EXPECT_NE(target_url, popup->GetLastCommittedURL()) | |
848 << "Navigation to " << target_url.spec() | |
849 << " should fail in an extension pop-up"; | |
850 EXPECT_THAT( | |
851 popup->GetLastCommittedURL(), | |
852 ::testing::AnyOf(::testing::Eq(old_popup_url), | |
853 ::testing::Eq(GURL("chrome-extension://invalid")), | |
854 ::testing::Eq(GURL("about:blank")))); | |
855 } | |
856 } | |
857 | |
858 // Make sure that the web navigation did not succeed somewhere outside of | |
859 // the extension popup (as it might if ExtensionViewHost::OpenURLFromTab | |
860 // forwards the navigation to Browser::OpenURL [which doesn't specify a | |
861 // source WebContents]). | |
862 LOG(INFO) << "Verifying contents of tabs..."; | |
863 TabStripModel* tabs = browser()->tab_strip_model(); | |
864 for (int i = 0; i < tabs->count(); i++) { | |
865 WebContents* tab_contents = tabs->GetWebContentsAt(i); | |
866 WaitForLoadStop(tab_contents); | |
867 EXPECT_NE(target_url, tab_contents->GetLastCommittedURL()) | |
868 << "Navigating an extension pop-up should not affect tabs."; | |
869 } | |
870 } | |
871 | |
872 void TestPopupNavigationViaGet(GURL target_url, | |
873 bool expecting_navigation_success) { | |
874 // Were there any failures so far (e.g. in SetUpOnMainThread)? | |
875 ASSERT_FALSE(HasFailure()); | |
876 | |
877 // Simulate a click on the browser action to open the popup. | |
878 LOG(INFO) << "Opening an extension popup"; | |
879 WebContents* popup = OpenPopup(0); | |
880 ASSERT_TRUE(popup); | |
881 GURL popup_url = popup_extension().GetResourceURL("popup.html"); | |
882 EXPECT_EQ(popup_url, popup->GetLastCommittedURL()); | |
883 | |
884 // Note that the |setTimeout| call below is needed to make sure | |
885 // ExecuteScriptAndExtractBool returns *after* a scheduled navigation has | |
886 // already started. | |
887 std::string navigation_starting_script = | |
888 "window.location = '" + target_url.spec() + "';" | |
889 "setTimeout(" | |
890 " function(){ window.domAutomationController.send(true); }," | |
891 " 0);"; | |
892 | |
893 // Try to navigate the pop-up. | |
894 bool ignored; | |
895 content::WebContentsDestroyedWatcher popup_destruction_watcher(popup); | |
896 LOG(INFO) << "Navigating the popup to " << target_url; | |
897 EXPECT_TRUE(ExecuteScriptAndExtractBool(popup, navigation_starting_script, | |
898 &ignored)); | |
899 | |
900 // Verify whether navigation succeeded or failed. | |
901 VerifyNavigationResult(popup_destruction_watcher.web_contents(), popup_url, | |
902 target_url, expecting_navigation_success); | |
903 | |
904 // Close the pop-up. | |
905 BrowserActionTestUtil* actions_bar = GetBrowserActionsBar(); | |
906 EXPECT_TRUE(actions_bar->HidePopup()); | |
907 } | |
908 | |
909 void TestPopupNavigationViaPost(GURL target_url, | |
910 bool expecting_navigation_success) { | |
911 // Were there any failures so far (e.g. in SetUpOnMainThread)? | |
912 ASSERT_FALSE(HasFailure()); | |
913 | |
914 // Simulate a click on the browser action to open the popup. | |
915 LOG(INFO) << "Opening an extension popup..."; | |
916 WebContents* popup = OpenPopup(0); | |
917 ASSERT_TRUE(popup); | |
918 GURL popup_url = popup_extension().GetResourceURL("popup.html"); | |
919 EXPECT_EQ(popup_url, popup->GetLastCommittedURL()); | |
920 | |
921 // Note that the |setTimeout| call below is needed to make sure | |
922 // ExecuteScriptAndExtractBool returns *after* a scheduled navigation has | |
923 // already started. | |
924 std::string navigation_starting_script = | |
925 "var form = document.getElementById('form');" | |
926 "form.action = '" + target_url.spec() + "';" | |
927 "form.submit();" | |
Charlie Reis
2016/09/26 17:27:50
This function looks the same as TestPopupNavigatio
Łukasz Anforowicz
2016/09/26 18:30:23
Done.
| |
928 "setTimeout(" | |
929 " function(){ window.domAutomationController.send(true); }," | |
930 " 0);"; | |
931 | |
932 // Try to navigate the pop-up. | |
933 bool ignored; | |
934 content::WebContentsDestroyedWatcher popup_destruction_watcher(popup); | |
935 LOG(INFO) << "Navigating the popup to " << target_url; | |
936 EXPECT_TRUE(ExecuteScriptAndExtractBool(popup, navigation_starting_script, | |
937 &ignored)); | |
938 | |
939 // Verify whether navigation succeeded or failed. | |
940 VerifyNavigationResult(popup_destruction_watcher.web_contents(), popup_url, | |
941 target_url, expecting_navigation_success); | |
942 | |
943 // Close the pop-up. | |
944 BrowserActionTestUtil* actions_bar = GetBrowserActionsBar(); | |
945 EXPECT_TRUE(actions_bar->HidePopup()); | |
946 } | |
947 | |
948 private: | |
949 const Extension* popup_extension_; | |
950 const Extension* other_extension_; | |
951 }; | |
952 | |
953 // Test verifies if an extension pop-up can be navigated to a web page. | |
954 IN_PROC_BROWSER_TEST_F(NavigatingExtensionPopupBrowserTest, WebpageViaGet) { | |
955 GURL web_url(embedded_test_server()->GetURL("foo.com", "/title1.html")); | |
956 TestPopupNavigationViaGet(web_url, | |
957 false /* == expecting_navigation_success */); | |
Charlie Reis
2016/09/26 17:27:50
nit: No need for the ==
Łukasz Anforowicz
2016/09/26 18:30:23
Done.
| |
958 } | |
959 | |
960 // Test verifies if an extension pop-up can be navigated to a web page. | |
961 IN_PROC_BROWSER_TEST_F(NavigatingExtensionPopupBrowserTest, WebpageViaPost) { | |
962 GURL web_url(embedded_test_server()->GetURL("foo.com", "/title1.html")); | |
963 TestPopupNavigationViaPost(web_url, | |
964 false /* == expecting_navigation_success */); | |
965 } | |
966 | |
967 // Test verifies if an extension pop-up can be navigated to another page | |
968 // in the same extension. | |
969 IN_PROC_BROWSER_TEST_F(NavigatingExtensionPopupBrowserTest, | |
970 PageInSameExtensionViaGet) { | |
971 GURL other_page_in_same_extension = | |
972 popup_extension().GetResourceURL("other_page.html"); | |
973 TestPopupNavigationViaGet(other_page_in_same_extension, | |
974 true /* == expecting_navigation_success */); | |
975 } | |
976 | |
977 // Test verifies if an extension pop-up can be navigated to another page | |
978 // in the same extension. | |
979 IN_PROC_BROWSER_TEST_F(NavigatingExtensionPopupBrowserTest, | |
980 PageInSameExtensionViaPost) { | |
981 GURL other_page_in_same_extension = | |
982 popup_extension().GetResourceURL("other_page.html"); | |
983 TestPopupNavigationViaPost(other_page_in_same_extension, | |
984 true /* == expecting_navigation_success */); | |
985 } | |
986 | |
987 // Test verifies if an extension pop-up can be navigated to a page | |
988 // in another extension. | |
989 IN_PROC_BROWSER_TEST_F(NavigatingExtensionPopupBrowserTest, | |
990 PageInOtherExtensionViaGet) { | |
991 GURL other_extension_url = other_extension().GetResourceURL("other.html"); | |
992 TestPopupNavigationViaGet(other_extension_url, | |
993 false /* == expecting_navigation_success */); | |
994 } | |
995 | |
996 // Test verifies if an extension pop-up can be navigated to a page | |
997 // in another extension. | |
998 IN_PROC_BROWSER_TEST_F(NavigatingExtensionPopupBrowserTest, | |
999 PageInOtherExtensionViaPost) { | |
1000 GURL other_extension_url = other_extension().GetResourceURL("other.html"); | |
1001 TestPopupNavigationViaPost(other_extension_url, | |
1002 false /* == expecting_navigation_success */); | |
1003 } | |
1004 | |
1005 // Test verifies if navigating an extension pop-up to a http URI that returns | |
1006 // Content-Disposition: attachment; filename=... | |
1007 // works: No navigation, but download shelf visible + download goes through. | |
1008 // | |
1009 // Note - there is no "...ViaGet" flavour of this test, because we don't care | |
1010 // (yet) if GET succeeds with the download or not (it probably should succeed | |
1011 // for consistency with POST, but it always failed in M54 and before). After | |
1012 // abandoing ShouldFork/OpenURL for all methods (not just for POST) [see comment | |
1013 // about https://crbug.com/646261 in ChromeContentRendererClient::ShouldFork] | |
1014 // GET should automagically start working for downloads. | |
1015 IN_PROC_BROWSER_TEST_F(NavigatingExtensionPopupBrowserTest, DownloadViaPost) { | |
1016 content::DownloadTestObserverTerminal downloads_observer( | |
1017 content::BrowserContext::GetDownloadManager(browser()->profile()), | |
1018 1, // == wait_count (only waiting for "download-test3.gif"). | |
1019 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL); | |
1020 | |
1021 // Navigate to a URL that replies with | |
1022 // Content-Disposition: attachment; filename=... | |
1023 // header. | |
1024 GURL download_url( | |
1025 embedded_test_server()->GetURL("foo.com", "/download-test3.gif")); | |
1026 TestPopupNavigationViaPost(download_url, | |
1027 false /* == expecting_navigation_success */); | |
1028 | |
1029 // Verify that "download-test3.gif got downloaded. | |
1030 LOG(INFO) << "Waiting for downloads to finish..."; | |
1031 downloads_observer.WaitForFinished(); | |
1032 EXPECT_EQ(0u, downloads_observer.NumDangerousDownloadsSeen()); | |
1033 EXPECT_EQ(1u, downloads_observer.NumDownloadsSeenInState( | |
1034 content::DownloadItem::COMPLETE)); | |
1035 #if !defined(OS_CHROMEOS) | |
Charlie Reis
2016/09/26 17:27:50
nit: Add a comment explaining why this is skipped
Łukasz Anforowicz
2016/09/26 18:30:23
Done.
I've also felt that maybe !defined(OS_CHROM
Charlie Reis
2016/09/26 19:00:48
Cool, I like it.
Łukasz Anforowicz
2016/09/26 22:05:10
Actually, this didn't work... I've built CrOS bro
| |
1036 EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible()); | |
1037 #endif | |
1038 } | |
1039 | |
797 } // namespace | 1040 } // namespace |
798 } // namespace extensions | 1041 } // namespace extensions |
OLD | NEW |