forked from mirrors/gecko-dev
Bug 1872245 - [devtools] Sort worker and extension targets alphabetically in about:debugging r=devtools-reviewers,ochameau
The debug targets are currently displayed in the order from the server, which makes it hard to find specific targets. Differential Revision: https://phabricator.services.mozilla.com/D197521
This commit is contained in:
parent
16fab22608
commit
9c509b8feb
7 changed files with 171 additions and 46 deletions
|
|
@ -258,8 +258,8 @@ function requestExtensions() {
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: REQUEST_EXTENSIONS_SUCCESS,
|
type: REQUEST_EXTENSIONS_SUCCESS,
|
||||||
installedExtensions,
|
installedExtensions: sortTargetsByName(installedExtensions),
|
||||||
temporaryExtensions,
|
temporaryExtensions: sortTargetsByName(temporaryExtensions),
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
dispatch({ type: REQUEST_EXTENSIONS_FAILURE, error: e });
|
dispatch({ type: REQUEST_EXTENSIONS_FAILURE, error: e });
|
||||||
|
|
@ -310,9 +310,9 @@ function requestWorkers() {
|
||||||
|
|
||||||
dispatch({
|
dispatch({
|
||||||
type: REQUEST_WORKERS_SUCCESS,
|
type: REQUEST_WORKERS_SUCCESS,
|
||||||
otherWorkers,
|
otherWorkers: sortTargetsByName(otherWorkers),
|
||||||
serviceWorkers,
|
serviceWorkers: sortTargetsByName(serviceWorkers),
|
||||||
sharedWorkers,
|
sharedWorkers: sortTargetsByName(sharedWorkers),
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
dispatch({ type: REQUEST_WORKERS_FAILURE, error: e });
|
dispatch({ type: REQUEST_WORKERS_FAILURE, error: e });
|
||||||
|
|
@ -330,6 +330,15 @@ function startServiceWorker(registrationFront) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sortTargetsByName(targets) {
|
||||||
|
return targets.sort((target1, target2) => {
|
||||||
|
// Fallback to empty string in case some targets don't have a valid name.
|
||||||
|
const name1 = target1.name || "";
|
||||||
|
const name2 = target2.name || "";
|
||||||
|
return name1.localeCompare(name2);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function unregisterServiceWorker(registrationFront) {
|
function unregisterServiceWorker(registrationFront) {
|
||||||
return async () => {
|
return async () => {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -243,6 +243,8 @@ skip-if = ["a11y_checks"] # Bug 1849028 and 1849179 for causing crashes
|
||||||
|
|
||||||
["browser_aboutdebugging_tab_zombietab.js"]
|
["browser_aboutdebugging_tab_zombietab.js"]
|
||||||
|
|
||||||
|
["browser_aboutdebugging_targets_sorted.js"]
|
||||||
|
|
||||||
["browser_aboutdebugging_telemetry_basic.js"]
|
["browser_aboutdebugging_telemetry_basic.js"]
|
||||||
|
|
||||||
["browser_aboutdebugging_telemetry_connection_attempt.js"]
|
["browser_aboutdebugging_telemetry_connection_attempt.js"]
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ PromiseTestUtils.allowMatchingRejectionsGlobally(/File closed/);
|
||||||
requestLongerTimeout(2);
|
requestLongerTimeout(2);
|
||||||
|
|
||||||
const ADDON_ID = "test-devtools-webextension@mozilla.org";
|
const ADDON_ID = "test-devtools-webextension@mozilla.org";
|
||||||
const ADDON_NAME = "test-devtools-webextension";
|
const ADDON_NAME = "base-test-devtools-webextension";
|
||||||
|
|
||||||
const OTHER_ADDON_ID = "other-test-devtools-webextension@mozilla.org";
|
const OTHER_ADDON_ID = "other-test-devtools-webextension@mozilla.org";
|
||||||
const OTHER_ADDON_NAME = "other-test-devtools-webextension";
|
const OTHER_ADDON_NAME = "other-test-devtools-webextension";
|
||||||
|
|
|
||||||
|
|
@ -64,43 +64,3 @@ async function testAddonsDisplay(showHidden) {
|
||||||
|
|
||||||
await removeTab(tab);
|
await removeTab(tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a basic mock for this-firefox client, and setup a runtime-client-factory mock
|
|
||||||
// to return our mock client when needed.
|
|
||||||
function setupThisFirefoxMock() {
|
|
||||||
const runtimeClientFactoryMock = createRuntimeClientFactoryMock();
|
|
||||||
const thisFirefoxClient = createThisFirefoxClientMock();
|
|
||||||
runtimeClientFactoryMock.createClientForRuntime = runtime => {
|
|
||||||
const {
|
|
||||||
RUNTIMES,
|
|
||||||
} = require("resource://devtools/client/aboutdebugging/src/constants.js");
|
|
||||||
if (runtime.id === RUNTIMES.THIS_FIREFOX) {
|
|
||||||
return thisFirefoxClient;
|
|
||||||
}
|
|
||||||
throw new Error("Unexpected runtime id " + runtime.id);
|
|
||||||
};
|
|
||||||
|
|
||||||
info("Enable mocks");
|
|
||||||
enableRuntimeClientFactoryMock(runtimeClientFactoryMock);
|
|
||||||
registerCleanupFunction(() => {
|
|
||||||
disableRuntimeClientFactoryMock();
|
|
||||||
});
|
|
||||||
|
|
||||||
return thisFirefoxClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create basic addon data as the DevToolsClient would return it (debuggable and non
|
|
||||||
// temporary).
|
|
||||||
function createAddonData({ id, name, isSystem, hidden }) {
|
|
||||||
return {
|
|
||||||
actor: `actorid-${id}`,
|
|
||||||
hidden,
|
|
||||||
iconURL: `moz-extension://${id}/icon-url.png`,
|
|
||||||
id,
|
|
||||||
manifestURL: `moz-extension://${id}/manifest-url.json`,
|
|
||||||
name,
|
|
||||||
isSystem,
|
|
||||||
temporarilyInstalled: false,
|
|
||||||
debuggable: true,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,111 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Check that all debug targets except tabs are sorted alphabetically.
|
||||||
|
add_task(async function () {
|
||||||
|
const thisFirefoxClient = setupThisFirefoxMock();
|
||||||
|
|
||||||
|
thisFirefoxClient.listAddons = () => [
|
||||||
|
createAddonData({ id: "addon-b", name: "Addon B" }),
|
||||||
|
createAddonData({ id: "addon-c", name: "Addon C" }),
|
||||||
|
createAddonData({ id: "addon-a", name: "Addon A" }),
|
||||||
|
createAddonData({ id: "tmp-b", name: "Temporary B", temporary: true }),
|
||||||
|
createAddonData({ id: "tmp-c", name: "Temporary C", temporary: true }),
|
||||||
|
createAddonData({ id: "tmp-a", name: "Temporary A", temporary: true }),
|
||||||
|
];
|
||||||
|
|
||||||
|
thisFirefoxClient.listWorkers = () => {
|
||||||
|
return {
|
||||||
|
otherWorkers: [
|
||||||
|
{ id: "worker-b", name: "Worker B" },
|
||||||
|
{ id: "worker-c", name: "Worker C" },
|
||||||
|
{ id: "worker-a", name: "Worker A" },
|
||||||
|
],
|
||||||
|
sharedWorkers: [
|
||||||
|
{ id: "shared-worker-b", name: "Shared Worker B" },
|
||||||
|
{ id: "shared-worker-c", name: "Shared Worker C" },
|
||||||
|
{ id: "shared-worker-a", name: "Shared Worker A" },
|
||||||
|
],
|
||||||
|
serviceWorkers: [
|
||||||
|
{ id: "service-worker-b", name: "Service Worker B" },
|
||||||
|
{ id: "service-worker-c", name: "Service Worker C" },
|
||||||
|
{ id: "service-worker-a", name: "Service Worker A" },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
thisFirefoxClient.listTabs = () => [
|
||||||
|
{
|
||||||
|
browserId: 2,
|
||||||
|
title: "Tab B",
|
||||||
|
url: "https://www.b.com",
|
||||||
|
retrieveFavicon: () => {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
browserId: 3,
|
||||||
|
title: "Tab C",
|
||||||
|
url: "https://www.c.com",
|
||||||
|
retrieveFavicon: () => {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
browserId: 1,
|
||||||
|
title: "Tab A",
|
||||||
|
url: "https://www.a.com",
|
||||||
|
retrieveFavicon: () => {},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const { document, tab, window } = await openAboutDebugging();
|
||||||
|
await selectThisFirefoxPage(document, window.AboutDebugging.store);
|
||||||
|
|
||||||
|
function findTargetIndex(name) {
|
||||||
|
const targets = [...document.querySelectorAll(".qa-debug-target-item")];
|
||||||
|
return targets.findIndex(target => target.textContent.includes(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
function assertTargetOrder(targetNames, message) {
|
||||||
|
let isSorted = true;
|
||||||
|
for (let i = 1; i < targetNames.length; i++) {
|
||||||
|
const index1 = findTargetIndex(targetNames[i - 1]);
|
||||||
|
const index2 = findTargetIndex(targetNames[i]);
|
||||||
|
if (index1 > index2) {
|
||||||
|
isSorted = false;
|
||||||
|
info(
|
||||||
|
`Targets ${targetNames[i - 1]} and ${targetNames[i]} ` +
|
||||||
|
`are not sorted as expected`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ok(isSorted, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertTargetOrder(
|
||||||
|
["Tab B", "Tab C", "Tab A"],
|
||||||
|
"Tabs are sorted as returned by the back-end"
|
||||||
|
);
|
||||||
|
assertTargetOrder(
|
||||||
|
["Addon A", "Addon B", "Addon C"],
|
||||||
|
"Addons are sorted alphabetically"
|
||||||
|
);
|
||||||
|
assertTargetOrder(
|
||||||
|
["Temporary A", "Temporary B", "Temporary C"],
|
||||||
|
"Temporary addons are sorted alphabetically"
|
||||||
|
);
|
||||||
|
assertTargetOrder(
|
||||||
|
["Worker A", "Worker B", "Worker C"],
|
||||||
|
"Workers are sorted alphabetically"
|
||||||
|
);
|
||||||
|
assertTargetOrder(
|
||||||
|
["Shared Worker A", "Shared Worker B", "Shared Worker C"],
|
||||||
|
"Shared workers are sorted alphabetically"
|
||||||
|
);
|
||||||
|
assertTargetOrder(
|
||||||
|
["Service Worker A", "Service Worker B", "Service Worker C"],
|
||||||
|
"Service workers are sorted alphabetically"
|
||||||
|
);
|
||||||
|
|
||||||
|
await removeTab(tab);
|
||||||
|
});
|
||||||
|
|
@ -503,3 +503,24 @@ function clickOnAddonWidget(addonId) {
|
||||||
info("Show the web extension popup");
|
info("Show the web extension popup");
|
||||||
browserActionEl.firstElementChild.click();
|
browserActionEl.firstElementChild.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create basic addon data as the DevToolsClient would return it.
|
||||||
|
function createAddonData({
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
isSystem = false,
|
||||||
|
hidden = false,
|
||||||
|
temporary = false,
|
||||||
|
}) {
|
||||||
|
return {
|
||||||
|
actor: `actorid-${id}`,
|
||||||
|
hidden,
|
||||||
|
iconURL: `moz-extension://${id}/icon-url.png`,
|
||||||
|
id,
|
||||||
|
manifestURL: `moz-extension://${id}/manifest-url.json`,
|
||||||
|
name,
|
||||||
|
isSystem,
|
||||||
|
temporarilyInstalled: temporary,
|
||||||
|
debuggable: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -260,3 +260,25 @@ async function createLocalClientWrapper() {
|
||||||
return new ClientWrapper(client);
|
return new ClientWrapper(client);
|
||||||
}
|
}
|
||||||
/* exported createLocalClientWrapper */
|
/* exported createLocalClientWrapper */
|
||||||
|
|
||||||
|
// Create a basic mock for this-firefox client, and setup a runtime-client-factory mock
|
||||||
|
// to return our mock client when needed.
|
||||||
|
function setupThisFirefoxMock() {
|
||||||
|
const runtimeClientFactoryMock = createRuntimeClientFactoryMock();
|
||||||
|
const thisFirefoxClient = createThisFirefoxClientMock();
|
||||||
|
runtimeClientFactoryMock.createClientForRuntime = runtime => {
|
||||||
|
if (runtime.id === RUNTIMES.THIS_FIREFOX) {
|
||||||
|
return thisFirefoxClient;
|
||||||
|
}
|
||||||
|
throw new Error("Unexpected runtime id " + runtime.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
info("Enable mocks");
|
||||||
|
enableRuntimeClientFactoryMock(runtimeClientFactoryMock);
|
||||||
|
registerCleanupFunction(() => {
|
||||||
|
disableRuntimeClientFactoryMock();
|
||||||
|
});
|
||||||
|
|
||||||
|
return thisFirefoxClient;
|
||||||
|
}
|
||||||
|
/* exported setupThisFirefoxMock */
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue