blob: fbfc56144f5d02b1b6b9ab83fe6a6b1ecc48b547 [file] [log] [blame]
annekao38685502015-07-14 17:46:391// 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.
4
kalman6f984ae2015-09-18 17:21:585#include "base/bind_helpers.h"
6#include "base/strings/stringprintf.h"
horo1eeddde2015-11-19 05:59:257#include "base/strings/utf_string_conversions.h"
annekao38685502015-07-14 17:46:398#include "chrome/browser/extensions/extension_apitest.h"
rdevlin.croninf5863da2015-09-10 19:21:459#include "chrome/browser/extensions/extension_service.h"
lazyboy561b7de2015-11-19 19:27:3010#include "chrome/browser/notifications/desktop_notification_profile_util.h"
11#include "chrome/browser/push_messaging/push_messaging_app_identifier.h"
12#include "chrome/browser/push_messaging/push_messaging_service_factory.h"
13#include "chrome/browser/push_messaging/push_messaging_service_impl.h"
14#include "chrome/browser/services/gcm/fake_gcm_profile_service.h"
15#include "chrome/browser/services/gcm/gcm_profile_service_factory.h"
annekao1db36fd2015-07-29 17:09:1616#include "chrome/browser/ui/tabs/tab_strip_model.h"
rdevlin.croninf5863da2015-09-10 19:21:4517#include "chrome/test/base/ui_test_utils.h"
sdefresne9fb67692015-08-03 18:48:2218#include "components/version_info/version_info.h"
kalman6f984ae2015-09-18 17:21:5819#include "content/public/browser/navigation_controller.h"
rdevlin.croninf5863da2015-09-10 19:21:4520#include "content/public/browser/navigation_entry.h"
kalman6f984ae2015-09-18 17:21:5821#include "content/public/browser/web_contents.h"
lazyboybd325ae2015-11-18 21:35:2622#include "content/public/common/content_switches.h"
kalman6f984ae2015-09-18 17:21:5823#include "content/public/common/page_type.h"
lazyboybd325ae2015-11-18 21:35:2624#include "content/public/test/background_sync_test_util.h"
annekao1db36fd2015-07-29 17:09:1625#include "content/public/test/browser_test_utils.h"
kalman6f984ae2015-09-18 17:21:5826#include "extensions/browser/extension_host.h"
lazyboyc3e763a2015-12-09 23:09:5827#include "extensions/browser/extension_registry.h"
kalman6f984ae2015-09-18 17:21:5828#include "extensions/browser/process_manager.h"
29#include "extensions/test/background_page_watcher.h"
annekao38685502015-07-14 17:46:3930#include "extensions/test/extension_test_message_listener.h"
horo1eeddde2015-11-19 05:59:2531#include "net/test/embedded_test_server/embedded_test_server.h"
annekao38685502015-07-14 17:46:3932
33namespace extensions {
34
kalman6f984ae2015-09-18 17:21:5835namespace {
36
37// Pass into ServiceWorkerTest::StartTestFromBackgroundPage to indicate that
38// registration is expected to succeed.
39std::string* const kExpectSuccess = nullptr;
40
41void DoNothingWithBool(bool b) {}
42
43} // namespace
44
annekao38685502015-07-14 17:46:3945class ServiceWorkerTest : public ExtensionApiTest {
46 public:
kalman6f984ae2015-09-18 17:21:5847 ServiceWorkerTest() : current_channel_(version_info::Channel::UNKNOWN) {}
annekao38685502015-07-14 17:46:3948
49 ~ServiceWorkerTest() override {}
50
kalman6f984ae2015-09-18 17:21:5851 protected:
52 // Returns the ProcessManager for the test's profile.
53 ProcessManager* process_manager() { return ProcessManager::Get(profile()); }
54
55 // Starts running a test from the background page test extension.
56 //
57 // This registers a service worker with |script_name|, and fetches the
58 // registration result.
59 //
60 // If |error_or_null| is null (kExpectSuccess), success is expected and this
61 // will fail if there is an error.
62 // If |error_or_null| is not null, nothing is assumed, and the error (which
63 // may be empty) is written to it.
64 const Extension* StartTestFromBackgroundPage(const char* script_name,
65 std::string* error_or_null) {
66 const Extension* extension =
67 LoadExtension(test_data_dir_.AppendASCII("service_worker/background"));
68 CHECK(extension);
69 ExtensionHost* background_host =
70 process_manager()->GetBackgroundHostForExtension(extension->id());
71 CHECK(background_host);
72 std::string error;
73 CHECK(content::ExecuteScriptAndExtractString(
74 background_host->host_contents(),
75 base::StringPrintf("test.registerServiceWorker('%s')", script_name),
76 &error));
77 if (error_or_null)
78 *error_or_null = error;
79 else if (!error.empty())
80 ADD_FAILURE() << "Got unexpected error " << error;
81 return extension;
82 }
83
84 // Navigates the browser to a new tab at |url|, waits for it to load, then
85 // returns it.
86 content::WebContents* Navigate(const GURL& url) {
87 ui_test_utils::NavigateToURLWithDisposition(
88 browser(), url, NEW_FOREGROUND_TAB,
89 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
90 content::WebContents* web_contents =
91 browser()->tab_strip_model()->GetActiveWebContents();
92 content::WaitForLoadStop(web_contents);
93 return web_contents;
94 }
95
96 // Navigates the browser to |url| and returns the new tab's page type.
97 content::PageType NavigateAndGetPageType(const GURL& url) {
98 return Navigate(url)->GetController().GetActiveEntry()->GetPageType();
99 }
100
101 // Extracts the innerText from |contents|.
102 std::string ExtractInnerText(content::WebContents* contents) {
103 std::string inner_text;
104 if (!content::ExecuteScriptAndExtractString(
105 contents,
106 "window.domAutomationController.send(document.body.innerText)",
107 &inner_text)) {
108 ADD_FAILURE() << "Failed to get inner text for "
109 << contents->GetVisibleURL();
110 }
111 return inner_text;
112 }
113
114 // Navigates the browser to |url|, then returns the innerText of the new
115 // tab's WebContents' main frame.
116 std::string NavigateAndExtractInnerText(const GURL& url) {
117 return ExtractInnerText(Navigate(url));
118 }
119
annekao38685502015-07-14 17:46:39120 private:
kalman6f984ae2015-09-18 17:21:58121 // Sets the channel to "trunk" since service workers are restricted to trunk.
annekao38685502015-07-14 17:46:39122 ScopedCurrentChannel current_channel_;
kalman6f984ae2015-09-18 17:21:58123
annekao38685502015-07-14 17:46:39124 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerTest);
125};
126
lazyboybd325ae2015-11-18 21:35:26127class ServiceWorkerBackgroundSyncTest : public ServiceWorkerTest {
128 public:
129 ServiceWorkerBackgroundSyncTest() {}
130 ~ServiceWorkerBackgroundSyncTest() override {}
131
132 void SetUpCommandLine(base::CommandLine* command_line) override {
133 // ServiceWorkerRegistration.sync requires experimental flag.
134 command_line->AppendSwitch(
135 switches::kEnableExperimentalWebPlatformFeatures);
136 ServiceWorkerTest::SetUpCommandLine(command_line);
137 }
138
139 void SetUp() override {
140 content::background_sync_test_util::SetIgnoreNetworkChangeNotifier(true);
141 ServiceWorkerTest::SetUp();
142 }
143
144 private:
145 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerBackgroundSyncTest);
146};
147
lazyboy561b7de2015-11-19 19:27:30148class ServiceWorkerPushMessagingTest : public ServiceWorkerTest {
149 public:
150 ServiceWorkerPushMessagingTest()
151 : gcm_service_(nullptr), push_service_(nullptr) {}
152 ~ServiceWorkerPushMessagingTest() override {}
153
154 void GrantNotificationPermissionForTest(const GURL& url) {
155 GURL origin = url.GetOrigin();
156 DesktopNotificationProfileUtil::GrantPermission(profile(), origin);
157 ASSERT_EQ(
158 CONTENT_SETTING_ALLOW,
159 DesktopNotificationProfileUtil::GetContentSetting(profile(), origin));
160 }
161
162 PushMessagingAppIdentifier GetAppIdentifierForServiceWorkerRegistration(
163 int64 service_worker_registration_id,
164 const GURL& origin) {
165 PushMessagingAppIdentifier app_identifier =
166 PushMessagingAppIdentifier::FindByServiceWorker(
167 profile(), origin, service_worker_registration_id);
168
169 EXPECT_FALSE(app_identifier.is_null());
170 return app_identifier;
171 }
172
173 // ExtensionApiTest overrides.
174 void SetUpCommandLine(base::CommandLine* command_line) override {
peter9de96272015-12-04 15:23:27175 command_line->AppendSwitch(
176 switches::kEnableExperimentalWebPlatformFeatures);
lazyboy561b7de2015-11-19 19:27:30177 ServiceWorkerTest::SetUpCommandLine(command_line);
178 }
179 void SetUpOnMainThread() override {
180 gcm_service_ = static_cast<gcm::FakeGCMProfileService*>(
181 gcm::GCMProfileServiceFactory::GetInstance()->SetTestingFactoryAndUse(
182 profile(), &gcm::FakeGCMProfileService::Build));
183 gcm_service_->set_collect(true);
184 push_service_ = PushMessagingServiceFactory::GetForProfile(profile());
185
186 ServiceWorkerTest::SetUpOnMainThread();
187 }
188
189 gcm::FakeGCMProfileService* gcm_service() const { return gcm_service_; }
190 PushMessagingServiceImpl* push_service() const { return push_service_; }
191
192 private:
193 gcm::FakeGCMProfileService* gcm_service_;
194 PushMessagingServiceImpl* push_service_;
195
196 DISALLOW_COPY_AND_ASSIGN(ServiceWorkerPushMessagingTest);
197};
198
kalman6f984ae2015-09-18 17:21:58199IN_PROC_BROWSER_TEST_F(ServiceWorkerTest, RegisterSucceedsOnTrunk) {
200 StartTestFromBackgroundPage("register.js", kExpectSuccess);
annekao38685502015-07-14 17:46:39201}
202
203// This feature is restricted to trunk, so on dev it should have existing
204// behavior - which is for it to fail.
kalman6f984ae2015-09-18 17:21:58205IN_PROC_BROWSER_TEST_F(ServiceWorkerTest, RegisterFailsOnDev) {
annekao38685502015-07-14 17:46:39206 ScopedCurrentChannel current_channel_override(
sdefresne6e883e42015-07-30 08:05:54207 version_info::Channel::DEV);
kalman6f984ae2015-09-18 17:21:58208 std::string error;
209 const Extension* extension =
210 StartTestFromBackgroundPage("register.js", &error);
annekao1db36fd2015-07-29 17:09:16211 EXPECT_EQ(
kalman6f984ae2015-09-18 17:21:58212 "Failed to register a ServiceWorker: The URL protocol of the current "
213 "origin ('chrome-extension://" +
214 extension->id() + "') is not supported.",
215 error);
annekao38685502015-07-14 17:46:39216}
217
lazyboyc3e763a2015-12-09 23:09:58218IN_PROC_BROWSER_TEST_F(ServiceWorkerTest, UpdateRefreshesServiceWorker) {
219 base::ScopedTempDir scoped_temp_dir;
220 ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
221 base::FilePath pem_path = test_data_dir_.AppendASCII("service_worker")
222 .AppendASCII("update")
223 .AppendASCII("service_worker.pem");
224 base::FilePath path_v1 = PackExtensionWithOptions(
225 test_data_dir_.AppendASCII("service_worker")
226 .AppendASCII("update")
227 .AppendASCII("v1"),
228 scoped_temp_dir.path().AppendASCII("v1.crx"), pem_path, base::FilePath());
229 base::FilePath path_v2 = PackExtensionWithOptions(
230 test_data_dir_.AppendASCII("service_worker")
231 .AppendASCII("update")
232 .AppendASCII("v2"),
233 scoped_temp_dir.path().AppendASCII("v2.crx"), pem_path, base::FilePath());
234 const char* kId = "hfaanndiiilofhfokeanhddpkfffchdi";
235
236 ExtensionTestMessageListener listener_v1("Pong from version 1", false);
237 listener_v1.set_failure_message("FAILURE_V1");
238 // Install version 1.0 of the extension.
239 ASSERT_TRUE(InstallExtension(path_v1, 1));
240 EXPECT_TRUE(extensions::ExtensionRegistry::Get(profile())
241 ->enabled_extensions()
242 .GetByID(kId));
243 EXPECT_TRUE(listener_v1.WaitUntilSatisfied());
244
245 ExtensionTestMessageListener listener_v2("Pong from version 2", false);
246 listener_v2.set_failure_message("FAILURE_V2");
247
248 // Update to version 2.0.
249 EXPECT_TRUE(UpdateExtension(kId, path_v2, 0));
250 EXPECT_TRUE(extensions::ExtensionRegistry::Get(profile())
251 ->enabled_extensions()
252 .GetByID(kId));
253 EXPECT_TRUE(listener_v2.WaitUntilSatisfied());
254}
255
kalman6f984ae2015-09-18 17:21:58256IN_PROC_BROWSER_TEST_F(ServiceWorkerTest, FetchArbitraryPaths) {
257 const Extension* extension =
258 StartTestFromBackgroundPage("fetch.js", kExpectSuccess);
annekao1db36fd2015-07-29 17:09:16259
kalman6f984ae2015-09-18 17:21:58260 // Open some arbirary paths. Their contents should be what the service worker
261 // responds with, which in this case is the path of the fetch.
262 EXPECT_EQ(
263 "Caught a fetch for /index.html",
264 NavigateAndExtractInnerText(extension->GetResourceURL("index.html")));
265 EXPECT_EQ("Caught a fetch for /path/to/other.html",
266 NavigateAndExtractInnerText(
267 extension->GetResourceURL("path/to/other.html")));
268 EXPECT_EQ("Caught a fetch for /some/text/file.txt",
269 NavigateAndExtractInnerText(
270 extension->GetResourceURL("some/text/file.txt")));
271 EXPECT_EQ("Caught a fetch for /no/file/extension",
272 NavigateAndExtractInnerText(
273 extension->GetResourceURL("no/file/extension")));
274 EXPECT_EQ("Caught a fetch for /",
275 NavigateAndExtractInnerText(extension->GetResourceURL("")));
annekao1db36fd2015-07-29 17:09:16276}
277
kalman6f984ae2015-09-18 17:21:58278IN_PROC_BROWSER_TEST_F(ServiceWorkerTest,
279 LoadingBackgroundPageBypassesServiceWorker) {
280 const Extension* extension =
281 StartTestFromBackgroundPage("fetch.js", kExpectSuccess);
annekao49241182015-08-18 17:14:01282
kalman6f984ae2015-09-18 17:21:58283 std::string kExpectedInnerText = "background.html contents for testing.";
annekao49241182015-08-18 17:14:01284
kalman6f984ae2015-09-18 17:21:58285 // Sanity check that the background page has the expected content.
286 ExtensionHost* background_page =
287 process_manager()->GetBackgroundHostForExtension(extension->id());
288 ASSERT_TRUE(background_page);
289 EXPECT_EQ(kExpectedInnerText,
290 ExtractInnerText(background_page->host_contents()));
annekao49241182015-08-18 17:14:01291
kalman6f984ae2015-09-18 17:21:58292 // Close the background page.
293 background_page->Close();
294 BackgroundPageWatcher(process_manager(), extension).WaitForClose();
295 background_page = nullptr;
296
297 // Start it again.
298 process_manager()->WakeEventPage(extension->id(),
299 base::Bind(&DoNothingWithBool));
300 BackgroundPageWatcher(process_manager(), extension).WaitForOpen();
301
302 // Content should not have been affected by the fetch, which would otherwise
303 // be "Caught fetch for...".
304 background_page =
305 process_manager()->GetBackgroundHostForExtension(extension->id());
306 ASSERT_TRUE(background_page);
307 content::WaitForLoadStop(background_page->host_contents());
308
309 // TODO(kalman): Everything you've read has been a LIE! It should be:
310 //
311 // EXPECT_EQ(kExpectedInnerText,
312 // ExtractInnerText(background_page->host_contents()));
313 //
314 // but there is a bug, and we're actually *not* bypassing the service worker
315 // for background page loads! For now, let it pass (assert wrong behavior)
316 // because it's not a regression, but this must be fixed eventually.
317 //
318 // Tracked in crbug.com/532720.
319 EXPECT_EQ("Caught a fetch for /background.html",
320 ExtractInnerText(background_page->host_contents()));
annekao49241182015-08-18 17:14:01321}
322
kalman6f984ae2015-09-18 17:21:58323IN_PROC_BROWSER_TEST_F(ServiceWorkerTest,
324 ServiceWorkerPostsMessageToBackgroundClient) {
325 const Extension* extension = StartTestFromBackgroundPage(
326 "post_message_to_background_client.js", kExpectSuccess);
annekao533482222015-08-21 23:23:53327
kalman6f984ae2015-09-18 17:21:58328 // The service worker in this test simply posts a message to the background
329 // client it receives from getBackgroundClient().
330 const char* kScript =
331 "var messagePromise = null;\n"
332 "if (test.lastMessageFromServiceWorker) {\n"
333 " messagePromise = Promise.resolve(test.lastMessageFromServiceWorker);\n"
334 "} else {\n"
335 " messagePromise = test.waitForMessage(navigator.serviceWorker);\n"
336 "}\n"
337 "messagePromise.then(function(message) {\n"
338 " window.domAutomationController.send(String(message == 'success'));\n"
339 "})\n";
340 EXPECT_EQ("true", ExecuteScriptInBackgroundPage(extension->id(), kScript));
annekao533482222015-08-21 23:23:53341}
342
kalman6f984ae2015-09-18 17:21:58343IN_PROC_BROWSER_TEST_F(ServiceWorkerTest,
344 BackgroundPagePostsMessageToServiceWorker) {
345 const Extension* extension =
346 StartTestFromBackgroundPage("post_message_to_sw.js", kExpectSuccess);
annekao533482222015-08-21 23:23:53347
kalman6f984ae2015-09-18 17:21:58348 // The service worker in this test waits for a message, then echoes it back
349 // by posting a message to the background page via getBackgroundClient().
350 const char* kScript =
351 "var mc = new MessageChannel();\n"
352 "test.waitForMessage(mc.port1).then(function(message) {\n"
353 " window.domAutomationController.send(String(message == 'hello'));\n"
354 "});\n"
355 "test.registeredServiceWorker.postMessage(\n"
356 " {message: 'hello', port: mc.port2}, [mc.port2])\n";
357 EXPECT_EQ("true", ExecuteScriptInBackgroundPage(extension->id(), kScript));
annekao533482222015-08-21 23:23:53358}
359
rdevlin.croninf5863da2015-09-10 19:21:45360IN_PROC_BROWSER_TEST_F(ServiceWorkerTest,
361 ServiceWorkerSuspensionOnExtensionUnload) {
kalman6f984ae2015-09-18 17:21:58362 // For this test, only hold onto the extension's ID and URL + a function to
363 // get a resource URL, because we're going to be disabling and uninstalling
364 // it, which will invalidate the pointer.
365 std::string extension_id;
366 GURL extension_url;
367 {
368 const Extension* extension =
369 StartTestFromBackgroundPage("fetch.js", kExpectSuccess);
370 extension_id = extension->id();
371 extension_url = extension->url();
372 }
373 auto get_resource_url = [&extension_url](const std::string& path) {
374 return Extension::GetResourceURL(extension_url, path);
375 };
rdevlin.croninf5863da2015-09-10 19:21:45376
kalman6f984ae2015-09-18 17:21:58377 // Fetch should route to the service worker.
378 EXPECT_EQ("Caught a fetch for /index.html",
379 NavigateAndExtractInnerText(get_resource_url("index.html")));
rdevlin.croninf5863da2015-09-10 19:21:45380
kalman6f984ae2015-09-18 17:21:58381 // Disable the extension. Opening the page should fail.
382 extension_service()->DisableExtension(extension_id,
rdevlin.croninf5863da2015-09-10 19:21:45383 Extension::DISABLE_USER_ACTION);
384 base::RunLoop().RunUntilIdle();
rdevlin.croninf5863da2015-09-10 19:21:45385
kalman6f984ae2015-09-18 17:21:58386 EXPECT_EQ(content::PAGE_TYPE_ERROR,
387 NavigateAndGetPageType(get_resource_url("index.html")));
388 EXPECT_EQ(content::PAGE_TYPE_ERROR,
389 NavigateAndGetPageType(get_resource_url("other.html")));
390
391 // Re-enable the extension. Opening pages should immediately start to succeed
392 // again.
rdevlin.croninf5863da2015-09-10 19:21:45393 extension_service()->EnableExtension(extension_id);
394 base::RunLoop().RunUntilIdle();
395
kalman6f984ae2015-09-18 17:21:58396 EXPECT_EQ("Caught a fetch for /index.html",
397 NavigateAndExtractInnerText(get_resource_url("index.html")));
398 EXPECT_EQ("Caught a fetch for /other.html",
399 NavigateAndExtractInnerText(get_resource_url("other.html")));
400 EXPECT_EQ("Caught a fetch for /another.html",
401 NavigateAndExtractInnerText(get_resource_url("another.html")));
rdevlin.croninf5863da2015-09-10 19:21:45402
kalman6f984ae2015-09-18 17:21:58403 // Uninstall the extension. Opening pages should fail again.
404 base::string16 error;
405 extension_service()->UninstallExtension(
406 extension_id, UninstallReason::UNINSTALL_REASON_FOR_TESTING,
407 base::Bind(&base::DoNothing), &error);
408 base::RunLoop().RunUntilIdle();
409
410 EXPECT_EQ(content::PAGE_TYPE_ERROR,
411 NavigateAndGetPageType(get_resource_url("index.html")));
412 EXPECT_EQ(content::PAGE_TYPE_ERROR,
413 NavigateAndGetPageType(get_resource_url("other.html")));
414 EXPECT_EQ(content::PAGE_TYPE_ERROR,
415 NavigateAndGetPageType(get_resource_url("anotherother.html")));
416 EXPECT_EQ(content::PAGE_TYPE_ERROR,
417 NavigateAndGetPageType(get_resource_url("final.html")));
418}
419
420IN_PROC_BROWSER_TEST_F(ServiceWorkerTest, BackgroundPageIsWokenIfAsleep) {
421 const Extension* extension =
422 StartTestFromBackgroundPage("wake_on_fetch.js", kExpectSuccess);
423
424 // Navigate to special URLs that this test's service worker recognises, each
425 // making a check then populating the response with either "true" or "false".
426 EXPECT_EQ("true", NavigateAndExtractInnerText(extension->GetResourceURL(
427 "background-client-is-awake")));
428 EXPECT_EQ("true", NavigateAndExtractInnerText(
429 extension->GetResourceURL("ping-background-client")));
430 // Ping more than once for good measure.
431 EXPECT_EQ("true", NavigateAndExtractInnerText(
432 extension->GetResourceURL("ping-background-client")));
433
434 // Shut down the event page. The SW should detect that it's closed, but still
435 // be able to ping it.
436 ExtensionHost* background_page =
437 process_manager()->GetBackgroundHostForExtension(extension->id());
438 ASSERT_TRUE(background_page);
439 background_page->Close();
440 BackgroundPageWatcher(process_manager(), extension).WaitForClose();
441
442 EXPECT_EQ("false", NavigateAndExtractInnerText(extension->GetResourceURL(
443 "background-client-is-awake")));
444 EXPECT_EQ("true", NavigateAndExtractInnerText(
445 extension->GetResourceURL("ping-background-client")));
446 EXPECT_EQ("true", NavigateAndExtractInnerText(
447 extension->GetResourceURL("ping-background-client")));
448 EXPECT_EQ("true", NavigateAndExtractInnerText(extension->GetResourceURL(
449 "background-client-is-awake")));
450}
451
452IN_PROC_BROWSER_TEST_F(ServiceWorkerTest,
453 GetBackgroundClientFailsWithNoBackgroundPage) {
454 // This extension doesn't have a background page, only a tab at page.html.
455 // The service worker it registers tries to call getBackgroundClient() and
456 // should fail.
457 // Note that this also tests that service workers can be registered from tabs.
458 EXPECT_TRUE(RunExtensionSubtest("service_worker/no_background", "page.html"));
rdevlin.croninf5863da2015-09-10 19:21:45459}
460
lazyboy6ddb7d62015-11-10 23:15:27461IN_PROC_BROWSER_TEST_F(ServiceWorkerTest, NotificationAPI) {
462 EXPECT_TRUE(RunExtensionSubtest("service_worker/notifications/has_permission",
463 "page.html"));
464}
465
lazyboybd325ae2015-11-18 21:35:26466IN_PROC_BROWSER_TEST_F(ServiceWorkerBackgroundSyncTest, Sync) {
467 const Extension* extension = LoadExtensionWithFlags(
468 test_data_dir_.AppendASCII("service_worker/sync"), kFlagNone);
469 ASSERT_TRUE(extension);
470 ui_test_utils::NavigateToURL(browser(),
471 extension->GetResourceURL("page.html"));
472 content::WebContents* web_contents =
473 browser()->tab_strip_model()->GetActiveWebContents();
474
475 // Prevent firing by going offline.
476 content::background_sync_test_util::SetOnline(web_contents, false);
477
478 ExtensionTestMessageListener sync_listener("SYNC: send-chats", false);
479 sync_listener.set_failure_message("FAIL");
480
481 std::string result;
482 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
483 web_contents, "window.runServiceWorker()", &result));
484 ASSERT_EQ("SERVICE_WORKER_READY", result);
485
486 EXPECT_FALSE(sync_listener.was_satisfied());
487 // Resume firing by going online.
488 content::background_sync_test_util::SetOnline(web_contents, true);
489 EXPECT_TRUE(sync_listener.WaitUntilSatisfied());
490}
491
horo1eeddde2015-11-19 05:59:25492IN_PROC_BROWSER_TEST_F(ServiceWorkerTest,
493 FetchFromContentScriptShouldNotGoToServiceWorkerOfPage) {
494 ASSERT_TRUE(StartEmbeddedTestServer());
495 GURL page_url = embedded_test_server()->GetURL(
496 "/extensions/api_test/service_worker/content_script_fetch/"
497 "controlled_page/index.html");
498 content::WebContents* tab =
499 browser()->tab_strip_model()->GetActiveWebContents();
500 ui_test_utils::NavigateToURL(browser(), page_url);
501 content::WaitForLoadStop(tab);
502
503 std::string value;
504 ASSERT_TRUE(
505 content::ExecuteScriptAndExtractString(tab, "register();", &value));
506 EXPECT_EQ("SW controlled", value);
507
508 ASSERT_TRUE(RunExtensionTest("service_worker/content_script_fetch"))
509 << message_;
510}
511
lazyboy561b7de2015-11-19 19:27:30512IN_PROC_BROWSER_TEST_F(ServiceWorkerPushMessagingTest, OnPush) {
513 const Extension* extension = LoadExtensionWithFlags(
514 test_data_dir_.AppendASCII("service_worker/push_messaging"), kFlagNone);
515 ASSERT_TRUE(extension);
516 GURL extension_url = extension->url();
517
518 ASSERT_NO_FATAL_FAILURE(GrantNotificationPermissionForTest(extension_url));
519
520 GURL url = extension->GetResourceURL("page.html");
521 ui_test_utils::NavigateToURL(browser(), url);
522
523 content::WebContents* web_contents =
524 browser()->tab_strip_model()->GetActiveWebContents();
525
526 // Start the ServiceWorker.
527 ExtensionTestMessageListener ready_listener("SERVICE_WORKER_READY", false);
528 ready_listener.set_failure_message("SERVICE_WORKER_FAILURE");
529 const char* kScript = "window.runServiceWorker()";
530 EXPECT_TRUE(content::ExecuteScript(web_contents->GetMainFrame(), kScript));
531 EXPECT_TRUE(ready_listener.WaitUntilSatisfied());
532
533 PushMessagingAppIdentifier app_identifier =
534 GetAppIdentifierForServiceWorkerRegistration(0LL, extension_url);
535 ASSERT_EQ(app_identifier.app_id(), gcm_service()->last_registered_app_id());
536 EXPECT_EQ("1234567890", gcm_service()->last_registered_sender_ids()[0]);
537
538 // Send a push message via gcm and expect the ServiceWorker to receive it.
539 ExtensionTestMessageListener push_message_listener("OK", false);
540 push_message_listener.set_failure_message("FAIL");
541 gcm::IncomingMessage message;
542 message.sender_id = "1234567890";
543 message.raw_data = "testdata";
544 message.decrypted = true;
545 push_service()->OnMessage(app_identifier.app_id(), message);
546 EXPECT_TRUE(push_message_listener.WaitUntilSatisfied());
547}
548
annekao38685502015-07-14 17:46:39549} // namespace extensions