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
3 // found in the LICENSE file.
5 #include "base/strings/stringprintf.h"
6 #include "base/strings/utf_string_conversions.h"
7 #include "chrome/browser/extensions/api/permissions/permissions_api.h"
8 #include "chrome/browser/extensions/extension_apitest.h"
9 #include "chrome/browser/extensions/extension_service.h"
10 #include "chrome/browser/ui/browser.h"
11 #include "chrome/browser/ui/tabs/tab_strip_model.h"
12 #include "chrome/common/chrome_switches.h"
13 #include "chrome/test/base/ui_test_utils.h"
14 #include "content/public/browser/web_contents.h"
15 #include "content/public/test/browser_test_utils.h"
16 #include "extensions/browser/notification_types.h"
17 #include "extensions/common/extension.h"
18 #include "extensions/test/result_catcher.h"
19 #include "net/dns/mock_host_resolver.h"
20 #include "net/test/embedded_test_server/embedded_test_server.h"
23 namespace extensions {
27 // A fake webstore domain.
28 const char kWebstoreDomain[] = "cws.com";
30 // Check whether or not style was injected, with |expected_injection| indicating
31 // the expected result. Also ensure that no CSS was added to the
32 // document.styleSheets array.
33 testing::AssertionResult CheckStyleInjection(Browser* browser,
35 bool expected_injection) {
36 ui_test_utils::NavigateToURL(browser, url);
38 bool css_injected = false;
39 if (!content::ExecuteScriptAndExtractBool(
40 browser->tab_strip_model()->GetActiveWebContents(),
41 "window.domAutomationController.send("
42 " document.defaultView.getComputedStyle(document.body, null)."
43 " getPropertyValue('display') == 'none');",
45 return testing::AssertionFailure()
46 << "Failed to execute script and extract bool for injection status.";
49 if (css_injected != expected_injection) {
52 message = "CSS injected when no injection was expected.";
54 message = "CSS not injected when injection was expected.";
55 return testing::AssertionFailure() << message;
58 bool css_doesnt_add_to_list = false;
59 if (!content::ExecuteScriptAndExtractBool(
60 browser->tab_strip_model()->GetActiveWebContents(),
61 "window.domAutomationController.send("
62 " document.styleSheets.length == 0);",
63 &css_doesnt_add_to_list)) {
64 return testing::AssertionFailure()
65 << "Failed to execute script and extract bool for stylesheets length.";
67 if (!css_doesnt_add_to_list) {
68 return testing::AssertionFailure()
69 << "CSS injection added to number of stylesheets.";
72 return testing::AssertionSuccess();
77 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ContentScriptAllFrames) {
78 ASSERT_TRUE(StartEmbeddedTestServer());
79 ASSERT_TRUE(RunExtensionTest("content_scripts/all_frames")) << message_;
82 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ContentScriptAboutBlankIframes) {
83 ASSERT_TRUE(StartEmbeddedTestServer());
85 RunExtensionTest("content_scripts/about_blank_iframes")) << message_;
88 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ContentScriptAboutBlankAndSrcdoc) {
89 // The optional "*://*/*" permission is requested after verifying that
90 // content script insertion solely depends on content_scripts[*].matches.
91 // The permission is needed for chrome.tabs.executeScript tests.
92 PermissionsRequestFunction::SetAutoConfirmForTests(true);
93 PermissionsRequestFunction::SetIgnoreUserGestureForTests(true);
95 ASSERT_TRUE(StartEmbeddedTestServer());
96 ASSERT_TRUE(RunExtensionTest("content_scripts/about_blank_srcdoc"))
100 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ContentScriptExtensionIframe) {
101 ASSERT_TRUE(StartEmbeddedTestServer());
102 ASSERT_TRUE(RunExtensionTest("content_scripts/extension_iframe")) << message_;
105 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ContentScriptExtensionProcess) {
106 ASSERT_TRUE(StartEmbeddedTestServer());
108 RunExtensionTest("content_scripts/extension_process")) << message_;
111 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ContentScriptFragmentNavigation) {
112 ASSERT_TRUE(StartEmbeddedTestServer());
113 const char extension_name[] = "content_scripts/fragment";
114 ASSERT_TRUE(RunExtensionTest(extension_name)) << message_;
117 // Times out on Linux: http://crbug.com/163097
118 #if defined(OS_LINUX)
119 #define MAYBE_ContentScriptIsolatedWorlds DISABLED_ContentScriptIsolatedWorlds
121 #define MAYBE_ContentScriptIsolatedWorlds ContentScriptIsolatedWorlds
123 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_ContentScriptIsolatedWorlds) {
124 // This extension runs various bits of script and tests that they all run in
125 // the same isolated world.
126 ASSERT_TRUE(StartEmbeddedTestServer());
127 ASSERT_TRUE(RunExtensionTest("content_scripts/isolated_world1")) << message_;
129 // Now load a different extension, inject into same page, verify worlds aren't
131 ASSERT_TRUE(RunExtensionTest("content_scripts/isolated_world2")) << message_;
134 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ContentScriptIgnoreHostPermissions) {
135 host_resolver()->AddRule("a.com", "127.0.0.1");
136 host_resolver()->AddRule("b.com", "127.0.0.1");
137 ASSERT_TRUE(StartEmbeddedTestServer());
138 ASSERT_TRUE(RunExtensionTest(
139 "content_scripts/dont_match_host_permissions")) << message_;
142 // crbug.com/39249 -- content scripts js should not run on view source.
143 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ContentScriptViewSource) {
144 ASSERT_TRUE(StartEmbeddedTestServer());
145 ASSERT_TRUE(RunExtensionTest("content_scripts/view_source")) << message_;
148 // crbug.com/126257 -- content scripts should not get injected into other
150 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ContentScriptOtherExtensions) {
151 host_resolver()->AddRule("a.com", "127.0.0.1");
152 ASSERT_TRUE(StartEmbeddedTestServer());
153 // First, load extension that sets up content script.
154 ASSERT_TRUE(RunExtensionTest("content_scripts/other_extensions/injector"))
156 // Then load targeted extension to make sure its content isn't changed.
157 ASSERT_TRUE(RunExtensionTest("content_scripts/other_extensions/victim"))
161 class ContentScriptCssInjectionTest : public ExtensionApiTest {
163 // TODO(rdevlin.cronin): Make a testing switch that looks like FeatureSwitch,
164 // but takes in an optional value so that we don't have to do this.
165 void SetUpCommandLine(base::CommandLine* command_line) override {
166 ExtensionApiTest::SetUpCommandLine(command_line);
167 // We change the Webstore URL to be http://cws.com. We need to do this so
168 // we can check that css injection is not allowed on the webstore (which
169 // could lead to spoofing). Unfortunately, host_resolver seems to have
170 // problems with redirecting "chrome.google.com" to the test server, so we
171 // can't use the real Webstore's URL. If this changes, we could clean this
173 command_line->AppendSwitchASCII(
174 switches::kAppsGalleryURL,
175 base::StringPrintf("http://%s", kWebstoreDomain));
179 IN_PROC_BROWSER_TEST_F(ContentScriptCssInjectionTest,
180 ContentScriptInjectsStyles) {
181 ASSERT_TRUE(StartEmbeddedTestServer());
182 host_resolver()->AddRule(kWebstoreDomain, "127.0.0.1");
184 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("content_scripts")
185 .AppendASCII("css_injection")));
187 // CSS injection should be allowed on an aribitrary web page.
189 embedded_test_server()->GetURL("/extensions/test_file_with_body.html");
190 EXPECT_TRUE(CheckStyleInjection(browser(), url, true));
192 // The loaded extension has an exclude match for "extensions/test_file.html",
193 // so no CSS should be injected.
194 url = embedded_test_server()->GetURL("/extensions/test_file.html");
195 EXPECT_TRUE(CheckStyleInjection(browser(), url, false));
197 // We disallow all injection on the webstore.
198 GURL::Replacements replacements;
199 std::string host(kWebstoreDomain);
200 replacements.SetHostStr(host);
201 url = embedded_test_server()->GetURL("/extensions/test_file_with_body.html")
202 .ReplaceComponents(replacements);
203 EXPECT_TRUE(CheckStyleInjection(browser(), url, false));
207 IN_PROC_BROWSER_TEST_F(
209 DISABLED_ContentScriptStylesInjectedIntoExistingRenderers) {
210 ASSERT_TRUE(StartEmbeddedTestServer());
212 content::WindowedNotificationObserver signal(
213 extensions::NOTIFICATION_USER_SCRIPTS_UPDATED,
214 content::Source<Profile>(browser()->profile()));
216 // Start with a renderer already open at a URL.
217 GURL url(test_server()->GetURL("file/extensions/test_file.html"));
218 ui_test_utils::NavigateToURL(browser(), url);
221 test_data_dir_.AppendASCII("content_scripts/existing_renderers"));
225 // And check that its styles were affected by the styles that just got loaded.
226 bool styles_injected;
227 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
228 browser()->tab_strip_model()->GetActiveWebContents(),
229 "window.domAutomationController.send("
230 " document.defaultView.getComputedStyle(document.body, null)."
231 " getPropertyValue('background-color') == 'rgb(255, 0, 0)')",
233 ASSERT_TRUE(styles_injected);
236 IN_PROC_BROWSER_TEST_F(ExtensionApiTest,
237 ContentScriptCSSLocalization) {
238 ASSERT_TRUE(StartEmbeddedTestServer());
239 ASSERT_TRUE(RunExtensionTest("content_scripts/css_l10n")) << message_;
242 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ContentScriptExtensionAPIs) {
243 ASSERT_TRUE(StartEmbeddedTestServer());
245 const extensions::Extension* extension = LoadExtension(
246 test_data_dir_.AppendASCII("content_scripts/extension_api"));
248 ResultCatcher catcher;
249 ui_test_utils::NavigateToURL(
251 embedded_test_server()->GetURL(
252 "/extensions/api_test/content_scripts/extension_api/functions.html"));
253 EXPECT_TRUE(catcher.GetNextResult());
255 // Navigate to a page that will cause a content script to run that starts
256 // listening for an extension event.
257 ui_test_utils::NavigateToURL(
259 embedded_test_server()->GetURL(
260 "/extensions/api_test/content_scripts/extension_api/events.html"));
262 // Navigate to an extension page that will fire the event events.js is
264 ui_test_utils::NavigateToURLWithDisposition(
265 browser(), extension->GetResourceURL("fire_event.html"),
266 NEW_FOREGROUND_TAB, ui_test_utils::BROWSER_TEST_NONE);
267 EXPECT_TRUE(catcher.GetNextResult());
270 // Flaky on Windows. http://crbug.com/248418
272 #define MAYBE_ContentScriptPermissionsApi DISABLED_ContentScriptPermissionsApi
274 #define MAYBE_ContentScriptPermissionsApi ContentScriptPermissionsApi
276 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_ContentScriptPermissionsApi) {
277 extensions::PermissionsRequestFunction::SetIgnoreUserGestureForTests(true);
278 extensions::PermissionsRequestFunction::SetAutoConfirmForTests(true);
279 host_resolver()->AddRule("*.com", "127.0.0.1");
280 ASSERT_TRUE(StartEmbeddedTestServer());
281 ASSERT_TRUE(RunExtensionTest("content_scripts/permissions")) << message_;
284 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ContentScriptBypassPageCSP) {
285 ASSERT_TRUE(StartEmbeddedTestServer());
286 ASSERT_TRUE(RunExtensionTest("content_scripts/bypass_page_csp")) << message_;
289 } // namespace extensions