Bug 1509038 - Port serviceworker push test to new about:debugging;r=daisuke

Depends on D14077

This test is a conversion of devtools/client/aboutdebugging/test/browser_service_workers_push.js
It turns out I forgot to file a bug to migrate this test, so doing it here.

Differential Revision: https://phabricator.services.mozilla.com/D14078

--HG--
rename : devtools/client/aboutdebugging/test/service-workers/push-sw.html => devtools/client/aboutdebugging-new/test/browser/resources/service-workers/push-sw.html
rename : devtools/client/aboutdebugging/test/service-workers/push-sw.js => devtools/client/aboutdebugging-new/test/browser/resources/service-workers/push-sw.js
extra : moz-landing-system : lando
This commit is contained in:
Julian Descottes 2018-12-12 13:26:09 +00:00
parent c1946a4cbd
commit 08226e3138
7 changed files with 212 additions and 5 deletions

View File

@ -44,7 +44,11 @@ class ServiceWorkerAction extends PureComponent {
if (!isRunning) {
const startLabel = this.props.getString("about-debugging-worker-action-start");
return this._renderButton(startLabel, this.start.bind(this));
return this._renderButton({
className: "default-button",
label: startLabel,
onClick: this.start.bind(this),
});
}
if (!isActive) {
@ -54,15 +58,19 @@ class ServiceWorkerAction extends PureComponent {
const pushLabel = this.props.getString("about-debugging-worker-action-push");
return [
this._renderButton(pushLabel, this.push.bind(this)),
this._renderButton({
className: "default-button js-push-button",
label: pushLabel,
onClick: this.push.bind(this),
}),
InspectAction({ dispatch, target }),
];
}
_renderButton(label, onClick) {
_renderButton({ className, label, onClick }) {
return dom.button(
{
className: "default-button",
className,
onClick: e => onClick(),
},
label,

View File

@ -83,7 +83,10 @@ class WorkerDetail extends PureComponent {
$status: status,
},
dom.span(
{ className: `badge ${status === "running" ? "badge--success" : ""}`},
{
className: `badge js-worker-status ` +
`${status === "running" ? "badge--success" : ""}`,
},
status
)
),

View File

@ -9,9 +9,11 @@ support-files =
debug-target-pane_collapsibilities_head.js
head-addons-script.js
head-mocks.js
head-serviceworker.js
head.js
mocks/*
resources/bad-extension/*
resources/service-workers/*
resources/test-adb-extension/*
resources/test-temporary-extension/*
test-tab-favicons.html
@ -34,6 +36,7 @@ skip-if = (os == 'linux' && bits == 32) # ADB start() fails on linux 32, see Bug
[browser_aboutdebugging_routes.js]
[browser_aboutdebugging_runtime_connection-prompt.js]
[browser_aboutdebugging_select_network_runtime.js]
[browser_aboutdebugging_serviceworker_push.js]
[browser_aboutdebugging_sidebar_network_runtimes.js]
[browser_aboutdebugging_sidebar_usb_runtime.js]
[browser_aboutdebugging_sidebar_usb_runtime_connect.js]

View File

@ -0,0 +1,56 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/* global sendAsyncMessage */
"use strict";
/* import-globals-from head-serviceworker.js */
Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "head-serviceworker.js", this);
const SERVICE_WORKER = URL_ROOT + "resources/service-workers/push-sw.js";
const TAB_URL = URL_ROOT + "resources/service-workers/push-sw.html";
// Test that clicking on the Push button next to a Service Worker works as intended.
// It should trigger a "push" notification in the worker.
add_task(async function() {
await enableServiceWorkerDebugging();
const { document, tab } = await openAboutDebugging();
// Open a tab that registers a push service worker.
const swTab = await addTab(TAB_URL);
info("Forward service worker messages to the test");
await forwardServiceWorkerMessage(swTab);
info("Wait for the service worker to claim the test window before proceeding.");
await onTabMessage(swTab, "sw-claimed");
info("Wait until the service worker appears and is running");
await waitUntil(() => {
const target = findDebugTargetByText(SERVICE_WORKER, document);
const status = target && target.querySelector(".js-worker-status");
return status && status.textContent === "Running";
});
// Retrieve the Push button for the worker.
const targetElement = findDebugTargetByText(SERVICE_WORKER, document);
const pushButton = targetElement.querySelector(".js-push-button");
ok(pushButton, "Found its push button");
info("Click on the Push button and wait for the push notification");
const onPushNotification = onTabMessage(swTab, "sw-pushed");
pushButton.click();
await onPushNotification;
info("Unregister the service worker");
await unregisterServiceWorker(swTab, "pushServiceWorkerRegistration");
info("Wait until the service worker disappears from about:debugging");
await waitUntil(() => !findDebugTargetByText(SERVICE_WORKER, document));
info("Remove the service worker tab");
await removeTab(swTab);
await removeTab(tab);
});

View File

@ -0,0 +1,73 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/* import-globals-from ../../../shared/test/shared-head.js */
"use strict";
/**
* Temporarily flip all the preferences necessary for service worker testing.
*/
async function enableServiceWorkerDebugging() {
// Enable service workers.
await pushPref("dom.serviceWorkers.enabled", true);
// Accept workers from mochitest's http (normally only available in https).
await pushPref("dom.serviceWorkers.testing.enabled", true);
// Force single content process. Necessary until sw e10s refactor is done (Bug 1231208).
await pushPref("dom.ipc.processCount", 1);
Services.ppmm.releaseCachedProcesses();
}
/**
* Helper to listen once on a message sent using postMessage from the provided tab.
*
* @param {Tab} tab
* The tab on which the message will be received.
* @param {String} message
* The name of the expected message.
*/
function onTabMessage(tab, message) {
const mm = tab.linkedBrowser.messageManager;
return new Promise(resolve => {
mm.addMessageListener(message, function listener() {
mm.removeMessageListener(message, listener);
resolve();
});
});
}
/**
* Helper to listen once on a message sent using postMessage from the provided tab.
*
* @param {Tab} tab
* The tab on which the message will be received.
* @param {String} message
* The name of the expected message.
*/
function forwardServiceWorkerMessage(tab) {
info("Make the test page notify us when the service worker sends a message.");
return ContentTask.spawn(tab.linkedBrowser, {}, function() {
const win = content.wrappedJSObject;
win.navigator.serviceWorker.addEventListener("message", function(event) {
sendAsyncMessage(event.data);
});
});
}
/**
* Unregister the service worker from the content page
*
* @param {Tab} tab
* The tab on which the service worker should be removed.
* @param {String} reference
* The reference to the service worker registration promise created on the content
* window.
*/
async function unregisterServiceWorker(tab, reference) {
await ContentTask.spawn(tab.linkedBrowser, reference, async function(_reference) {
// Retrieve the registration promise created in the html page
const registration = await content.wrappedJSObject[_reference];
await registration.unregister();
});
}

View File

@ -0,0 +1,31 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>Service worker push test</title>
</head>
<body>
<script type="text/javascript">
"use strict";
window.pushServiceWorkerRegistration = (async function() {
await new Promise(resolve => {
const perm = { type: "desktop-notification", allow: true, context: document };
SpecialPowers.pushPermissions([perm], resolve);
});
try {
const registration = navigator.serviceWorker.register("push-sw.js");
dump("Push service worker registered\n");
return registration;
} catch (e) {
dump("Push service worker not registered: " + e + "\n");
}
return null;
})();
</script>
</body>
</html>

View File

@ -0,0 +1,33 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/* eslint-env worker */
/* global clients */
"use strict";
// Send a message to all controlled windows.
function postMessage(message) {
return clients.matchAll().then(function(clientlist) {
clientlist.forEach(function(client) {
client.postMessage(message);
});
});
}
// Don't wait for the next page load to become the active service worker.
self.addEventListener("install", function(event) {
event.waitUntil(self.skipWaiting());
});
// Claim control over the currently open test page when activating.
self.addEventListener("activate", function(event) {
event.waitUntil(self.clients.claim().then(function() {
return postMessage("sw-claimed");
}));
});
// Forward all "push" events to the controlled window.
self.addEventListener("push", function(event) {
event.waitUntil(postMessage("sw-pushed"));
});