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({
|
||||
type: REQUEST_EXTENSIONS_SUCCESS,
|
||||
installedExtensions,
|
||||
temporaryExtensions,
|
||||
installedExtensions: sortTargetsByName(installedExtensions),
|
||||
temporaryExtensions: sortTargetsByName(temporaryExtensions),
|
||||
});
|
||||
} catch (e) {
|
||||
dispatch({ type: REQUEST_EXTENSIONS_FAILURE, error: e });
|
||||
|
|
@ -310,9 +310,9 @@ function requestWorkers() {
|
|||
|
||||
dispatch({
|
||||
type: REQUEST_WORKERS_SUCCESS,
|
||||
otherWorkers,
|
||||
serviceWorkers,
|
||||
sharedWorkers,
|
||||
otherWorkers: sortTargetsByName(otherWorkers),
|
||||
serviceWorkers: sortTargetsByName(serviceWorkers),
|
||||
sharedWorkers: sortTargetsByName(sharedWorkers),
|
||||
});
|
||||
} catch (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) {
|
||||
return async () => {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -243,6 +243,8 @@ skip-if = ["a11y_checks"] # Bug 1849028 and 1849179 for causing crashes
|
|||
|
||||
["browser_aboutdebugging_tab_zombietab.js"]
|
||||
|
||||
["browser_aboutdebugging_targets_sorted.js"]
|
||||
|
||||
["browser_aboutdebugging_telemetry_basic.js"]
|
||||
|
||||
["browser_aboutdebugging_telemetry_connection_attempt.js"]
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ PromiseTestUtils.allowMatchingRejectionsGlobally(/File closed/);
|
|||
requestLongerTimeout(2);
|
||||
|
||||
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_NAME = "other-test-devtools-webextension";
|
||||
|
|
|
|||
|
|
@ -64,43 +64,3 @@ async function testAddonsDisplay(showHidden) {
|
|||
|
||||
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");
|
||||
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);
|
||||
}
|
||||
/* 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