1 // Copyright 2015 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/run_loop.h"
6 #include "chrome/browser/extensions/extension_apitest.h"
7 #include "chrome/browser/extensions/extension_service.h"
8 #include "chrome/browser/ui/tabs/tab_strip_model.h"
9 #include "chrome/test/base/ui_test_utils.h"
10 #include "components/version_info/version_info.h"
11 #include "content/public/browser/navigation_entry.h"
12 #include "content/public/test/browser_test_utils.h"
13 #include "content/public/test/test_utils.h"
14 #include "extensions/test/extension_test_message_listener.h"
16 namespace extensions
{
18 class ServiceWorkerTest
: public ExtensionApiTest
{
20 // Set the channel to "trunk" since service workers are restricted to trunk.
22 : current_channel_(version_info::Channel::UNKNOWN
) {}
24 ~ServiceWorkerTest() override
{}
27 ScopedCurrentChannel current_channel_
;
28 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerTest
);
31 IN_PROC_BROWSER_TEST_F(ServiceWorkerTest
, RegisterServiceWorkersOnTrunk
) {
32 ExtensionTestMessageListener
listener(false);
33 ASSERT_TRUE(RunExtensionTest("service_worker/register")) << message_
;
36 // This feature is restricted to trunk, so on dev it should have existing
37 // behavior - which is for it to fail.
38 IN_PROC_BROWSER_TEST_F(ServiceWorkerTest
, CannotRegisterServiceWorkersOnDev
) {
39 ScopedCurrentChannel
current_channel_override(
40 version_info::Channel::DEV
);
41 ExtensionTestMessageListener
listener(false);
42 ASSERT_FALSE(RunExtensionTest("service_worker/register")) << message_
;
43 ASSERT_TRUE(listener
.WaitUntilSatisfied());
45 "SecurityError: Failed to register a ServiceWorker: The URL "
46 "protocol of the current origin ('chrome-extension://" +
47 GetSingleLoadedExtension()->id() + "') is not supported.",
51 // Disabled: crbug.com/529516.
52 IN_PROC_BROWSER_TEST_F(ServiceWorkerTest
, DISABLED_ServiceWorkerFetchEvent
) {
53 RunExtensionTest("service_worker/fetch");
54 content::WebContents
* contents
=
55 browser()->tab_strip_model()->GetActiveWebContents();
56 content::WaitForLoadStop(contents
);
59 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
60 contents
, "window.domAutomationController.send(document.body.innerText);",
62 EXPECT_EQ("No Fetch Event yet.", output
);
64 // Page must reload in order for the service worker to take control.
65 contents
->GetController().Reload(true);
66 content::WaitForLoadStop(contents
);
68 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
69 contents
, "window.domAutomationController.send(document.body.innerText);",
71 EXPECT_EQ("Caught a fetch!", output
);
74 // Binding that was created on the v8::Context of the worker for testing
75 // purposes should bind an object to chrome.
76 // Disabled: crbug.com/529516.
77 IN_PROC_BROWSER_TEST_F(ServiceWorkerTest
, DISABLED_ServiceWorkerChromeBinding
) {
78 ASSERT_TRUE(RunExtensionTest("service_worker/bindings")) << message_
;
79 content::WebContents
* contents
=
80 browser()->tab_strip_model()->GetActiveWebContents();
81 content::WaitForLoadStop(contents
);
84 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
85 contents
, "window.domAutomationController.send(document.body.innerText);",
87 EXPECT_EQ("No Fetch Event yet.", output
);
89 // Page must reload in order for the service worker to take control.
90 contents
->GetController().Reload(true);
91 content::WaitForLoadStop(contents
);
93 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
94 contents
, "window.domAutomationController.send(document.body.innerText);",
96 EXPECT_EQ("object", output
);
99 // Disabled: crbug.com/529516.
100 IN_PROC_BROWSER_TEST_F(ServiceWorkerTest
, DISABLED_GetBackgroundClient
) {
101 ASSERT_TRUE(RunExtensionTest("service_worker/background_client")) << message_
;
102 content::WebContents
* contents
=
103 browser()->tab_strip_model()->GetActiveWebContents();
104 content::WaitForLoadStop(contents
);
107 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
108 contents
, "window.domAutomationController.send(document.body.innerText);",
110 EXPECT_EQ("No Fetch Event yet.", output
);
112 // Page must reload in order for the service worker to take control.
113 contents
->GetController().Reload(true);
114 content::WaitForLoadStop(contents
);
116 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
117 contents
, "window.domAutomationController.send(document.body.innerText);",
119 EXPECT_EQ("chrome-extension://" + GetSingleLoadedExtension()->id() +
121 "_generated_background_page.html",
125 IN_PROC_BROWSER_TEST_F(ServiceWorkerTest
, PostMessageToBackgroundClient
) {
126 ASSERT_TRUE(RunExtensionTest("service_worker/post_messaging")) << message_
;
128 EXPECT_EQ("Hello from the SW!",
129 ExecuteScriptInBackgroundPage(
130 GetSingleLoadedExtension()->id(),
131 "window.domAutomationController.send(message);"));
134 IN_PROC_BROWSER_TEST_F(ServiceWorkerTest
,
135 ServiceWorkerSuspensionOnExtensionUnload
) {
136 const Extension
* extension
= LoadExtension(
137 test_data_dir_
.AppendASCII("service_worker").AppendASCII("suspended"));
138 ASSERT_TRUE(extension
);
139 std::string extension_id
= extension
->id();
141 ExtensionTestMessageListener
listener("registered", false);
142 GURL url
= extension
->GetResourceURL("/page.html");
143 ui_test_utils::NavigateToURLWithDisposition(
144 browser(), url
, NEW_FOREGROUND_TAB
,
145 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
146 listener
.WaitUntilSatisfied();
147 content::WebContents
* web_contents
=
148 browser()->tab_strip_model()->GetActiveWebContents();
150 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
152 "window.domAutomationController.send(document.body.innerText);",
154 EXPECT_EQ("No Fetch Event yet.", output
);
156 // Page must reload in order for the service worker to take control.
157 content::RunAllBlockingPoolTasksUntilIdle();
158 base::RunLoop().RunUntilIdle();
159 web_contents
->GetController().Reload(true);
160 content::WaitForLoadStop(web_contents
);
162 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
164 "window.domAutomationController.send(document.body.innerText);",
166 EXPECT_EQ("Caught a fetch!", output
);
168 extension_service()->DisableExtension(extension
->id(),
169 Extension::DISABLE_USER_ACTION
);
170 base::RunLoop().RunUntilIdle();
171 // When the extension is disabled, chrome closes any tabs open to its pages,
172 // so we have to navigate back by hand.
173 ui_test_utils::NavigateToURLWithDisposition(
174 browser(), url
, NEW_FOREGROUND_TAB
,
175 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
176 web_contents
= browser()->tab_strip_model()->GetActiveWebContents();
177 EXPECT_EQ(content::PAGE_TYPE_ERROR
,
178 web_contents
->GetController().GetActiveEntry()->GetPageType());
180 extension_service()->EnableExtension(extension_id
);
181 base::RunLoop().RunUntilIdle();
183 web_contents
->GetController().Reload(true);
184 content::WaitForLoadStop(web_contents
);
186 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
188 "window.domAutomationController.send(document.body.innerText);",
190 EXPECT_EQ("Caught a fetch!", output
);
193 } // namespace extensions