--- a/devtools/client/aboutdebugging/aboutdebugging.css
+++ b/devtools/client/aboutdebugging/aboutdebugging.css
@@ -146,40 +146,58 @@ button {
text-overflow: ellipsis;
}
.addons-controls {
display: flex;
flex-direction: row;
}
-.addons-install-error {
- background-color: #f3b0b0;
+.addons-install-error,
+.service-worker-multi-process {
padding: 5px 10px;
margin-top: 5px;
margin-inline-end: 4px;
}
-.service-worker-disabled .warning,
-.addons-install-error .warning {
+.addons-install-error {
+ background-color: #f3b0b0;
+}
+
+.service-worker-multi-process {
+ background-color: #ffeebb;
+ line-height: 1.5em;
+}
+
+.service-worker-multi-process .update-button {
+ margin: 5px 0;
+}
+
+.warning {
background-image: url(chrome://devtools/skin/images/alerticon-warning.png);
background-size: 13px 12px;
- margin-inline-end: 10px;
display: inline-block;
width: 13px;
height: 12px;
+ margin-inline-end: 10px;
}
@media (min-resolution: 1.1dppx) {
- .service-worker-disabled .warning,
- .addons-install-error .warning {
+ .warning {
background-image: url(chrome://devtools/skin/images/alerticon-warning@2x.png);
}
}
+.addons-install-error .warning,
+.service-worker-multi-process .warning {
+ /* The warning icon can be hard to see on red / yellow backgrounds, this turns the icon
+ to a black icon. */
+ filter: brightness(0%);
+}
+
.addons-options {
flex: 1;
}
.addons-debugging-label {
display: inline-block;
margin-inline-end: 1ch;
}
--- a/devtools/client/aboutdebugging/components/workers/moz.build
+++ b/devtools/client/aboutdebugging/components/workers/moz.build
@@ -1,9 +1,10 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DevToolsModules(
+ 'multi-e10s-warning.js',
'panel.js',
'service-worker-target.js',
'target.js',
)
new file mode 100644
--- /dev/null
+++ b/devtools/client/aboutdebugging/components/workers/multi-e10s-warning.js
@@ -0,0 +1,60 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* eslint-env browser */
+
+"use strict";
+
+loader.lazyImporter(this, "PrivateBrowsingUtils",
+ "resource://gre/modules/PrivateBrowsingUtils.jsm");
+const { createClass, DOM: dom } =
+ require("devtools/client/shared/vendor/react");
+const Services = require("Services");
+const { Ci } = require("chrome");
+
+loader.lazyImporter(this, "PrivateBrowsingUtils",
+ "resource://gre/modules/PrivateBrowsingUtils.jsm");
+
+loader.lazyRequireGetter(this, "DebuggerClient",
+ "devtools/shared/client/main", true);
+
+const Strings = Services.strings.createBundle("chrome://devtools/locale/aboutdebugging.properties");
+const PROCESS_COUNT_PREF = "dom.ipc.processCount";
+
+module.exports = createClass({
+ displayName: "multiE10SWarning",
+
+ onUpdatePreferenceClick() {
+ let message = Strings.GetStringFromName("multiProcessWarningConfirmUpdate");
+ if (window.confirm(message)) {
+ Services.prefs.setIntPref(PROCESS_COUNT_PREF, 1);
+ // Restart the browser.
+ Services.startup.quit(Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart);
+ }
+ },
+
+ render() {
+ return dom.div(
+ {
+ className: "service-worker-multi-process"
+ },
+ dom.div(
+ {},
+ dom.div({ className: "warning" }),
+ dom.b({}, Strings.GetStringFromName("multiProcessWarningTitle"))
+ ),
+ dom.div(
+ {},
+ Strings.GetStringFromName("multiProcessWarningMessage")
+ ),
+ dom.button(
+ {
+ className: "update-button",
+ onClick: this.onUpdatePreferenceClick,
+ },
+ Strings.GetStringFromName("multiProcessWarningUpdateLink")
+ )
+ );
+ },
+});
--- a/devtools/client/aboutdebugging/components/workers/panel.js
+++ b/devtools/client/aboutdebugging/components/workers/panel.js
@@ -11,67 +11,80 @@ const { Ci } = require("chrome");
const { createClass, createFactory, DOM: dom, PropTypes } =
require("devtools/client/shared/vendor/react");
const { getWorkerForms } = require("../../modules/worker");
const Services = require("Services");
const PanelHeader = createFactory(require("../panel-header"));
const TargetList = createFactory(require("../target-list"));
const WorkerTarget = createFactory(require("./target"));
+const MultiE10SWarning = createFactory(require("./multi-e10s-warning"));
const ServiceWorkerTarget = createFactory(require("./service-worker-target"));
loader.lazyImporter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
loader.lazyRequireGetter(this, "DebuggerClient",
"devtools/shared/client/main", true);
const Strings = Services.strings.createBundle(
"chrome://devtools/locale/aboutdebugging.properties");
const WorkerIcon = "chrome://devtools/skin/images/debugging-workers.svg";
const MORE_INFO_URL = "https://developer.mozilla.org/en-US/docs/Tools/about%3Adebugging";
+const PROCESS_COUNT_PREF = "dom.ipc.processCount";
module.exports = createClass({
displayName: "WorkersPanel",
propTypes: {
client: PropTypes.instanceOf(DebuggerClient).isRequired,
id: PropTypes.string.isRequired
},
getInitialState() {
return {
workers: {
service: [],
shared: [],
other: []
- }
+ },
+ processCount: 1,
};
},
componentDidMount() {
let client = this.props.client;
- client.addListener("workerListChanged", this.update);
- client.addListener("serviceWorkerRegistrationListChanged", this.update);
- client.addListener("processListChanged", this.update);
- client.addListener("registration-changed", this.update);
+ client.addListener("workerListChanged", this.updateWorkers);
+ client.addListener("serviceWorkerRegistrationListChanged", this.updateWorkers);
+ client.addListener("processListChanged", this.updateWorkers);
+ client.addListener("registration-changed", this.updateWorkers);
- this.update();
+ Services.prefs.addObserver(PROCESS_COUNT_PREF, this.updateMultiE10S, false);
+
+ this.updateMultiE10S();
+ this.updateWorkers();
},
componentWillUnmount() {
let client = this.props.client;
- client.removeListener("processListChanged", this.update);
- client.removeListener("serviceWorkerRegistrationListChanged", this.update);
- client.removeListener("workerListChanged", this.update);
- client.removeListener("registration-changed", this.update);
+ client.removeListener("processListChanged", this.updateWorkers);
+ client.removeListener("serviceWorkerRegistrationListChanged", this.updateWorkers);
+ client.removeListener("workerListChanged", this.updateWorkers);
+ client.removeListener("registration-changed", this.updateWorkers);
+
+ Services.prefs.removeObserver(PROCESS_COUNT_PREF, this.updateMultiE10S);
},
- update() {
+ updateMultiE10S() {
+ let processCount = Services.prefs.getIntPref(PROCESS_COUNT_PREF);
+ this.setState({ processCount });
+ },
+
+ updateWorkers() {
let workers = this.getInitialState().workers;
getWorkerForms(this.props.client).then(forms => {
forms.registrations.forEach(form => {
workers.service.push({
icon: WorkerIcon,
name: form.url,
url: form.url,
@@ -131,16 +144,20 @@ module.exports = createClass({
for (let registration of registrations) {
if (registration.scope === form.scope) {
return registration;
}
}
return null;
},
+ isE10S() {
+ return Services.appinfo.browserTabsRemoteAutostart;
+ },
+
renderServiceWorkersError() {
let isWindowPrivate = PrivateBrowsingUtils.isContentWindowPrivate(window);
let isPrivateBrowsingMode = PrivateBrowsingUtils.permanentPrivateBrowsing;
let isServiceWorkerDisabled = !Services.prefs
.getBoolPref("dom.serviceWorkers.enabled");
let isDisabled = isWindowPrivate || isPrivateBrowsingMode || isServiceWorkerDisabled;
if (!isDisabled) {
@@ -161,36 +178,41 @@ module.exports = createClass({
Strings.GetStringFromName("moreInfo")
),
")"
);
},
render() {
let { client, id } = this.props;
- let { workers } = this.state;
+ let { workers, processCount } = this.state;
+
+ let isE10S = Services.appinfo.browserTabsRemoteAutostart;
+ let isMultiE10S = isE10S && processCount > 1;
return dom.div(
{
id: id + "-panel",
className: "panel",
role: "tabpanel",
"aria-labelledby": id + "-header"
},
PanelHeader({
id: id + "-header",
name: Strings.GetStringFromName("workers")
}),
+ isMultiE10S ? MultiE10SWarning() : "",
dom.div(
{
id: "workers",
className: "inverted-icons"
},
TargetList({
client,
+ debugDisabled: isMultiE10S,
error: this.renderServiceWorkersError(),
id: "service-workers",
name: Strings.GetStringFromName("serviceWorkers"),
sort: true,
targetClass: ServiceWorkerTarget,
targets: workers.service
}),
TargetList({
--- a/devtools/client/aboutdebugging/components/workers/service-worker-target.js
+++ b/devtools/client/aboutdebugging/components/workers/service-worker-target.js
@@ -150,28 +150,30 @@ module.exports = createClass({
// ACTIVE state. Unable to know the actual state ("installing", "waiting"), we
// display a custom state "registering" for now. See Bug 1153292.
return "registering";
},
renderButtons() {
let pushButton = dom.button({
className: "push-button",
- onClick: this.push
+ onClick: this.push,
+ disabled: this.props.debugDisabled
}, Strings.GetStringFromName("push"));
let debugButton = dom.button({
className: "debug-button",
onClick: this.debug,
disabled: this.props.debugDisabled
}, Strings.GetStringFromName("debug"));
let startButton = dom.button({
className: "start-button",
onClick: this.start,
+ disabled: this.props.debugDisabled
}, Strings.GetStringFromName("start"));
if (this.isRunning()) {
if (this.isActive()) {
return [pushButton, debugButton];
}
// Only debug button is available if the service worker is not active.
return debugButton;
@@ -182,17 +184,17 @@ module.exports = createClass({
renderUnregisterLink() {
if (!this.isActive()) {
// If not active, there might be no registrationActor available.
return null;
}
return dom.a({
onClick: this.unregister,
- className: "unregister-link"
+ className: "unregister-link",
}, Strings.GetStringFromName("unregister"));
},
render() {
let { target } = this.props;
let { pushSubscription } = this.state;
let status = this.getServiceWorkerStatus();
--- a/devtools/client/aboutdebugging/test/browser.ini
+++ b/devtools/client/aboutdebugging/test/browser.ini
@@ -30,16 +30,17 @@ tags = webextensions
tags = webextensions
[browser_addons_debugging_initial_state.js]
[browser_addons_install.js]
[browser_addons_reload.js]
[browser_addons_toggle_debug.js]
[browser_page_not_found.js]
[browser_service_workers.js]
[browser_service_workers_fetch_flag.js]
+[browser_service_workers_multi_content_process.js]
[browser_service_workers_not_compatible.js]
[browser_service_workers_push.js]
[browser_service_workers_push_service.js]
[browser_service_workers_start.js]
[browser_service_workers_status.js]
[browser_service_workers_timeout.js]
skip-if = true # Bug 1232931
[browser_service_workers_unregister.js]
--- a/devtools/client/aboutdebugging/test/browser_service_workers.js
+++ b/devtools/client/aboutdebugging/test/browser_service_workers.js
@@ -4,23 +4,17 @@
"use strict";
// Service workers can't be loaded from chrome://,
// but http:// is ok with dom.serviceWorkers.testing.enabled turned on.
const SERVICE_WORKER = URL_ROOT + "service-workers/empty-sw.js";
const TAB_URL = URL_ROOT + "service-workers/empty-sw.html";
add_task(function* () {
- yield new Promise(done => {
- let options = {"set": [
- ["dom.serviceWorkers.enabled", true],
- ["dom.serviceWorkers.testing.enabled", true],
- ]};
- SpecialPowers.pushPrefEnv(options, done);
- });
+ yield enableServiceWorkerDebugging();
let { tab, document } = yield openAboutDebugging("workers");
let swTab = yield addTab(TAB_URL);
let serviceWorkersElement = getServiceWorkerList(document);
yield waitForMutation(serviceWorkersElement, { childList: true });
--- a/devtools/client/aboutdebugging/test/browser_service_workers_fetch_flag.js
+++ b/devtools/client/aboutdebugging/test/browser_service_workers_fetch_flag.js
@@ -4,24 +4,17 @@
"use strict";
// Service workers can't be loaded from chrome://,
// but http:// is ok with dom.serviceWorkers.testing.enabled turned on.
const EMPTY_SW_TAB_URL = URL_ROOT + "service-workers/empty-sw.html";
const FETCH_SW_TAB_URL = URL_ROOT + "service-workers/fetch-sw.html";
function* testBody(url, expecting) {
- yield new Promise(done => {
- let options = {"set": [
- ["dom.serviceWorkers.enabled", true],
- ["dom.serviceWorkers.testing.enabled", true],
- ]};
- SpecialPowers.pushPrefEnv(options, done);
- });
-
+ yield enableServiceWorkerDebugging();
let { tab, document } = yield openAboutDebugging("workers");
let swTab = yield addTab(url);
let serviceWorkersElement = getServiceWorkerList(document);
yield waitForMutation(serviceWorkersElement, { childList: true });
let fetchFlags =
new file mode 100644
--- /dev/null
+++ b/devtools/client/aboutdebugging/test/browser_service_workers_multi_content_process.js
@@ -0,0 +1,61 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Service worker debugging is unavailable when multi-e10s is enabled.
+// Check that the appropriate warning panel is displayed when there are more than 1
+// content process available.
+
+const SERVICE_WORKER = URL_ROOT + "service-workers/empty-sw.js";
+const TAB_URL = URL_ROOT + "service-workers/empty-sw.html";
+
+add_task(function* () {
+ yield enableServiceWorkerDebugging();
+ info("Force two content processes");
+ yield pushPref("dom.ipc.processCount", 2);
+
+ let { tab, document } = yield openAboutDebugging("workers");
+
+ let warningSection = document.querySelector(".service-worker-multi-process");
+ let img = warningSection.querySelector(".warning");
+ ok(img, "warning message is rendered");
+
+ let swTab = yield addTab(TAB_URL, { background: true });
+ let serviceWorkersElement = getServiceWorkerList(document);
+
+ yield waitForMutation(serviceWorkersElement, { childList: true });
+
+ info("Check that service worker buttons are disabled.");
+ // Check that the service worker appears in the UI
+ let serviceWorkerContainer = getServiceWorkerContainer(SERVICE_WORKER, document);
+ let debugButton = serviceWorkerContainer.querySelector(".debug-button");
+ ok(debugButton.disabled, "Start/Debug button is disabled");
+
+ info("Update the preference to 1");
+ let onWarningCleared = waitUntil(() => {
+ return document.querySelector(".service-worker-multi-process");
+ });
+ yield pushPref("dom.ipc.processCount", 1);
+ yield onWarningCleared;
+ ok(!debugButton.disabled, "Debug button is enabled.");
+
+ info("Update the preference back to 2");
+ let onWarningRestored = waitUntil(() => {
+ return document.querySelector(".service-worker-multi-process");
+ });
+ yield pushPref("dom.ipc.processCount", 2);
+ yield onWarningRestored;
+ ok(debugButton.disabled, "Debug button is disabled again.");
+
+ info("Unregister service worker");
+ try {
+ yield unregisterServiceWorker(swTab, serviceWorkersElement);
+ ok(true, "Service worker registration unregistered");
+ } catch (e) {
+ ok(false, "SW not unregistered; " + e);
+ }
+
+ yield removeTab(swTab);
+ yield closeAboutDebugging(tab);
+});
--- a/devtools/client/aboutdebugging/test/browser_service_workers_push.js
+++ b/devtools/client/aboutdebugging/test/browser_service_workers_push.js
@@ -10,25 +10,17 @@
// It should trigger a "push" notification in the worker.
// Service workers can't be loaded from chrome://, but http:// is ok with
// dom.serviceWorkers.testing.enabled turned on.
const SERVICE_WORKER = URL_ROOT + "service-workers/push-sw.js";
const TAB_URL = URL_ROOT + "service-workers/push-sw.html";
add_task(function* () {
- info("Turn on workers via mochitest http.");
- yield new Promise(done => {
- let options = { "set": [
- // Accept workers from mochitest's http.
- ["dom.serviceWorkers.testing.enabled", true],
- ]};
- SpecialPowers.pushPrefEnv(options, done);
- });
-
+ yield enableServiceWorkerDebugging();
let { tab, document } = yield openAboutDebugging("workers");
// Listen for mutations in the service-workers list.
let serviceWorkersElement = getServiceWorkerList(document);
let onMutation = waitForMutation(serviceWorkersElement, { childList: true });
// Open a tab that registers a push service worker.
let swTab = yield addTab(TAB_URL);
--- a/devtools/client/aboutdebugging/test/browser_service_workers_push_service.js
+++ b/devtools/client/aboutdebugging/test/browser_service_workers_push_service.js
@@ -13,24 +13,19 @@ const TAB_URL = URL_ROOT + "service-work
const FAKE_ENDPOINT = "https://fake/endpoint";
const PushService = Cc["@mozilla.org/push/Service;1"]
.getService(Ci.nsIPushService).wrappedJSObject;
add_task(function* () {
info("Turn on workers via mochitest http.");
- yield SpecialPowers.pushPrefEnv({
- "set": [
- // Accept workers from mochitest's http.
- ["dom.serviceWorkers.testing.enabled", true],
- // Enable the push service.
- ["dom.push.connection.enabled", true],
- ]
- });
+ yield enableServiceWorkerDebugging();
+ // Enable the push service.
+ yield pushPref("dom.push.connection.enabled", true);
info("Mock the push service");
PushService.service = {
_registrations: new Map(),
_notify(scope) {
Services.obs.notifyObservers(
null,
PushService.subscriptionModifiedTopic,
--- a/devtools/client/aboutdebugging/test/browser_service_workers_start.js
+++ b/devtools/client/aboutdebugging/test/browser_service_workers_start.js
@@ -10,27 +10,19 @@
// Service workers can't be loaded from chrome://, but http:// is ok with
// dom.serviceWorkers.testing.enabled turned on.
const SERVICE_WORKER = URL_ROOT + "service-workers/empty-sw.js";
const TAB_URL = URL_ROOT + "service-workers/empty-sw.html";
const SW_TIMEOUT = 1000;
add_task(function* () {
- info("Turn on workers via mochitest http.");
- yield new Promise(done => {
- let options = { "set": [
- // Accept workers from mochitest's http.
- ["dom.serviceWorkers.testing.enabled", true],
- // Reduce the timeout to accelerate service worker freezing
- ["dom.serviceWorkers.idle_timeout", SW_TIMEOUT],
- ["dom.serviceWorkers.idle_extended_timeout", SW_TIMEOUT],
- ]};
- SpecialPowers.pushPrefEnv(options, done);
- });
+ yield enableServiceWorkerDebugging();
+ yield pushPref("dom.serviceWorkers.idle_timeout", SW_TIMEOUT);
+ yield pushPref("dom.serviceWorkers.idle_extended_timeout", SW_TIMEOUT);
let { tab, document } = yield openAboutDebugging("workers");
// Listen for mutations in the service-workers list.
let serviceWorkersElement = getServiceWorkerList(document);
let onMutation = waitForMutation(serviceWorkersElement, { childList: true });
// Open a tab that registers an empty service worker.
--- a/devtools/client/aboutdebugging/test/browser_service_workers_status.js
+++ b/devtools/client/aboutdebugging/test/browser_service_workers_status.js
@@ -7,25 +7,19 @@
// but http:// is ok with dom.serviceWorkers.testing.enabled turned on.
const SERVICE_WORKER = URL_ROOT + "service-workers/delay-sw.js";
const TAB_URL = URL_ROOT + "service-workers/delay-sw.html";
const SW_TIMEOUT = 2000;
requestLongerTimeout(2);
add_task(function* () {
- yield SpecialPowers.pushPrefEnv({
- "set": [
- // Accept workers from mochitest's http.
- ["dom.serviceWorkers.testing.enabled", true],
- ["dom.serviceWorkers.idle_timeout", SW_TIMEOUT],
- ["dom.serviceWorkers.idle_extended_timeout", SW_TIMEOUT],
- ["dom.ipc.processCount", 1],
- ]
- });
+ yield enableServiceWorkerDebugging();
+ yield pushPref("dom.serviceWorkers.idle_timeout", SW_TIMEOUT);
+ yield pushPref("dom.serviceWorkers.idle_extended_timeout", SW_TIMEOUT);
let { tab, document } = yield openAboutDebugging("workers");
// Listen for mutations in the service-workers list.
let serviceWorkersElement = getServiceWorkerList(document);
let onMutation = waitForMutation(serviceWorkersElement, { childList: true });
let swTab = yield addTab(TAB_URL);
--- a/devtools/client/aboutdebugging/test/browser_service_workers_timeout.js
+++ b/devtools/client/aboutdebugging/test/browser_service_workers_timeout.js
@@ -6,27 +6,19 @@
// Service workers can't be loaded from chrome://,
// but http:// is ok with dom.serviceWorkers.testing.enabled turned on.
const SERVICE_WORKER = URL_ROOT + "service-workers/empty-sw.js";
const TAB_URL = URL_ROOT + "service-workers/empty-sw.html";
const SW_TIMEOUT = 1000;
add_task(function* () {
- yield new Promise(done => {
- let options = {"set": [
- // Accept workers from mochitest's http
- ["dom.serviceWorkers.testing.enabled", true],
- // Reduce the timeout to expose issues when service worker
- // freezing is broken
- ["dom.serviceWorkers.idle_timeout", SW_TIMEOUT],
- ["dom.serviceWorkers.idle_extended_timeout", SW_TIMEOUT],
- ]};
- SpecialPowers.pushPrefEnv(options, done);
- });
+ yield enableServiceWorkerDebugging();
+ yield pushPref("dom.serviceWorkers.idle_timeout", SW_TIMEOUT);
+ yield pushPref("dom.serviceWorkers.idle_extended_timeout", SW_TIMEOUT);
let { tab, document } = yield openAboutDebugging("workers");
let swTab = yield addTab(TAB_URL);
let serviceWorkersElement = getServiceWorkerList(document);
yield waitForMutation(serviceWorkersElement, { childList: true });
--- a/devtools/client/aboutdebugging/test/browser_service_workers_unregister.js
+++ b/devtools/client/aboutdebugging/test/browser_service_workers_unregister.js
@@ -10,25 +10,17 @@
// Service workers can't be loaded from chrome://, but http:// is ok with
// dom.serviceWorkers.testing.enabled turned on.
const SCOPE = URL_ROOT + "service-workers/";
const SERVICE_WORKER = SCOPE + "empty-sw.js";
const TAB_URL = SCOPE + "empty-sw.html";
add_task(function* () {
- info("Turn on workers via mochitest http.");
- yield new Promise(done => {
- let options = { "set": [
- // Accept workers from mochitest's http.
- ["dom.serviceWorkers.testing.enabled", true],
- ["dom.ipc.processCount", 1],
- ]};
- SpecialPowers.pushPrefEnv(options, done);
- });
+ yield enableServiceWorkerDebugging();
let { tab, document } = yield openAboutDebugging("workers");
// Listen for mutations in the service-workers list.
let serviceWorkersElement = getServiceWorkerList(document);
let onMutation = waitForMutation(serviceWorkersElement, { childList: true });
// Open a tab that registers an empty service worker.
--- a/devtools/client/aboutdebugging/test/head.js
+++ b/devtools/client/aboutdebugging/test/head.js
@@ -2,17 +2,18 @@
http://creativecommons.org/publicdomain/zero/1.0/ */
/* eslint-env browser */
/* exported openAboutDebugging, changeAboutDebuggingHash, closeAboutDebugging,
installAddon, uninstallAddon, waitForMutation, waitForContentMutation, assertHasTarget,
getServiceWorkerList, getTabList, openPanel, waitForInitialAddonList,
waitForServiceWorkerRegistered, unregisterServiceWorker,
waitForDelayedStartupFinished, setupTestAboutDebuggingWebExtension,
- waitForServiceWorkerActivation */
+ waitForServiceWorkerActivation, enableServiceWorkerDebugging,
+ getServiceWorkerContainer */
/* import-globals-from ../../framework/test/shared-head.js */
"use strict";
// Load the shared-head file first.
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/framework/test/shared-head.js",
this);
@@ -127,16 +128,36 @@ function getInstalledAddonNames(document
* @return {DOMNode} target list or container element
*/
function getServiceWorkerList(document) {
return document.querySelector("#service-workers .target-list") ||
document.querySelector("#service-workers.targets");
}
/**
+ * Retrieve the container element for the service worker corresponding to the provided
+ * name.
+ *
+ * @param {String} name
+ * expected service worker name
+ * @param {DOMDocument} document
+ * #service-workers section container document
+ * @return {DOMNode} container element
+ */
+function getServiceWorkerContainer(name, document) {
+ let nameElements = [...document.querySelectorAll("#service-workers .target-name")];
+ let nameElement = nameElements.filter(element => element.textContent === name)[0];
+ if (nameElement) {
+ return nameElement.closest(".target-container");
+ }
+
+ return null;
+}
+
+/**
* Depending on whether there are tabs opened, return either a
* target list element or its container.
* @param {DOMDocument} document #tabs section container document
* @return {DOMNode} target list or container element
*/
function getTabList(document) {
return document.querySelector("#tabs .target-list") ||
document.querySelector("#tabs.targets");
@@ -392,8 +413,25 @@ function* waitForServiceWorkerActivation
let targetElement = name.parentNode.parentNode;
let targetStatus = targetElement.querySelector(".target-status");
while (targetStatus.textContent === "Registering") {
// Wait for the status to leave the "registering" stage.
yield waitForMutation(serviceWorkersElement, { childList: true, subtree: true });
}
}
+
+/**
+ * Set all preferences needed to enable service worker debugging and testing.
+ */
+function enableServiceWorkerDebugging() {
+ return new Promise(done => {
+ let options = { "set": [
+ // Enable service workers.
+ ["dom.serviceWorkers.enabled", true],
+ // Accept workers from mochitest's http.
+ ["dom.serviceWorkers.testing.enabled", true],
+ // Force single content process.
+ ["dom.ipc.processCount", 1],
+ ]};
+ SpecialPowers.pushPrefEnv(options, done);
+ });
+}
--- a/devtools/client/locales/en-US/aboutdebugging.properties
+++ b/devtools/client/locales/en-US/aboutdebugging.properties
@@ -114,8 +114,28 @@ pageNotFound = Page not found
# %S will be replaced by the name of the page at run-time.
doesNotExist = #%S does not exist!
# LOCALIZATION NOTE (nothing):
# This string is displayed when the list of workers is empty.
nothing = Nothing yet.
configurationIsNotCompatible = Your browser configuration is not compatible with Service Workers
+
+# LOCALIZATION NOTE (multiProcessWarningTitle):
+# This string is displayed as a warning message on top of the about:debugging#workers
+# page when multi-e10s is enabled
+multiProcessWarningTitle = Service Worker debugging is not compatible with multiple content processes at the moment.
+
+# LOCALIZATION NOTE (multiProcessWarningMessage):
+# This string is displayed in the warning section for multi-e10s in
+# about:debugging#workers
+multiProcessWarningMessage = The preference “dom.ipc.processCount” can be set to 1 to force a single content process.
+
+# LOCALIZATION NOTE (multiProcessWarningLink):
+# This string is the text content of a link in the warning section for multi-e10s in
+# about:debugging#workers. The link updates the pref and restarts the browser.
+multiProcessWarningUpdateLink = Set dom.ipc.processCount to 1
+
+# LOCALIZATION NOTE (multiProcessWarningConfirmUpdate):
+# This string is displayed as a confirmation message when the user clicks on
+# the multiProcessWarningUpdateLink in about:debugging#workers
+multiProcessWarningConfirmUpdate = Set “dom.ipc.processCount” to 1 and restart the browser?