| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "base/files/file_path.h" | 5 #include "base/files/file_path.h" |
| 6 #include "base/files/file_util.h" | 6 #include "base/files/file_util.h" |
| 7 #include "base/memory/ptr_util.h" | 7 #include "base/memory/ptr_util.h" |
| 8 #include "base/path_service.h" | 8 #include "base/path_service.h" |
| 9 #include "base/threading/thread_restrictions.h" | 9 #include "base/threading/thread_restrictions.h" |
| 10 #include "base/values.h" | 10 #include "base/values.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 | 27 |
| 28 namespace OnMessage = api::test::OnMessage; | 28 namespace OnMessage = api::test::OnMessage; |
| 29 | 29 |
| 30 namespace { | 30 namespace { |
| 31 | 31 |
| 32 // Tests running extension APIs on WebUI. | 32 // Tests running extension APIs on WebUI. |
| 33 class ExtensionWebUITest : public ExtensionApiTest { | 33 class ExtensionWebUITest : public ExtensionApiTest { |
| 34 protected: | 34 protected: |
| 35 testing::AssertionResult RunTest(const char* name, | 35 testing::AssertionResult RunTest(const char* name, |
| 36 const GURL& page_url, | 36 const GURL& page_url, |
| 37 const GURL& frame_url, | |
| 38 bool expected_result) { | 37 bool expected_result) { |
| 39 std::string script; | 38 std::string script; |
| 40 { | 39 { |
| 41 base::ThreadRestrictions::ScopedAllowIO allow_io; | 40 base::ThreadRestrictions::ScopedAllowIO allow_io; |
| 42 // Tests are located in chrome/test/data/extensions/webui/$(name). | 41 // Tests are located in chrome/test/data/extensions/webui/$(name). |
| 43 base::FilePath path; | 42 base::FilePath path; |
| 44 PathService::Get(chrome::DIR_TEST_DATA, &path); | 43 PathService::Get(chrome::DIR_TEST_DATA, &path); |
| 45 path = | 44 path = |
| 46 path.AppendASCII("extensions").AppendASCII("webui").AppendASCII(name); | 45 path.AppendASCII("extensions").AppendASCII("webui").AppendASCII(name); |
| 47 | 46 |
| 48 // Read the test. | 47 // Read the test. |
| 49 if (!base::PathExists(path)) | 48 if (!base::PathExists(path)) |
| 50 return testing::AssertionFailure() << "Couldn't find " << path.value(); | 49 return testing::AssertionFailure() << "Couldn't find " << path.value(); |
| 51 base::ReadFileToString(path, &script); | 50 base::ReadFileToString(path, &script); |
| 52 script = "(function(){'use strict';" + script + "}());"; | 51 script = "(function(){'use strict';" + script + "}());"; |
| 53 } | 52 } |
| 54 | 53 |
| 55 // Run the test. | 54 // Run the test. |
| 56 bool actual_result = false; | 55 bool actual_result = false; |
| 57 content::RenderFrameHost* webui = NavigateToWebUI(page_url, frame_url); | 56 ui_test_utils::NavigateToURL(browser(), page_url); |
| 57 content::RenderFrameHost* webui = |
| 58 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(); |
| 58 if (!webui) | 59 if (!webui) |
| 59 return testing::AssertionFailure() << "Failed to navigate to WebUI"; | 60 return testing::AssertionFailure() << "Failed to navigate to WebUI"; |
| 60 CHECK(content::ExecuteScriptAndExtractBool(webui, script, &actual_result)); | 61 CHECK(content::ExecuteScriptAndExtractBool(webui, script, &actual_result)); |
| 61 return (expected_result == actual_result) | 62 return (expected_result == actual_result) |
| 62 ? testing::AssertionSuccess() | 63 ? testing::AssertionSuccess() |
| 63 : (testing::AssertionFailure() << "Check console output"); | 64 : (testing::AssertionFailure() << "Check console output"); |
| 64 } | 65 } |
| 65 | 66 |
| 66 testing::AssertionResult RunTestOnExtensionsFrame(const char* name) { | 67 testing::AssertionResult RunTestOnExtensionsPage(const char* name) { |
| 67 // In the current extension WebUI design, the content is actually hosted in | 68 return RunTest(name, GURL("chrome://extensions"), true); |
| 68 // an iframe at chrome://extensions-frame. | |
| 69 return RunTest(name, | |
| 70 GURL("chrome://extensions"), | |
| 71 GURL("chrome://extensions-frame"), | |
| 72 true); // tests on chrome://extensions-frame should succeed | |
| 73 } | 69 } |
| 74 | 70 |
| 75 testing::AssertionResult RunTestOnChromeExtensionsFrame(const char* name) { | 71 testing::AssertionResult RunTestOnAboutPage(const char* name) { |
| 76 // Like RunTestOnExtensionsFrame, but chrome://extensions is an alias for | |
| 77 // chrome://chrome/extensions so test it explicitly. | |
| 78 return RunTest(name, | |
| 79 GURL("chrome://chrome/extensions"), | |
| 80 GURL("chrome://extensions-frame"), | |
| 81 true); // tests on chrome://extensions-frame should succeed | |
| 82 } | |
| 83 | |
| 84 testing::AssertionResult RunTestOnChromeExtensions(const char* name) { | |
| 85 // Despite the extensions page being hosted in an iframe, also test the | |
| 86 // top-level chrome://extensions page (which actually loads | |
| 87 // chrome://chrome/extensions). In the past there was a bug where top-level | |
| 88 // extension WebUI bindings weren't correctly set up. | |
| 89 return RunTest(name, | |
| 90 GURL("chrome://chrome/extensions"), | |
| 91 GURL("chrome://chrome/extensions"), | |
| 92 true); // tests on chrome://chrome/extensions should succeed | |
| 93 } | |
| 94 | |
| 95 testing::AssertionResult RunTestOnAbout(const char* name) { | |
| 96 // chrome://about is an innocuous page that doesn't have any bindings. | 72 // chrome://about is an innocuous page that doesn't have any bindings. |
| 97 // Tests should fail. | 73 // Tests should fail. |
| 98 return RunTest(name, | 74 return RunTest(name, GURL("chrome://about"), false); |
| 99 GURL("chrome://about"), | |
| 100 GURL("chrome://about"), | |
| 101 false); // tests on chrome://about should fail | |
| 102 } | |
| 103 | |
| 104 private: | |
| 105 // Navigates the browser to a WebUI page and returns the RenderFrameHost for | |
| 106 // that page. | |
| 107 content::RenderFrameHost* NavigateToWebUI(const GURL& page_url, | |
| 108 const GURL& frame_url) { | |
| 109 ui_test_utils::NavigateToURL(browser(), page_url); | |
| 110 | |
| 111 content::WebContents* active_web_contents = | |
| 112 browser()->tab_strip_model()->GetActiveWebContents(); | |
| 113 | |
| 114 if (active_web_contents->GetLastCommittedURL() == frame_url) | |
| 115 return active_web_contents->GetMainFrame(); | |
| 116 | |
| 117 return FrameMatchingPredicate( | |
| 118 active_web_contents, | |
| 119 base::Bind(&content::FrameHasSourceUrl, frame_url)); | |
| 120 } | 75 } |
| 121 }; | 76 }; |
| 122 | 77 |
| 123 #if !defined(OS_WIN) // flaky http://crbug.com/530722 | 78 #if !defined(OS_WIN) // flaky http://crbug.com/530722 |
| 124 | 79 |
| 125 IN_PROC_BROWSER_TEST_F(ExtensionWebUITest, SanityCheckAvailableAPIsInFrame) { | 80 IN_PROC_BROWSER_TEST_F(ExtensionWebUITest, SanityCheckAvailableAPIs) { |
| 126 ASSERT_TRUE(RunTestOnExtensionsFrame("sanity_check_available_apis.js")); | 81 ASSERT_TRUE(RunTestOnExtensionsPage("sanity_check_available_apis.js")); |
| 127 } | |
| 128 | |
| 129 IN_PROC_BROWSER_TEST_F(ExtensionWebUITest, | |
| 130 SanityCheckAvailableAPIsInChromeFrame) { | |
| 131 ASSERT_TRUE(RunTestOnChromeExtensionsFrame("sanity_check_available_apis.js")); | |
| 132 } | |
| 133 | |
| 134 IN_PROC_BROWSER_TEST_F(ExtensionWebUITest, SanityCheckAvailableAPIsInToplevel) { | |
| 135 ASSERT_TRUE(RunTestOnChromeExtensions("sanity_check_available_apis.js")); | |
| 136 } | 82 } |
| 137 | 83 |
| 138 IN_PROC_BROWSER_TEST_F(ExtensionWebUITest, SanityCheckUnavailableAPIs) { | 84 IN_PROC_BROWSER_TEST_F(ExtensionWebUITest, SanityCheckUnavailableAPIs) { |
| 139 ASSERT_TRUE(RunTestOnAbout("sanity_check_available_apis.js")); | 85 ASSERT_TRUE(RunTestOnAboutPage("sanity_check_available_apis.js")); |
| 140 } | 86 } |
| 141 | 87 |
| 142 // Tests chrome.test.sendMessage, which exercises WebUI making a | 88 // Tests chrome.test.sendMessage, which exercises WebUI making a |
| 143 // function call and receiving a response. | 89 // function call and receiving a response. |
| 144 IN_PROC_BROWSER_TEST_F(ExtensionWebUITest, SendMessage) { | 90 IN_PROC_BROWSER_TEST_F(ExtensionWebUITest, SendMessage) { |
| 145 std::unique_ptr<ExtensionTestMessageListener> listener( | 91 std::unique_ptr<ExtensionTestMessageListener> listener( |
| 146 new ExtensionTestMessageListener("ping", true)); | 92 new ExtensionTestMessageListener("ping", true)); |
| 147 | 93 |
| 148 ASSERT_TRUE(RunTestOnExtensionsFrame("send_message.js")); | 94 ASSERT_TRUE(RunTestOnExtensionsPage("send_message.js")); |
| 149 | 95 |
| 150 ASSERT_TRUE(listener->WaitUntilSatisfied()); | 96 ASSERT_TRUE(listener->WaitUntilSatisfied()); |
| 151 listener->Reply("pong"); | 97 listener->Reply("pong"); |
| 152 | 98 |
| 153 listener.reset(new ExtensionTestMessageListener(false)); | 99 listener.reset(new ExtensionTestMessageListener(false)); |
| 154 ASSERT_TRUE(listener->WaitUntilSatisfied()); | 100 ASSERT_TRUE(listener->WaitUntilSatisfied()); |
| 155 EXPECT_EQ("true", listener->message()); | 101 EXPECT_EQ("true", listener->message()); |
| 156 } | 102 } |
| 157 | 103 |
| 158 // Tests chrome.runtime.onMessage, which exercises WebUI registering and | 104 // Tests chrome.runtime.onMessage, which exercises WebUI registering and |
| 159 // receiving an event. | 105 // receiving an event. |
| 160 IN_PROC_BROWSER_TEST_F(ExtensionWebUITest, OnMessage) { | 106 IN_PROC_BROWSER_TEST_F(ExtensionWebUITest, OnMessage) { |
| 161 ASSERT_TRUE(RunTestOnExtensionsFrame("on_message.js")); | 107 ASSERT_TRUE(RunTestOnExtensionsPage("on_message.js")); |
| 162 | 108 |
| 163 OnMessage::Info info; | 109 OnMessage::Info info; |
| 164 info.data = "hi"; | 110 info.data = "hi"; |
| 165 info.last_message = true; | 111 info.last_message = true; |
| 166 EventRouter::Get(profile())->BroadcastEvent(base::WrapUnique( | 112 EventRouter::Get(profile())->BroadcastEvent(base::WrapUnique( |
| 167 new Event(events::RUNTIME_ON_MESSAGE, OnMessage::kEventName, | 113 new Event(events::RUNTIME_ON_MESSAGE, OnMessage::kEventName, |
| 168 OnMessage::Create(info)))); | 114 OnMessage::Create(info)))); |
| 169 | 115 |
| 170 std::unique_ptr<ExtensionTestMessageListener> listener( | 116 std::unique_ptr<ExtensionTestMessageListener> listener( |
| 171 new ExtensionTestMessageListener(false)); | 117 new ExtensionTestMessageListener(false)); |
| 172 ASSERT_TRUE(listener->WaitUntilSatisfied()); | 118 ASSERT_TRUE(listener->WaitUntilSatisfied()); |
| 173 EXPECT_EQ("true", listener->message()); | 119 EXPECT_EQ("true", listener->message()); |
| 174 } | 120 } |
| 175 | 121 |
| 176 // Tests chrome.runtime.lastError, which exercises WebUI accessing a property | 122 // Tests chrome.runtime.lastError, which exercises WebUI accessing a property |
| 177 // on an API which it doesn't actually have access to. A bindings test really. | 123 // on an API which it doesn't actually have access to. A bindings test really. |
| 178 IN_PROC_BROWSER_TEST_F(ExtensionWebUITest, RuntimeLastError) { | 124 IN_PROC_BROWSER_TEST_F(ExtensionWebUITest, RuntimeLastError) { |
| 179 std::unique_ptr<ExtensionTestMessageListener> listener( | 125 std::unique_ptr<ExtensionTestMessageListener> listener( |
| 180 new ExtensionTestMessageListener("ping", true)); | 126 new ExtensionTestMessageListener("ping", true)); |
| 181 | 127 |
| 182 ASSERT_TRUE(RunTestOnExtensionsFrame("runtime_last_error.js")); | 128 ASSERT_TRUE(RunTestOnExtensionsPage("runtime_last_error.js")); |
| 183 | 129 |
| 184 ASSERT_TRUE(listener->WaitUntilSatisfied()); | 130 ASSERT_TRUE(listener->WaitUntilSatisfied()); |
| 185 listener->ReplyWithError("unknown host"); | 131 listener->ReplyWithError("unknown host"); |
| 186 | 132 |
| 187 listener.reset(new ExtensionTestMessageListener(false)); | 133 listener.reset(new ExtensionTestMessageListener(false)); |
| 188 ASSERT_TRUE(listener->WaitUntilSatisfied()); | 134 ASSERT_TRUE(listener->WaitUntilSatisfied()); |
| 189 EXPECT_EQ("true", listener->message()); | 135 EXPECT_EQ("true", listener->message()); |
| 190 } | 136 } |
| 191 | 137 |
| 192 IN_PROC_BROWSER_TEST_F(ExtensionWebUITest, CanEmbedExtensionOptions) { | 138 IN_PROC_BROWSER_TEST_F(ExtensionWebUITest, CanEmbedExtensionOptions) { |
| 193 std::unique_ptr<ExtensionTestMessageListener> listener( | 139 std::unique_ptr<ExtensionTestMessageListener> listener( |
| 194 new ExtensionTestMessageListener("ready", true)); | 140 new ExtensionTestMessageListener("ready", true)); |
| 195 | 141 |
| 196 const Extension* extension = | 142 const Extension* extension = |
| 197 LoadExtension(test_data_dir_.AppendASCII("extension_options") | 143 LoadExtension(test_data_dir_.AppendASCII("extension_options") |
| 198 .AppendASCII("embed_self")); | 144 .AppendASCII("embed_self")); |
| 199 ASSERT_TRUE(extension); | 145 ASSERT_TRUE(extension); |
| 200 | 146 |
| 201 ASSERT_TRUE(RunTestOnExtensionsFrame("can_embed_extension_options.js")); | 147 ASSERT_TRUE(RunTestOnExtensionsPage("can_embed_extension_options.js")); |
| 202 | 148 |
| 203 ASSERT_TRUE(listener->WaitUntilSatisfied()); | 149 ASSERT_TRUE(listener->WaitUntilSatisfied()); |
| 204 listener->Reply(extension->id()); | 150 listener->Reply(extension->id()); |
| 205 listener.reset(new ExtensionTestMessageListener("load", false)); | 151 listener.reset(new ExtensionTestMessageListener("load", false)); |
| 206 ASSERT_TRUE(listener->WaitUntilSatisfied()); | 152 ASSERT_TRUE(listener->WaitUntilSatisfied()); |
| 207 } | 153 } |
| 208 | 154 |
| 209 IN_PROC_BROWSER_TEST_F(ExtensionWebUITest, ReceivesExtensionOptionsOnClose) { | 155 IN_PROC_BROWSER_TEST_F(ExtensionWebUITest, ReceivesExtensionOptionsOnClose) { |
| 210 std::unique_ptr<ExtensionTestMessageListener> listener( | 156 std::unique_ptr<ExtensionTestMessageListener> listener( |
| 211 new ExtensionTestMessageListener("ready", true)); | 157 new ExtensionTestMessageListener("ready", true)); |
| 212 | 158 |
| 213 const Extension* extension = | 159 const Extension* extension = |
| 214 InstallExtension(test_data_dir_.AppendASCII("extension_options") | 160 InstallExtension(test_data_dir_.AppendASCII("extension_options") |
| 215 .AppendASCII("close_self"), 1); | 161 .AppendASCII("close_self"), 1); |
| 216 ASSERT_TRUE(extension); | 162 ASSERT_TRUE(extension); |
| 217 | 163 |
| 218 ASSERT_TRUE( | 164 ASSERT_TRUE( |
| 219 RunTestOnExtensionsFrame("receives_extension_options_on_close.js")); | 165 RunTestOnExtensionsPage("receives_extension_options_on_close.js")); |
| 220 | 166 |
| 221 ASSERT_TRUE(listener->WaitUntilSatisfied()); | 167 ASSERT_TRUE(listener->WaitUntilSatisfied()); |
| 222 listener->Reply(extension->id()); | 168 listener->Reply(extension->id()); |
| 223 listener.reset(new ExtensionTestMessageListener("onclose received", false)); | 169 listener.reset(new ExtensionTestMessageListener("onclose received", false)); |
| 224 ASSERT_TRUE(listener->WaitUntilSatisfied()); | 170 ASSERT_TRUE(listener->WaitUntilSatisfied()); |
| 225 } | 171 } |
| 226 | 172 |
| 227 // Regression test for crbug.com/414526. | 173 // Regression test for crbug.com/414526. |
| 228 // | 174 // |
| 229 // Same setup as CanEmbedExtensionOptions but disable the extension before | 175 // Same setup as CanEmbedExtensionOptions but disable the extension before |
| 230 // embedding. | 176 // embedding. |
| 231 IN_PROC_BROWSER_TEST_F(ExtensionWebUITest, EmbedDisabledExtension) { | 177 IN_PROC_BROWSER_TEST_F(ExtensionWebUITest, EmbedDisabledExtension) { |
| 232 std::unique_ptr<ExtensionTestMessageListener> listener( | 178 std::unique_ptr<ExtensionTestMessageListener> listener( |
| 233 new ExtensionTestMessageListener("ready", true)); | 179 new ExtensionTestMessageListener("ready", true)); |
| 234 | 180 |
| 235 std::string extension_id; | 181 std::string extension_id; |
| 236 { | 182 { |
| 237 const Extension* extension = | 183 const Extension* extension = |
| 238 LoadExtension(test_data_dir_.AppendASCII("extension_options") | 184 LoadExtension(test_data_dir_.AppendASCII("extension_options") |
| 239 .AppendASCII("embed_self")); | 185 .AppendASCII("embed_self")); |
| 240 ASSERT_TRUE(extension); | 186 ASSERT_TRUE(extension); |
| 241 extension_id = extension->id(); | 187 extension_id = extension->id(); |
| 242 DisableExtension(extension_id); | 188 DisableExtension(extension_id); |
| 243 } | 189 } |
| 244 | 190 |
| 245 ASSERT_TRUE(RunTestOnExtensionsFrame("can_embed_extension_options.js")); | 191 ASSERT_TRUE(RunTestOnExtensionsPage("can_embed_extension_options.js")); |
| 246 | 192 |
| 247 ASSERT_TRUE(listener->WaitUntilSatisfied()); | 193 ASSERT_TRUE(listener->WaitUntilSatisfied()); |
| 248 listener->Reply(extension_id); | 194 listener->Reply(extension_id); |
| 249 listener.reset(new ExtensionTestMessageListener("createfailed", false)); | 195 listener.reset(new ExtensionTestMessageListener("createfailed", false)); |
| 250 ASSERT_TRUE(listener->WaitUntilSatisfied()); | 196 ASSERT_TRUE(listener->WaitUntilSatisfied()); |
| 251 } | 197 } |
| 252 | 198 |
| 253 #endif | 199 #endif |
| 254 | 200 |
| 255 } // namespace | 201 } // namespace |
| 256 | 202 |
| 257 } // namespace extensions | 203 } // namespace extensions |
| OLD | NEW |