Bug 1561435 - Format devtools/client/, a=automatic-formatting

# ignore-this-changeset

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

--HG--
extra : source : 60e4496cf9699dc59f2f4738cb60f87cbdb01e67
This commit is contained in:
Victor Porof 2019-07-05 11:24:38 +02:00
parent 7676fc16e4
commit f6db0ee557
2792 changed files with 96115 additions and 52865 deletions

View file

@ -43,14 +43,6 @@ module.exports = {
"mozilla" "mozilla"
], ],
"overrides": [{ "overrides": [{
"files": [
"devtools/**",
],
"rules": {
// Temporarily disable the curly everywhere, pending Prettier.
"curly": "off"
}
}, {
"files": [ "files": [
"*.html", "*.html",
"*.xhtml", "*.xhtml",

View file

@ -40,31 +40,6 @@ toolkit/components/telemetry/datareporting-prefs.js
toolkit/components/telemetry/healthreport-prefs.js toolkit/components/telemetry/healthreport-prefs.js
# Ignore all devtools directories for now, except the debugger. # Ignore all devtools directories for now, except the debugger.
devtools/client/*.js
devtools/client/aboutdebugging/**
devtools/client/aboutdebugging-new/**
devtools/client/accessibility/**
devtools/client/application/**
devtools/client/bin/**
devtools/client/dom/**
devtools/client/framework/**
devtools/client/inspector/**
devtools/client/jsonview/**
devtools/client/locales/**
devtools/client/memory/**
devtools/client/netmonitor/**
devtools/client/performance/**
devtools/client/performance-new/**
devtools/client/preferences/**
devtools/client/responsive.html/**
devtools/client/scratchpad/**
devtools/client/shared/**
devtools/client/storage/**
devtools/client/styleeditor/**
devtools/client/themes/**
devtools/client/webconsole/**
devtools/client/webide/**
devtools/client/webreplay/**
devtools/docs/** devtools/docs/**
devtools/platform/** devtools/platform/**
devtools/server/** devtools/server/**

View file

@ -8,10 +8,13 @@ const Services = require("Services");
const { bindActionCreators } = require("devtools/client/shared/vendor/redux"); const { bindActionCreators } = require("devtools/client/shared/vendor/redux");
const { createFactory } = require("devtools/client/shared/vendor/react"); const { createFactory } = require("devtools/client/shared/vendor/react");
const { render, unmountComponentAtNode } = const {
require("devtools/client/shared/vendor/react-dom"); render,
const Provider = unmountComponentAtNode,
createFactory(require("devtools/client/shared/vendor/react-redux").Provider); } = require("devtools/client/shared/vendor/react-dom");
const Provider = createFactory(
require("devtools/client/shared/vendor/react-redux").Provider
);
const FluentReact = require("devtools/client/shared/vendor/fluent-react"); const FluentReact = require("devtools/client/shared/vendor/fluent-react");
const LocalizationProvider = createFactory(FluentReact.LocalizationProvider); const LocalizationProvider = createFactory(FluentReact.LocalizationProvider);
@ -36,10 +39,22 @@ const {
} = require("./src/modules/usb-runtimes"); } = require("./src/modules/usb-runtimes");
loader.lazyRequireGetter(this, "adb", "devtools/shared/adb/adb", true); loader.lazyRequireGetter(this, "adb", "devtools/shared/adb/adb", true);
loader.lazyRequireGetter(this, "adbAddon", "devtools/shared/adb/adb-addon", true); loader.lazyRequireGetter(
loader.lazyRequireGetter(this, "adbProcess", "devtools/shared/adb/adb-process", true); this,
"adbAddon",
"devtools/shared/adb/adb-addon",
true
);
loader.lazyRequireGetter(
this,
"adbProcess",
"devtools/shared/adb/adb-process",
true
);
const Router = createFactory(require("devtools/client/shared/vendor/react-router-dom").HashRouter); const Router = createFactory(
require("devtools/client/shared/vendor/react-router-dom").HashRouter
);
const App = createFactory(require("./src/components/App")); const App = createFactory(require("./src/components/App"));
const AboutDebugging = { const AboutDebugging = {
@ -61,10 +76,7 @@ const AboutDebugging = {
const width = this.getRoundedViewportWidth(); const width = this.getRoundedViewportWidth();
this.actions.recordTelemetryEvent("open_adbg", { width }); this.actions.recordTelemetryEvent("open_adbg", { width });
await l10n.init([ await l10n.init(["branding/brand.ftl", "devtools/aboutdebugging.ftl"]);
"branding/brand.ftl",
"devtools/aboutdebugging.ftl",
]);
this.actions.createThisFirefoxRuntime(); this.actions.createThisFirefoxRuntime();
@ -77,7 +89,9 @@ const AboutDebugging = {
// If ADB is already started, wait for the initial runtime list to be able to restore // If ADB is already started, wait for the initial runtime list to be able to restore
// already connected runtimes. // already connected runtimes.
const isProcessStarted = await adb.isProcessStarted(); const isProcessStarted = await adb.isProcessStarted();
const onAdbRuntimesReady = isProcessStarted ? adb.once("runtime-list-ready") : null; const onAdbRuntimesReady = isProcessStarted
? adb.once("runtime-list-ready")
: null;
addUSBRuntimesObserver(this.onUSBRuntimesUpdated); addUSBRuntimesObserver(this.onUSBRuntimesUpdated);
await onAdbRuntimesReady; await onAdbRuntimesReady;
@ -90,12 +104,7 @@ const AboutDebugging = {
}, },
LocalizationProvider( LocalizationProvider(
{ messages: l10n.getBundles() }, { messages: l10n.getBundles() },
Router( Router({}, App({}))
{},
App(
{}
)
)
) )
), ),
this.mount this.mount
@ -161,13 +170,21 @@ const AboutDebugging = {
}, },
}; };
window.addEventListener("DOMContentLoaded", () => { window.addEventListener(
AboutDebugging.init(); "DOMContentLoaded",
}, { once: true }); () => {
AboutDebugging.init();
},
{ once: true }
);
window.addEventListener("unload", () => { window.addEventListener(
AboutDebugging.destroy(); "unload",
}, {once: true}); () => {
AboutDebugging.destroy();
},
{ once: true }
);
// Expose AboutDebugging to tests so that they can access to the store. // Expose AboutDebugging to tests so that they can access to the store.
window.AboutDebugging = AboutDebugging; window.AboutDebugging = AboutDebugging;

View file

@ -4,8 +4,9 @@
"use strict"; "use strict";
const { BrowserLoader } = const { BrowserLoader } = ChromeUtils.import(
ChromeUtils.import("resource://devtools/client/shared/browser-loader.js"); "resource://devtools/client/shared/browser-loader.js"
);
const { require } = BrowserLoader({ const { require } = BrowserLoader({
baseURI: "resource://devtools/client/aboutdebugging-new/", baseURI: "resource://devtools/client/aboutdebugging-new/",
window, window,

View file

@ -5,13 +5,16 @@
"use strict"; "use strict";
const { AddonManager } = require("resource://gre/modules/AddonManager.jsm"); const { AddonManager } = require("resource://gre/modules/AddonManager.jsm");
const { remoteClientManager } = const {
require("devtools/client/shared/remote-debugging/remote-client-manager"); remoteClientManager,
} = require("devtools/client/shared/remote-debugging/remote-client-manager");
const Services = require("Services"); const Services = require("Services");
const { l10n } = require("../modules/l10n"); const { l10n } = require("../modules/l10n");
const { isSupportedDebugTargetPane } = require("../modules/debug-target-support"); const {
isSupportedDebugTargetPane,
} = require("../modules/debug-target-support");
const { const {
openTemporaryExtension, openTemporaryExtension,
@ -54,14 +57,19 @@ function isCachedActorNeeded(runtime, type, id) {
// older browsers, the id falls back to the actor ID. Check if the target id is a worker // older browsers, the id falls back to the actor ID. Check if the target id is a worker
// actorID (which means getActor() should return an actor with id). // actorID (which means getActor() should return an actor with id).
// Can be removed when Firefox 68 is in Release channel. // Can be removed when Firefox 68 is in Release channel.
return type === DEBUG_TARGETS.WORKER && return (
runtime.runtimeDetails.clientWrapper.client.getActor(id); type === DEBUG_TARGETS.WORKER &&
runtime.runtimeDetails.clientWrapper.client.getActor(id)
);
} }
function getTabForUrl(url) { function getTabForUrl(url) {
for (const navigator of Services.wm.getEnumerator("navigator:browser")) { for (const navigator of Services.wm.getEnumerator("navigator:browser")) {
for (const browser of navigator.gBrowser.browsers) { for (const browser of navigator.gBrowser.browsers) {
if (browser.contentWindow && browser.contentWindow.location.href === url) { if (
browser.contentWindow &&
browser.contentWindow.location.href === url
) {
return navigator.gBrowser.getTabForBrowser(browser); return navigator.gBrowser.getTabForBrowser(browser);
} }
} }
@ -76,7 +84,10 @@ function inspectDebugTarget(type, id) {
id = encodeURIComponent(id); id = encodeURIComponent(id);
let url; let url;
if (runtime.id === RUNTIMES.THIS_FIREFOX && !isCachedActorNeeded(runtime, type, id)) { if (
runtime.id === RUNTIMES.THIS_FIREFOX &&
!isCachedActorNeeded(runtime, type, id)
) {
// Even when debugging on This Firefox we need to re-use the client since the worker // Even when debugging on This Firefox we need to re-use the client since the worker
// actor is cached in the client instance. Instead we should pass an id that does // actor is cached in the client instance. Instead we should pass an id that does
// not depend on the client (such as the worker url). This will be fixed in // not depend on the client (such as the worker url). This will be fixed in
@ -88,7 +99,10 @@ function inspectDebugTarget(type, id) {
// will fail. See Bug 1534201. // will fail. See Bug 1534201.
url = `about:devtools-toolbox?type=${type}&id=${id}`; url = `about:devtools-toolbox?type=${type}&id=${id}`;
} else { } else {
const remoteId = remoteClientManager.getRemoteId(runtime.id, runtime.type); const remoteId = remoteClientManager.getRemoteId(
runtime.id,
runtime.type
);
url = `about:devtools-toolbox?type=${type}&id=${id}&remoteId=${remoteId}`; url = `about:devtools-toolbox?type=${type}&id=${id}&remoteId=${remoteId}`;
} }
@ -101,15 +115,19 @@ function inspectDebugTarget(type, id) {
window.open(url); window.open(url);
} }
dispatch(Actions.recordTelemetryEvent("inspect", { dispatch(
"target_type": type.toUpperCase(), Actions.recordTelemetryEvent("inspect", {
"runtime_type": runtime.type, target_type: type.toUpperCase(),
})); runtime_type: runtime.type,
})
);
}; };
} }
function installTemporaryExtension() { function installTemporaryExtension() {
const message = l10n.getString("about-debugging-tmp-extension-install-message"); const message = l10n.getString(
"about-debugging-tmp-extension-install-message"
);
return async (dispatch, getState) => { return async (dispatch, getState) => {
dispatch({ type: TEMPORARY_EXTENSION_INSTALL_START }); dispatch({ type: TEMPORARY_EXTENSION_INSTALL_START });
const file = await openTemporaryExtension(window, message); const file = await openTemporaryExtension(window, message);
@ -169,9 +187,13 @@ function requestTabs() {
const clientWrapper = getCurrentClient(getState().runtimes); const clientWrapper = getCurrentClient(getState().runtimes);
try { try {
const isSupported = isSupportedDebugTargetPane(runtime.runtimeDetails.info.type, const isSupported = isSupportedDebugTargetPane(
DEBUG_TARGET_PANE.TAB); runtime.runtimeDetails.info.type,
const tabs = isSupported ? (await clientWrapper.listTabs({ favicons: true })) : []; DEBUG_TARGET_PANE.TAB
);
const tabs = isSupported
? await clientWrapper.listTabs({ favicons: true })
: [];
dispatch({ type: REQUEST_TABS_SUCCESS, tabs }); dispatch({ type: REQUEST_TABS_SUCCESS, tabs });
} catch (e) { } catch (e) {
@ -189,8 +211,9 @@ function requestExtensions() {
try { try {
const isIconDataURLRequired = runtime.type !== RUNTIMES.THIS_FIREFOX; const isIconDataURLRequired = runtime.type !== RUNTIMES.THIS_FIREFOX;
const addons = const addons = await clientWrapper.listAddons({
await clientWrapper.listAddons({ iconDataURL: isIconDataURLRequired }); iconDataURL: isIconDataURLRequired,
});
let extensions = addons.filter(a => a.debuggable); let extensions = addons.filter(a => a.debuggable);
// Filter out hidden & system addons unless the dedicated preference is set to true. // Filter out hidden & system addons unless the dedicated preference is set to true.
@ -209,8 +232,12 @@ function requestExtensions() {
}); });
} }
const installedExtensions = extensions.filter(e => !e.temporarilyInstalled); const installedExtensions = extensions.filter(
const temporaryExtensions = extensions.filter(e => e.temporarilyInstalled); e => !e.temporarilyInstalled
);
const temporaryExtensions = extensions.filter(
e => e.temporarilyInstalled
);
dispatch({ dispatch({
type: REQUEST_EXTENSIONS_SUCCESS, type: REQUEST_EXTENSIONS_SUCCESS,

View file

@ -20,8 +20,9 @@ const {
isSupportedDebugTargetPane, isSupportedDebugTargetPane,
} = require("../modules/debug-target-support"); } = require("../modules/debug-target-support");
const { remoteClientManager } = const {
require("devtools/client/shared/remote-debugging/remote-client-manager"); remoteClientManager,
} = require("devtools/client/shared/remote-debugging/remote-client-manager");
const { const {
CONNECT_RUNTIME_CANCEL, CONNECT_RUNTIME_CANCEL,
@ -67,8 +68,8 @@ async function getRuntimeIcon(runtime, channel) {
} }
} }
return (channel === "release" || channel === "beta" || channel === "aurora") return channel === "release" || channel === "beta" || channel === "aurora"
? `chrome://devtools/skin/images/aboutdebugging-firefox-${ channel }.svg` ? `chrome://devtools/skin/images/aboutdebugging-firefox-${channel}.svg`
: "chrome://devtools/skin/images/aboutdebugging-firefox-nightly.svg"; : "chrome://devtools/skin/images/aboutdebugging-firefox-nightly.svg";
} }
@ -92,9 +93,12 @@ function connectRuntime(id) {
// don't have a default value but will be overridden during our tests. // don't have a default value but will be overridden during our tests.
const connectionTimingOutDelay = Services.prefs.getIntPref( const connectionTimingOutDelay = Services.prefs.getIntPref(
"devtools.aboutdebugging.test-connection-timing-out-delay", "devtools.aboutdebugging.test-connection-timing-out-delay",
CONNECTION_TIMING_OUT_DELAY); CONNECTION_TIMING_OUT_DELAY
);
const connectionCancelDelay = Services.prefs.getIntPref( const connectionCancelDelay = Services.prefs.getIntPref(
"devtools.aboutdebugging.test-connection-cancel-delay", CONNECTION_CANCEL_DELAY); "devtools.aboutdebugging.test-connection-cancel-delay",
CONNECTION_CANCEL_DELAY
);
const connectionNotRespondingTimer = setTimeout(() => { const connectionNotRespondingTimer = setTimeout(() => {
// If connecting to the runtime takes time over CONNECTION_TIMING_OUT_DELAY, // If connecting to the runtime takes time over CONNECTION_TIMING_OUT_DELAY,
@ -124,12 +128,18 @@ function connectRuntime(id) {
PERMANENT_PRIVATE_BROWSING, PERMANENT_PRIVATE_BROWSING,
SERVICE_WORKERS_ENABLED, SERVICE_WORKERS_ENABLED,
} = RUNTIME_PREFERENCE; } = RUNTIME_PREFERENCE;
const connectionPromptEnabled = const connectionPromptEnabled = await clientWrapper.getPreference(
await clientWrapper.getPreference(CONNECTION_PROMPT, false); CONNECTION_PROMPT,
const privateBrowsing = false
await clientWrapper.getPreference(PERMANENT_PRIVATE_BROWSING, false); );
const serviceWorkersEnabled = const privateBrowsing = await clientWrapper.getPreference(
await clientWrapper.getPreference(SERVICE_WORKERS_ENABLED, true); PERMANENT_PRIVATE_BROWSING,
false
);
const serviceWorkersEnabled = await clientWrapper.getPreference(
SERVICE_WORKERS_ENABLED,
true
);
const serviceWorkersAvailable = serviceWorkersEnabled && !privateBrowsing; const serviceWorkersAvailable = serviceWorkersEnabled && !privateBrowsing;
// Fenix specific workarounds are needed until we can get proper server side APIs // Fenix specific workarounds are needed until we can get proper server side APIs
@ -138,12 +148,15 @@ function connectRuntime(id) {
// For Fenix runtimes, the ADB runtime name is more accurate than the one returned // For Fenix runtimes, the ADB runtime name is more accurate than the one returned
// by the Device actor. // by the Device actor.
const runtimeName = runtime.isFenix ? runtime.name : deviceDescription.name; const runtimeName = runtime.isFenix
? runtime.name
: deviceDescription.name;
// For Fenix runtimes, the version we should display is the application version // For Fenix runtimes, the version we should display is the application version
// retrieved from ADB, and not the Gecko version returned by the Device actor. // retrieved from ADB, and not the Gecko version returned by the Device actor.
const version = runtime.isFenix ? const version = runtime.isFenix
runtime.extra.adbPackageVersion : deviceDescription.version; ? runtime.extra.adbPackageVersion
: deviceDescription.version;
const runtimeDetails = { const runtimeDetails = {
clientWrapper, clientWrapper,
@ -203,7 +216,10 @@ function createThisFirefoxRuntime() {
name: l10n.getString("about-debugging-this-firefox-runtime-name"), name: l10n.getString("about-debugging-this-firefox-runtime-name"),
type: RUNTIMES.THIS_FIREFOX, type: RUNTIMES.THIS_FIREFOX,
}; };
dispatch({ type: THIS_FIREFOX_RUNTIME_CREATED, runtime: thisFirefoxRuntime }); dispatch({
type: THIS_FIREFOX_RUNTIME_CREATED,
runtime: thisFirefoxRuntime,
});
}; };
} }
@ -224,7 +240,9 @@ function disconnectRuntime(id, shouldRedirect = false) {
} }
await clientWrapper.close(); await clientWrapper.close();
if (shouldRedirect) { if (shouldRedirect) {
await dispatch(Actions.selectPage(PAGE_TYPES.RUNTIME, RUNTIMES.THIS_FIREFOX)); await dispatch(
Actions.selectPage(PAGE_TYPES.RUNTIME, RUNTIMES.THIS_FIREFOX)
);
} }
dispatch({ dispatch({
@ -247,13 +265,21 @@ function updateConnectionPromptSetting(connectionPromptEnabled) {
const runtime = getCurrentRuntime(getState().runtimes); const runtime = getCurrentRuntime(getState().runtimes);
const { clientWrapper } = runtime.runtimeDetails; const { clientWrapper } = runtime.runtimeDetails;
const promptPrefName = RUNTIME_PREFERENCE.CONNECTION_PROMPT; const promptPrefName = RUNTIME_PREFERENCE.CONNECTION_PROMPT;
await clientWrapper.setPreference(promptPrefName, connectionPromptEnabled); await clientWrapper.setPreference(
promptPrefName,
connectionPromptEnabled
);
// Re-get actual value from the runtime. // Re-get actual value from the runtime.
connectionPromptEnabled = connectionPromptEnabled = await clientWrapper.getPreference(
await clientWrapper.getPreference(promptPrefName, connectionPromptEnabled); promptPrefName,
connectionPromptEnabled
);
dispatch({ type: UPDATE_CONNECTION_PROMPT_SETTING_SUCCESS, dispatch({
runtime, connectionPromptEnabled }); type: UPDATE_CONNECTION_PROMPT_SETTING_SUCCESS,
runtime,
connectionPromptEnabled,
});
} catch (e) { } catch (e) {
dispatch({ type: UPDATE_CONNECTION_PROMPT_SETTING_FAILURE, error: e }); dispatch({ type: UPDATE_CONNECTION_PROMPT_SETTING_FAILURE, error: e });
} }
@ -269,7 +295,11 @@ function updateMultiE10s() {
// Re-get actual value from the runtime. // Re-get actual value from the runtime.
const { isMultiE10s } = await clientWrapper.getDeviceDescription(); const { isMultiE10s } = await clientWrapper.getDeviceDescription();
dispatch({ type: UPDATE_RUNTIME_MULTIE10S_SUCCESS, runtime, isMultiE10s }); dispatch({
type: UPDATE_RUNTIME_MULTIE10S_SUCCESS,
runtime,
isMultiE10s,
});
} catch (e) { } catch (e) {
dispatch({ type: UPDATE_RUNTIME_MULTIE10S_FAILURE, error: e }); dispatch({ type: UPDATE_RUNTIME_MULTIE10S_FAILURE, error: e });
} }
@ -294,8 +324,12 @@ function watchRuntime(id) {
dispatch(Actions.requestTabs()); dispatch(Actions.requestTabs());
dispatch(Actions.requestWorkers()); dispatch(Actions.requestWorkers());
if (isSupportedDebugTargetPane(runtime.runtimeDetails.info.type, if (
DEBUG_TARGET_PANE.PROCESSES)) { isSupportedDebugTargetPane(
runtime.runtimeDetails.info.type,
DEBUG_TARGET_PANE.PROCESSES
)
) {
dispatch(Actions.requestProcesses()); dispatch(Actions.requestProcesses());
} }
} catch (e) { } catch (e) {
@ -325,7 +359,7 @@ function unwatchRuntime(id) {
function updateNetworkRuntimes(locations) { function updateNetworkRuntimes(locations) {
const runtimes = locations.map(location => { const runtimes = locations.map(location => {
const [ host, port ] = location.split(":"); const [host, port] = location.split(":");
return { return {
id: location, id: location,
extra: { extra: {
@ -381,8 +415,8 @@ function updateUSBRuntimes(adbRuntimes) {
*/ */
function _isRuntimeValid(runtime, runtimes) { function _isRuntimeValid(runtime, runtimes) {
const isRuntimeAvailable = runtimes.some(r => r.id === runtime.id); const isRuntimeAvailable = runtimes.some(r => r.id === runtime.id);
const isConnectionValid = runtime.runtimeDetails && const isConnectionValid =
!runtime.runtimeDetails.clientWrapper.isClosed(); runtime.runtimeDetails && !runtime.runtimeDetails.clientWrapper.isClosed();
return isRuntimeAvailable && isConnectionValid; return isRuntimeAvailable && isConnectionValid;
} }
@ -392,8 +426,11 @@ function updateRemoteRuntimes(runtimes, type) {
// Check if the updated remote runtimes should trigger a navigation out of the current // Check if the updated remote runtimes should trigger a navigation out of the current
// runtime page. // runtime page.
if (currentRuntime && currentRuntime.type === type && if (
!_isRuntimeValid(currentRuntime, runtimes)) { currentRuntime &&
currentRuntime.type === type &&
!_isRuntimeValid(currentRuntime, runtimes)
) {
// Since current remote runtime is invalid, move to this firefox page. // Since current remote runtime is invalid, move to this firefox page.
// This case is considered as followings and so on: // This case is considered as followings and so on:
// * Remove ADB addon // * Remove ADB addon
@ -403,7 +440,9 @@ function updateRemoteRuntimes(runtimes, type) {
// Current runtime can not be retrieved after REMOTE_RUNTIMES_UPDATED action, since // Current runtime can not be retrieved after REMOTE_RUNTIMES_UPDATED action, since
// that updates runtime state. So, before that we fire selectPage action to execute // that updates runtime state. So, before that we fire selectPage action to execute
// `unwatchRuntime` correctly. // `unwatchRuntime` correctly.
await dispatch(Actions.selectPage(PAGE_TYPES.RUNTIME, RUNTIMES.THIS_FIREFOX)); await dispatch(
Actions.selectPage(PAGE_TYPES.RUNTIME, RUNTIMES.THIS_FIREFOX)
);
} }
// For existing runtimes, transfer all properties that are not available in the // For existing runtimes, transfer all properties that are not available in the
@ -416,16 +455,25 @@ function updateRemoteRuntimes(runtimes, type) {
// - isConnectionTimeout (set by about:debugging if connection was timeout) // - isConnectionTimeout (set by about:debugging if connection was timeout)
runtimes.forEach(runtime => { runtimes.forEach(runtime => {
const existingRuntime = findRuntimeById(runtime.id, getState().runtimes); const existingRuntime = findRuntimeById(runtime.id, getState().runtimes);
const isConnectionValid = existingRuntime && existingRuntime.runtimeDetails && const isConnectionValid =
!existingRuntime.runtimeDetails.clientWrapper.isClosed(); existingRuntime &&
runtime.runtimeDetails = isConnectionValid ? existingRuntime.runtimeDetails : null; existingRuntime.runtimeDetails &&
runtime.isConnecting = existingRuntime ? existingRuntime.isConnecting : false; !existingRuntime.runtimeDetails.clientWrapper.isClosed();
runtime.isConnectionFailed = runtime.runtimeDetails = isConnectionValid
existingRuntime ? existingRuntime.isConnectionFailed : false; ? existingRuntime.runtimeDetails
runtime.isConnectionNotResponding = : null;
existingRuntime ? existingRuntime.isConnectionNotResponding : false; runtime.isConnecting = existingRuntime
runtime.isConnectionTimeout = ? existingRuntime.isConnecting
existingRuntime ? existingRuntime.isConnectionTimeout : false; : false;
runtime.isConnectionFailed = existingRuntime
? existingRuntime.isConnectionFailed
: false;
runtime.isConnectionNotResponding = existingRuntime
? existingRuntime.isConnectionNotResponding
: false;
runtime.isConnectionTimeout = existingRuntime
? existingRuntime.isConnectionTimeout
: false;
}); });
const existingRuntimes = getAllRuntimes(getState().runtimes); const existingRuntimes = getAllRuntimes(getState().runtimes);
@ -449,7 +497,10 @@ function updateRemoteRuntimes(runtimes, type) {
// Reconnect clients already available in the RemoteClientManager. // Reconnect clients already available in the RemoteClientManager.
const isConnected = !!runtime.runtimeDetails; const isConnected = !!runtime.runtimeDetails;
const hasConnectedClient = remoteClientManager.hasClient(runtime.id, runtime.type); const hasConnectedClient = remoteClientManager.hasClient(
runtime.id,
runtime.type
);
if (!isConnected && hasConnectedClient) { if (!isConnected && hasConnectedClient) {
await dispatch(connectRuntime(runtime.id)); await dispatch(connectRuntime(runtime.id));
} }
@ -465,7 +516,9 @@ function updateRemoteRuntimes(runtimes, type) {
function removeRuntimeListeners() { function removeRuntimeListeners() {
return (dispatch, getState) => { return (dispatch, getState) => {
const allRuntimes = getAllRuntimes(getState().runtimes); const allRuntimes = getAllRuntimes(getState().runtimes);
const remoteRuntimes = allRuntimes.filter(r => r.type !== RUNTIMES.THIS_FIREFOX); const remoteRuntimes = allRuntimes.filter(
r => r.type !== RUNTIMES.THIS_FIREFOX
);
for (const runtime of remoteRuntimes) { for (const runtime of remoteRuntimes) {
if (runtime.runtimeDetails) { if (runtime.runtimeDetails) {
const { clientWrapper } = runtime.runtimeDetails; const { clientWrapper } = runtime.runtimeDetails;

View file

@ -4,9 +4,7 @@
"use strict"; "use strict";
const { const { TELEMETRY_RECORD } = require("../constants");
TELEMETRY_RECORD,
} = require("../constants");
/** /**
* If a given event cannot be mapped to an existing action, use this action that will only * If a given event cannot be mapped to an existing action, use this action that will only

View file

@ -5,16 +5,25 @@
"use strict"; "use strict";
const { connect } = require("devtools/client/shared/vendor/react-redux"); const { connect } = require("devtools/client/shared/vendor/react-redux");
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const {
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const FluentReact = require("devtools/client/shared/vendor/fluent-react"); const FluentReact = require("devtools/client/shared/vendor/fluent-react");
const Localized = createFactory(FluentReact.Localized); const Localized = createFactory(FluentReact.Localized);
const Route = createFactory(require("devtools/client/shared/vendor/react-router-dom").Route); const Route = createFactory(
const Switch = createFactory(require("devtools/client/shared/vendor/react-router-dom").Switch); require("devtools/client/shared/vendor/react-router-dom").Route
const Redirect = createFactory(require("devtools/client/shared/vendor/react-router-dom").Redirect); );
const Switch = createFactory(
require("devtools/client/shared/vendor/react-router-dom").Switch
);
const Redirect = createFactory(
require("devtools/client/shared/vendor/react-router-dom").Redirect
);
const Types = require("../types/index"); const Types = require("../types/index");
const { PAGE_TYPES, RUNTIMES } = require("../constants"); const { PAGE_TYPES, RUNTIMES } = require("../constants");
@ -50,19 +59,18 @@ class App extends PureComponent {
updateTitle() { updateTitle() {
const { getString, selectedPage, selectedRuntimeId } = this.props; const { getString, selectedPage, selectedRuntimeId } = this.props;
const pageTitle = selectedPage === PAGE_TYPES.RUNTIME ? const pageTitle =
getString("about-debugging-page-title-runtime-page", { selectedRuntimeId }) : selectedPage === PAGE_TYPES.RUNTIME
getString("about-debugging-page-title-setup-page"); ? getString("about-debugging-page-title-runtime-page", {
selectedRuntimeId,
})
: getString("about-debugging-page-title-setup-page");
document.title = pageTitle; document.title = pageTitle;
} }
renderConnect() { renderConnect() {
const { const { adbAddonStatus, dispatch, networkLocations } = this.props;
adbAddonStatus,
dispatch,
networkLocations,
} = this.props;
return ConnectPage({ return ConnectPage({
adbAddonStatus, adbAddonStatus,
@ -125,10 +133,14 @@ class App extends PureComponent {
// about:debugging#workers, about:debugging#addons and about:debugging#tabs. // about:debugging#workers, about:debugging#addons and about:debugging#tabs.
// Such links can still be found in external documentation pages. // Such links can still be found in external documentation pages.
// We redirect to This Firefox rather than the Setup Page here. // We redirect to This Firefox rather than the Setup Page here.
if (pathname === "/workers" || pathname === "/addons" || pathname === "/tabs") { if (
return Redirect({ to: `/runtime/${RUNTIMES.THIS_FIREFOX}`}); pathname === "/workers" ||
pathname === "/addons" ||
pathname === "/tabs"
) {
return Redirect({ to: `/runtime/${RUNTIMES.THIS_FIREFOX}` });
} }
return Redirect({ to: "/setup"}); return Redirect({ to: "/setup" });
}, },
}) })
); );
@ -147,7 +159,7 @@ class App extends PureComponent {
} = this.props; } = this.props;
return Localized( return Localized(
{ }, {},
dom.div( dom.div(
{ className: "app" }, { className: "app" },
Sidebar({ Sidebar({
@ -184,6 +196,9 @@ const mapDispatchToProps = dispatch => ({
dispatch, dispatch,
}); });
module.exports = FluentReact module.exports = FluentReact.withLocalization(
.withLocalization( connect(
connect(mapStateToProps, mapDispatchToProps)(App)); mapStateToProps,
mapDispatchToProps
)(App)
);

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const {
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const FluentReact = require("devtools/client/shared/vendor/fluent-react"); const FluentReact = require("devtools/client/shared/vendor/fluent-react");
@ -13,9 +16,12 @@ const Localized = createFactory(FluentReact.Localized);
const Message = createFactory(require("./shared/Message")); const Message = createFactory(require("./shared/Message"));
const { MESSAGE_LEVEL } = require("../constants"); const { MESSAGE_LEVEL } = require("../constants");
const { COMPATIBILITY_STATUS } = require("devtools/client/shared/remote-debugging/version-checker"); const {
COMPATIBILITY_STATUS,
} = require("devtools/client/shared/remote-debugging/version-checker");
const TROUBLESHOOTING_URL = "https://developer.mozilla.org/docs/Tools/about:debugging#Troubleshooting"; const TROUBLESHOOTING_URL =
"https://developer.mozilla.org/docs/Tools/about:debugging#Troubleshooting";
const Types = require("../types/index"); const Types = require("../types/index");
@ -27,8 +33,14 @@ class CompatibilityWarning extends PureComponent {
} }
render() { render() {
const { localID, localVersion, minVersion, runtimeID, runtimeVersion, status } = const {
this.props.compatibilityReport; localID,
localVersion,
minVersion,
runtimeID,
runtimeVersion,
status,
} = this.props.compatibilityReport;
if (status === COMPATIBILITY_STATUS.COMPATIBLE) { if (status === COMPATIBILITY_STATUS.COMPATIBLE) {
return null; return null;
@ -72,8 +84,8 @@ class CompatibilityWarning extends PureComponent {
{ {
className: `qa-compatibility-warning ${statusClassName}`, className: `qa-compatibility-warning ${statusClassName}`,
}, },
localizationId, localizationId
), )
) )
); );
} }

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const {
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
@ -31,8 +34,8 @@ class ConnectionPromptSetting extends PureComponent {
const { className, connectionPromptEnabled } = this.props; const { className, connectionPromptEnabled } = this.props;
const localizedState = connectionPromptEnabled const localizedState = connectionPromptEnabled
? "about-debugging-connection-prompt-disable-button" ? "about-debugging-connection-prompt-disable-button"
: "about-debugging-connection-prompt-enable-button"; : "about-debugging-connection-prompt-enable-button";
return Localized( return Localized(
{ {
@ -40,7 +43,7 @@ class ConnectionPromptSetting extends PureComponent {
}, },
dom.button( dom.button(
{ {
className: `${ className } default-button qa-connection-prompt-toggle-button`, className: `${className} default-button qa-connection-prompt-toggle-button`,
onClick: () => this.onToggleClick(), onClick: () => this.onToggleClick(),
}, },
localizedState localizedState

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const {
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
@ -54,7 +57,7 @@ class ProfilerDialog extends PureComponent {
{ {
className: "profiler-dialog__header__title", className: "profiler-dialog__header__title",
}, },
"about-debugging-profiler-dialog-title2", "about-debugging-profiler-dialog-title2"
) )
), ),
dom.button( dom.button(
@ -62,17 +65,15 @@ class ProfilerDialog extends PureComponent {
className: "ghost-button qa-profiler-dialog-close", className: "ghost-button qa-profiler-dialog-close",
onClick: () => this.hide(), onClick: () => this.hide(),
}, },
dom.img( dom.img({
{ src: "chrome://devtools/skin/images/close.svg",
src: "chrome://devtools/skin/images/close.svg", })
}
)
) )
), ),
dom.iframe({ dom.iframe({
className: "profiler-dialog__frame", className: "profiler-dialog__frame",
src: clientWrapper.getPerformancePanelUrl(), src: clientWrapper.getPerformancePanelUrl(),
onLoad: (e) => { onLoad: e => {
clientWrapper.loadPerformanceProfiler(e.target.contentWindow); clientWrapper.loadPerformanceProfiler(e.target.contentWindow);
}, },
}) })

View file

@ -4,14 +4,19 @@
"use strict"; "use strict";
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const {
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const FluentReact = require("devtools/client/shared/vendor/fluent-react"); const FluentReact = require("devtools/client/shared/vendor/fluent-react");
const Localized = createFactory(FluentReact.Localized); const Localized = createFactory(FluentReact.Localized);
const ConnectionPromptSetting = createFactory(require("./ConnectionPromptSetting")); const ConnectionPromptSetting = createFactory(
require("./ConnectionPromptSetting")
);
const Actions = require("../actions/index"); const Actions = require("../actions/index");
const { RUNTIMES } = require("../constants"); const { RUNTIMES } = require("../constants");
@ -35,30 +40,30 @@ class RuntimeActions extends PureComponent {
const { connectionPromptEnabled } = runtimeDetails; const { connectionPromptEnabled } = runtimeDetails;
// do not show the connection prompt setting in 'This Firefox' // do not show the connection prompt setting in 'This Firefox'
return runtimeId !== RUNTIMES.THIS_FIREFOX return runtimeId !== RUNTIMES.THIS_FIREFOX
? ConnectionPromptSetting({ ? ConnectionPromptSetting({
connectionPromptEnabled, connectionPromptEnabled,
dispatch, dispatch,
}) })
: null; : null;
} }
renderProfileButton() { renderProfileButton() {
const { runtimeId } = this.props; const { runtimeId } = this.props;
return runtimeId !== RUNTIMES.THIS_FIREFOX return runtimeId !== RUNTIMES.THIS_FIREFOX
? Localized( ? Localized(
{ {
id: "about-debugging-runtime-profile-button2", id: "about-debugging-runtime-profile-button2",
}, },
dom.button( dom.button(
{ {
className: "default-button qa-profile-runtime-button", className: "default-button qa-profile-runtime-button",
onClick: () => this.onProfilerButtonClick(), onClick: () => this.onProfilerButtonClick(),
}, },
"about-debugging-runtime-profile-button2" "about-debugging-runtime-profile-button2"
), )
) )
: null; : null;
} }
render() { render() {
@ -67,7 +72,7 @@ class RuntimeActions extends PureComponent {
className: "runtime-actions__toolbar", className: "runtime-actions__toolbar",
}, },
this.renderProfileButton(), this.renderProfileButton(),
this.renderConnectionPromptSetting(), this.renderConnectionPromptSetting()
); );
} }
} }

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const {
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
@ -35,12 +38,10 @@ class RuntimeInfo extends PureComponent {
{ {
className: "main-heading runtime-info", className: "main-heading runtime-info",
}, },
dom.img( dom.img({
{ className: "main-heading__icon runtime-info__icon qa-runtime-icon",
className: "main-heading__icon runtime-info__icon qa-runtime-icon", src: icon,
src: icon, }),
}
),
Localized( Localized(
{ {
id: "about-debugging-runtime-name", id: "about-debugging-runtime-name",
@ -51,31 +52,34 @@ class RuntimeInfo extends PureComponent {
{ {
className: "qa-runtime-name runtime-info__title", className: "qa-runtime-name runtime-info__title",
}, },
`${ name } (${ version })` `${name} (${version})`
) )
), ),
deviceName ? deviceName
dom.label( ? dom.label(
{
className: "main-heading-subtitle runtime-info__subtitle",
},
deviceName
) : null,
runtimeId !== RUNTIMES.THIS_FIREFOX ?
Localized(
{
id: "about-debugging-runtime-disconnect-button",
},
dom.button(
{ {
className: "default-button runtime-info__action qa-runtime-info__action", className: "main-heading-subtitle runtime-info__subtitle",
onClick() {
dispatch(Actions.disconnectRuntime(runtimeId, true));
},
}, },
"Disconnect" deviceName
) )
) : null, : null,
runtimeId !== RUNTIMES.THIS_FIREFOX
? Localized(
{
id: "about-debugging-runtime-disconnect-button",
},
dom.button(
{
className:
"default-button runtime-info__action qa-runtime-info__action",
onClick() {
dispatch(Actions.disconnectRuntime(runtimeId, true));
},
},
"Disconnect"
)
)
: null
); );
} }
} }

View file

@ -5,7 +5,10 @@
"use strict"; "use strict";
const { connect } = require("devtools/client/shared/vendor/react-redux"); const { connect } = require("devtools/client/shared/vendor/react-redux");
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const {
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
@ -19,25 +22,40 @@ const InspectAction = createFactory(require("./debugtarget/InspectAction"));
const ProfilerDialog = createFactory(require("./ProfilerDialog")); const ProfilerDialog = createFactory(require("./ProfilerDialog"));
const RuntimeActions = createFactory(require("./RuntimeActions")); const RuntimeActions = createFactory(require("./RuntimeActions"));
const RuntimeInfo = createFactory(require("./RuntimeInfo")); const RuntimeInfo = createFactory(require("./RuntimeInfo"));
const ServiceWorkerAction = createFactory(require("./debugtarget/ServiceWorkerAction")); const ServiceWorkerAction = createFactory(
const ServiceWorkerAdditionalActions = require("./debugtarget/ServiceWorkerAction")
createFactory(require("./debugtarget/ServiceWorkerAdditionalActions")); );
const ServiceWorkerAdditionalActions = createFactory(
require("./debugtarget/ServiceWorkerAdditionalActions")
);
const ServiceWorkersWarning = createFactory(require("./ServiceWorkersWarning")); const ServiceWorkersWarning = createFactory(require("./ServiceWorkersWarning"));
const ProcessDetail = createFactory(require("./debugtarget/ProcessDetail")); const ProcessDetail = createFactory(require("./debugtarget/ProcessDetail"));
const TabDetail = createFactory(require("./debugtarget/TabDetail")); const TabDetail = createFactory(require("./debugtarget/TabDetail"));
const TemporaryExtensionAdditionalActions = const TemporaryExtensionAdditionalActions = createFactory(
createFactory(require("./debugtarget/TemporaryExtensionAdditionalActions")); require("./debugtarget/TemporaryExtensionAdditionalActions")
const TemporaryExtensionDetail = createFactory(require("./debugtarget/TemporaryExtensionDetail")); );
const TemporaryExtensionInstallSection = const TemporaryExtensionDetail = createFactory(
createFactory(require("./debugtarget/TemporaryExtensionInstallSection")); require("./debugtarget/TemporaryExtensionDetail")
);
const TemporaryExtensionInstallSection = createFactory(
require("./debugtarget/TemporaryExtensionInstallSection")
);
const WorkerDetail = createFactory(require("./debugtarget/WorkerDetail")); const WorkerDetail = createFactory(require("./debugtarget/WorkerDetail"));
const Actions = require("../actions/index"); const Actions = require("../actions/index");
const { DEBUG_TARGETS, DEBUG_TARGET_PANE, PAGE_TYPES } = require("../constants"); const {
DEBUG_TARGETS,
DEBUG_TARGET_PANE,
PAGE_TYPES,
} = require("../constants");
const Types = require("../types/index"); const Types = require("../types/index");
const { getCurrentRuntimeDetails } = require("../modules/runtimes-state-helper"); const {
const { isSupportedDebugTargetPane } = require("../modules/debug-target-support"); getCurrentRuntimeDetails,
} = require("../modules/runtimes-state-helper");
const {
isSupportedDebugTargetPane,
} = require("../modules/debug-target-support");
class RuntimePage extends PureComponent { class RuntimePage extends PureComponent {
static get propTypes() { static get propTypes() {
@ -77,12 +95,20 @@ class RuntimePage extends PureComponent {
return "chrome://devtools/skin/images/debugging-workers.svg"; return "chrome://devtools/skin/images/debugging-workers.svg";
} }
throw new Error(`Unsupported type [${ type }]`); throw new Error(`Unsupported type [${type}]`);
} }
renderDebugTargetPane(name, icon, targets, children, actionComponent, renderDebugTargetPane(
additionalActionsComponent, detailComponent, name,
paneKey, localizationId) { icon,
targets,
children,
actionComponent,
additionalActionsComponent,
detailComponent,
paneKey,
localizationId
) {
const { collapsibilities, dispatch, runtimeDetails } = this.props; const { collapsibilities, dispatch, runtimeDetails } = this.props;
if (!isSupportedDebugTargetPane(runtimeDetails.info.type, paneKey)) { if (!isSupportedDebugTargetPane(runtimeDetails.info.type, paneKey)) {
@ -112,13 +138,20 @@ class RuntimePage extends PureComponent {
} }
renderTemporaryExtensionInstallSection() { renderTemporaryExtensionInstallSection() {
if (!isSupportedDebugTargetPane(this.props.runtimeDetails.info.type, if (
DEBUG_TARGET_PANE.TEMPORARY_EXTENSION)) { !isSupportedDebugTargetPane(
this.props.runtimeDetails.info.type,
DEBUG_TARGET_PANE.TEMPORARY_EXTENSION
)
) {
return null; return null;
} }
const { dispatch, temporaryInstallError } = this.props; const { dispatch, temporaryInstallError } = this.props;
return TemporaryExtensionInstallSection({ dispatch, temporaryInstallError }); return TemporaryExtensionInstallSection({
dispatch,
temporaryInstallError,
});
} }
render() { render() {
@ -152,71 +185,85 @@ class RuntimePage extends PureComponent {
RuntimeActions({ dispatch, runtimeId, runtimeDetails }), RuntimeActions({ dispatch, runtimeId, runtimeDetails }),
runtimeDetails.serviceWorkersAvailable ? null : ServiceWorkersWarning(), runtimeDetails.serviceWorkersAvailable ? null : ServiceWorkersWarning(),
CompatibilityWarning({ compatibilityReport }), CompatibilityWarning({ compatibilityReport }),
this.renderDebugTargetPane("Tabs", this.renderDebugTargetPane(
this.getIconByType(DEBUG_TARGETS.TAB), "Tabs",
tabs, this.getIconByType(DEBUG_TARGETS.TAB),
null, tabs,
InspectAction, null,
null, InspectAction,
TabDetail, null,
DEBUG_TARGET_PANE.TAB, TabDetail,
"about-debugging-runtime-tabs"), DEBUG_TARGET_PANE.TAB,
this.renderDebugTargetPane("Temporary Extensions", "about-debugging-runtime-tabs"
this.getIconByType(DEBUG_TARGETS.EXTENSION), ),
temporaryExtensions, this.renderDebugTargetPane(
this.renderTemporaryExtensionInstallSection(), "Temporary Extensions",
InspectAction, this.getIconByType(DEBUG_TARGETS.EXTENSION),
TemporaryExtensionAdditionalActions, temporaryExtensions,
TemporaryExtensionDetail, this.renderTemporaryExtensionInstallSection(),
DEBUG_TARGET_PANE.TEMPORARY_EXTENSION, InspectAction,
"about-debugging-runtime-temporary-extensions"), TemporaryExtensionAdditionalActions,
this.renderDebugTargetPane("Extensions", TemporaryExtensionDetail,
this.getIconByType(DEBUG_TARGETS.EXTENSION), DEBUG_TARGET_PANE.TEMPORARY_EXTENSION,
installedExtensions, "about-debugging-runtime-temporary-extensions"
null, ),
InspectAction, this.renderDebugTargetPane(
null, "Extensions",
ExtensionDetail, this.getIconByType(DEBUG_TARGETS.EXTENSION),
DEBUG_TARGET_PANE.INSTALLED_EXTENSION, installedExtensions,
"about-debugging-runtime-extensions"), null,
this.renderDebugTargetPane("Service Workers", InspectAction,
this.getIconByType(DEBUG_TARGETS.WORKER), null,
serviceWorkers, ExtensionDetail,
null, DEBUG_TARGET_PANE.INSTALLED_EXTENSION,
ServiceWorkerAction, "about-debugging-runtime-extensions"
ServiceWorkerAdditionalActions, ),
WorkerDetail, this.renderDebugTargetPane(
DEBUG_TARGET_PANE.SERVICE_WORKER, "Service Workers",
"about-debugging-runtime-service-workers"), this.getIconByType(DEBUG_TARGETS.WORKER),
this.renderDebugTargetPane("Shared Workers", serviceWorkers,
this.getIconByType(DEBUG_TARGETS.WORKER), null,
sharedWorkers, ServiceWorkerAction,
null, ServiceWorkerAdditionalActions,
InspectAction, WorkerDetail,
null, DEBUG_TARGET_PANE.SERVICE_WORKER,
WorkerDetail, "about-debugging-runtime-service-workers"
DEBUG_TARGET_PANE.SHARED_WORKER, ),
"about-debugging-runtime-shared-workers"), this.renderDebugTargetPane(
this.renderDebugTargetPane("Other Workers", "Shared Workers",
this.getIconByType(DEBUG_TARGETS.WORKER), this.getIconByType(DEBUG_TARGETS.WORKER),
otherWorkers, sharedWorkers,
null, null,
InspectAction, InspectAction,
null, null,
WorkerDetail, WorkerDetail,
DEBUG_TARGET_PANE.OTHER_WORKER, DEBUG_TARGET_PANE.SHARED_WORKER,
"about-debugging-runtime-other-workers"), "about-debugging-runtime-shared-workers"
this.renderDebugTargetPane("Processes", ),
this.getIconByType(DEBUG_TARGETS.PROCESS), this.renderDebugTargetPane(
processes, "Other Workers",
null, this.getIconByType(DEBUG_TARGETS.WORKER),
InspectAction, otherWorkers,
null, null,
ProcessDetail, InspectAction,
DEBUG_TARGET_PANE.PROCESSES, null,
"about-debugging-runtime-processes"), WorkerDetail,
DEBUG_TARGET_PANE.OTHER_WORKER,
"about-debugging-runtime-other-workers"
),
this.renderDebugTargetPane(
"Processes",
this.getIconByType(DEBUG_TARGETS.PROCESS),
processes,
null,
InspectAction,
null,
ProcessDetail,
DEBUG_TARGET_PANE.PROCESSES,
"about-debugging-runtime-processes"
),
showProfilerDialog ? ProfilerDialog({ dispatch, runtimeDetails }) : null, showProfilerDialog ? ProfilerDialog({ dispatch, runtimeDetails }) : null
); );
} }
} }

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const {
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const FluentReact = require("devtools/client/shared/vendor/fluent-react"); const FluentReact = require("devtools/client/shared/vendor/fluent-react");
@ -13,7 +16,8 @@ const Localized = createFactory(FluentReact.Localized);
const Message = createFactory(require("./shared/Message")); const Message = createFactory(require("./shared/Message"));
const { MESSAGE_LEVEL } = require("../constants"); const { MESSAGE_LEVEL } = require("../constants");
const DOC_URL = "https://developer.mozilla.org/docs/Tools/about:debugging#Service_workers_not_compatible"; const DOC_URL =
"https://developer.mozilla.org/docs/Tools/about:debugging#Service_workers_not_compatible";
class ServiceWorkersWarning extends PureComponent { class ServiceWorkersWarning extends PureComponent {
render() { render() {
@ -34,8 +38,8 @@ class ServiceWorkersWarning extends PureComponent {
{ {
className: "qa-service-workers-warning", className: "qa-service-workers-warning",
}, },
"about-debugging-runtime-service-workers-not-compatible", "about-debugging-runtime-service-workers-not-compatible"
), )
) )
); );
} }

View file

@ -4,22 +4,30 @@
"use strict"; "use strict";
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const {
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const FluentReact = require("devtools/client/shared/vendor/fluent-react"); const FluentReact = require("devtools/client/shared/vendor/fluent-react");
const Localized = createFactory(FluentReact.Localized); const Localized = createFactory(FluentReact.Localized);
const { const { USB_STATES } = require("../../constants");
USB_STATES,
} = require("../../constants");
const Actions = require("../../actions/index"); const Actions = require("../../actions/index");
loader.lazyRequireGetter(this, "ADB_ADDON_STATES", "devtools/shared/adb/adb-addon", true); loader.lazyRequireGetter(
this,
"ADB_ADDON_STATES",
"devtools/shared/adb/adb-addon",
true
);
const Link = createFactory(require("devtools/client/shared/vendor/react-router-dom").Link); const Link = createFactory(
require("devtools/client/shared/vendor/react-router-dom").Link
);
const ConnectSection = createFactory(require("./ConnectSection")); const ConnectSection = createFactory(require("./ConnectSection"));
const ConnectSteps = createFactory(require("./ConnectSteps")); const ConnectSteps = createFactory(require("./ConnectSteps"));
const NetworkLocationsForm = createFactory(require("./NetworkLocationsForm")); const NetworkLocationsForm = createFactory(require("./NetworkLocationsForm"));
@ -28,8 +36,10 @@ const NetworkLocationsList = createFactory(require("./NetworkLocationsList"));
const { PAGE_TYPES, RUNTIMES } = require("../../constants"); const { PAGE_TYPES, RUNTIMES } = require("../../constants");
const Types = require("../../types/index"); const Types = require("../../types/index");
const USB_ICON_SRC = "chrome://devtools/skin/images/aboutdebugging-usb-icon.svg"; const USB_ICON_SRC =
const GLOBE_ICON_SRC = "chrome://devtools/skin/images/aboutdebugging-globe-icon.svg"; "chrome://devtools/skin/images/aboutdebugging-usb-icon.svg";
const GLOBE_ICON_SRC =
"chrome://devtools/skin/images/aboutdebugging-globe-icon.svg";
const TROUBLESHOOT_USB_URL = const TROUBLESHOOT_USB_URL =
"https://developer.mozilla.org/docs/Tools/Remote_Debugging/Debugging_over_USB"; "https://developer.mozilla.org/docs/Tools/Remote_Debugging/Debugging_over_USB";
@ -87,8 +97,8 @@ class ConnectPage extends PureComponent {
{ {
className: "connect-page__usb-section__heading__status", className: "connect-page__usb-section__heading__status",
}, },
statusTextId, statusTextId
), )
); );
} }
@ -138,45 +148,45 @@ class ConnectPage extends PureComponent {
{ {
className: "connect-page__usb-section__heading__title", className: "connect-page__usb-section__heading__title",
}, },
"USB", "USB"
), )
), ),
this.renderUsbStatus(), this.renderUsbStatus(),
this.renderUsbToggleButton(), this.renderUsbToggleButton()
), ),
}, },
isAddonInstalled isAddonInstalled
? ConnectSteps( ? ConnectSteps({
{
steps: [ steps: [
{ {
localizationId: "about-debugging-setup-usb-step-enable-dev-menu2", localizationId:
"about-debugging-setup-usb-step-enable-dev-menu2",
}, },
{ {
localizationId: "about-debugging-setup-usb-step-enable-debug2", localizationId: "about-debugging-setup-usb-step-enable-debug2",
}, },
{ {
localizationId: "about-debugging-setup-usb-step-enable-debug-firefox2", localizationId:
"about-debugging-setup-usb-step-enable-debug-firefox2",
}, },
{ {
localizationId: "about-debugging-setup-usb-step-plug-device", localizationId: "about-debugging-setup-usb-step-plug-device",
}, },
], ],
} })
)
: Localized( : Localized(
{
id: "about-debugging-setup-usb-disabled",
},
dom.aside(
{ {
className: "qa-connect-usb-disabled-message", id: "about-debugging-setup-usb-disabled",
}, },
"Enabling this will download and add the required Android USB debugging " + dom.aside(
"components to Firefox." {
) className: "qa-connect-usb-disabled-message",
), },
this.renderTroubleshootText(RUNTIMES.USB), "Enabling this will download and add the required Android USB debugging " +
"components to Firefox."
)
),
this.renderTroubleshootText(RUNTIMES.USB)
); );
} }
@ -196,24 +206,26 @@ class ConnectPage extends PureComponent {
{}, {},
NetworkLocationsList({ dispatch, networkLocations }), NetworkLocationsList({ dispatch, networkLocations }),
NetworkLocationsForm({ dispatch, networkLocations }), NetworkLocationsForm({ dispatch, networkLocations }),
this.renderTroubleshootText(RUNTIMES.NETWORK), this.renderTroubleshootText(RUNTIMES.NETWORK)
), ),
}, })
)
); );
} }
renderTroubleshootText(connectionType) { renderTroubleshootText(connectionType) {
const localizationId = connectionType === RUNTIMES.USB const localizationId =
? "about-debugging-setup-usb-troubleshoot" connectionType === RUNTIMES.USB
: "about-debugging-setup-network-troubleshoot"; ? "about-debugging-setup-usb-troubleshoot"
: "about-debugging-setup-network-troubleshoot";
const className = "connect-page__troubleshoot connect-page__troubleshoot--" + const className =
"connect-page__troubleshoot connect-page__troubleshoot--" +
`${connectionType === RUNTIMES.USB ? "usb" : "network"}`; `${connectionType === RUNTIMES.USB ? "usb" : "network"}`;
const url = connectionType === RUNTIMES.USB const url =
? TROUBLESHOOT_USB_URL connectionType === RUNTIMES.USB
: TROUBLESHOOT_NETWORK_URL; ? TROUBLESHOOT_USB_URL
: TROUBLESHOOT_NETWORK_URL;
return dom.aside( return dom.aside(
{ {
@ -222,17 +234,12 @@ class ConnectPage extends PureComponent {
Localized( Localized(
{ {
id: localizationId, id: localizationId,
a: dom.a( a: dom.a({
{ href: url,
href: url, target: "_blank",
target: "_blank", }),
}
),
}, },
dom.p( dom.p({}, localizationId)
{},
localizationId,
),
) )
); );
} }
@ -251,7 +258,7 @@ class ConnectPage extends PureComponent {
className: "alt-heading alt-heading--larger", className: "alt-heading alt-heading--larger",
}, },
"Setup" "Setup"
), )
), ),
Localized( Localized(
{ {
@ -269,10 +276,7 @@ class ConnectPage extends PureComponent {
to: `/runtime/${RUNTIMES.THIS_FIREFOX}`, to: `/runtime/${RUNTIMES.THIS_FIREFOX}`,
}), }),
}, },
dom.p( dom.p({}, "about-debugging-setup-this-firefox")
{},
"about-debugging-setup-this-firefox",
),
), ),
dom.section( dom.section(
{ {
@ -286,12 +290,12 @@ class ConnectPage extends PureComponent {
{ {
className: "alt-heading", className: "alt-heading",
}, },
"Connect a device", "Connect a device"
), )
), ),
this.renderUsb(), this.renderUsb(),
this.renderNetwork() this.renderNetwork()
), )
); );
} }
} }

View file

@ -25,7 +25,7 @@ class ConnectSection extends PureComponent {
{ {
className: "connect-section__extra", className: "connect-section__extra",
}, },
extraContent, extraContent
); );
} }
@ -40,28 +40,26 @@ class ConnectSection extends PureComponent {
{ {
className: "connect-section__header", className: "connect-section__header",
}, },
dom.img( dom.img({
{ className: "connect-section__header__icon",
className: "connect-section__header__icon", src: this.props.icon,
src: this.props.icon, }),
},
),
dom.h1( dom.h1(
{ {
className: "card__heading connect-section__header__title", className: "card__heading connect-section__header__title",
}, },
this.props.title, this.props.title
), )
), ),
this.props.children this.props.children
? dom.div( ? dom.div(
{ {
className: "connect-section__content", className: "connect-section__content",
}, },
this.props.children this.props.children
) )
: null, : null,
extraContent ? this.renderExtraContent() : null, extraContent ? this.renderExtraContent() : null
); );
} }
} }

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
const { PureComponent, createFactory } = require("devtools/client/shared/vendor/react"); const {
PureComponent,
createFactory,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
@ -17,7 +20,7 @@ class ConnectSteps extends PureComponent {
steps: PropTypes.arrayOf( steps: PropTypes.arrayOf(
PropTypes.shape({ PropTypes.shape({
localizationId: PropTypes.string.isRequired, localizationId: PropTypes.string.isRequired,
}).isRequired, }).isRequired
), ),
}; };
} }

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const {
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
@ -73,8 +76,9 @@ class NetworkLocationsForm extends PureComponent {
return Message( return Message(
{ {
className: "connect-page__network-form__error-message " + className:
"qa-connect-page__network-form__error-message", "connect-page__network-form__error-message " +
"qa-connect-page__network-form__error-message",
level: MESSAGE_LEVEL.ERROR, level: MESSAGE_LEVEL.ERROR,
isCloseable: true, isCloseable: true,
}, },
@ -85,11 +89,11 @@ class NetworkLocationsForm extends PureComponent {
}, },
dom.p( dom.p(
{ {
className: "technical-text", className: "technical-text",
}, },
errorMessageId errorMessageId
) )
), )
); );
} }
@ -97,7 +101,7 @@ class NetworkLocationsForm extends PureComponent {
return dom.form( return dom.form(
{ {
className: "connect-page__network-form", className: "connect-page__network-form",
onSubmit: (e) => this.onSubmit(e), onSubmit: e => this.onSubmit(e),
}, },
this.renderError(), this.renderError(),
Localized( Localized(
@ -108,7 +112,7 @@ class NetworkLocationsForm extends PureComponent {
{ {
htmlFor: "about-debugging-network-locations-host-input", htmlFor: "about-debugging-network-locations-host-input",
}, },
"Host", "Host"
) )
), ),
dom.input({ dom.input({
@ -117,7 +121,7 @@ class NetworkLocationsForm extends PureComponent {
placeholder: "localhost:6080", placeholder: "localhost:6080",
type: "text", type: "text",
value: this.state.value, value: this.state.value,
onChange: (e) => { onChange: e => {
const value = e.target.value; const value = e.target.value;
this.setState({ value }); this.setState({ value });
}, },
@ -132,7 +136,7 @@ class NetworkLocationsForm extends PureComponent {
}, },
"Add" "Add"
) )
), )
); );
} }
} }

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const {
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
@ -48,8 +51,8 @@ class NetworkLocationsList extends PureComponent {
this.props.dispatch(Actions.removeNetworkLocation(location)); this.props.dispatch(Actions.removeNetworkLocation(location));
}, },
}, },
"Remove", "Remove"
), )
) )
) )
) )
@ -57,8 +60,7 @@ class NetworkLocationsList extends PureComponent {
} }
render() { render() {
return this.props.networkLocations.length > 0 ? return this.props.networkLocations.length > 0 ? this.renderList() : null;
this.renderList() : null;
} }
} }

View file

@ -30,7 +30,7 @@ class DebugTargetItem extends PureComponent {
{ {
className: "debug-target-item__action", className: "debug-target-item__action",
}, },
actionComponent({ dispatch, target }), actionComponent({ dispatch, target })
); );
} }
@ -45,7 +45,7 @@ class DebugTargetItem extends PureComponent {
{ {
className: "debug-target-item__additional_actions", className: "debug-target-item__additional_actions",
}, },
additionalActionsComponent({ dispatch, target }), additionalActionsComponent({ dispatch, target })
); );
} }
@ -67,7 +67,7 @@ class DebugTargetItem extends PureComponent {
className: "debug-target-item__name ellipsis-text", className: "debug-target-item__name ellipsis-text",
title: this.props.target.name, title: this.props.target.name,
}, },
this.props.target.name, this.props.target.name
); );
} }
@ -80,7 +80,7 @@ class DebugTargetItem extends PureComponent {
this.renderName(), this.renderName(),
this.renderAction(), this.renderAction(),
this.renderDetail(), this.renderDetail(),
this.renderAdditionalActions(), this.renderAdditionalActions()
); );
} }
} }

View file

@ -4,8 +4,10 @@
"use strict"; "use strict";
const { createFactory, PureComponent } = const {
require("devtools/client/shared/vendor/react"); createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
@ -56,20 +58,20 @@ class DebugTargetList extends PureComponent {
return targets.length === 0 return targets.length === 0
? this.renderEmptyList() ? this.renderEmptyList()
: dom.ul( : dom.ul(
{ {
className: "debug-target-list qa-debug-target-list", className: "debug-target-list qa-debug-target-list",
}, },
targets.map((target, key) => targets.map((target, key) =>
DebugTargetItem({ DebugTargetItem({
actionComponent, actionComponent,
additionalActionsComponent, additionalActionsComponent,
detailComponent, detailComponent,
dispatch, dispatch,
key, key,
target, target,
}) })
), )
); );
} }
} }

View file

@ -4,7 +4,11 @@
"use strict"; "use strict";
const { createFactory, createRef, PureComponent } = require("devtools/client/shared/vendor/react"); const {
createFactory,
createRef,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
@ -53,8 +57,10 @@ class DebugTargetPane extends PureComponent {
animation.cancel(); animation.cancel();
} }
el.animate({ maxHeight: [`${ snapshot }px`, `${ el.clientHeight }px`] }, el.animate(
{ duration: 150, easing: "cubic-bezier(.07, .95, 0, 1)" }); { maxHeight: [`${snapshot}px`, `${el.clientHeight}px`] },
{ duration: 150, easing: "cubic-bezier(.07, .95, 0, 1)" }
);
} }
getSnapshotBeforeUpdate(prevProps) { getSnapshotBeforeUpdate(prevProps) {
@ -67,7 +73,9 @@ class DebugTargetPane extends PureComponent {
toggleCollapsibility() { toggleCollapsibility() {
const { collapsibilityKey, dispatch, isCollapsed } = this.props; const { collapsibilityKey, dispatch, isCollapsed } = this.props;
dispatch(Actions.updateDebugTargetCollapsibility(collapsibilityKey, !isCollapsed)); dispatch(
Actions.updateDebugTargetCollapsibility(collapsibilityKey, !isCollapsed)
);
} }
render() { render() {
@ -92,33 +100,32 @@ class DebugTargetPane extends PureComponent {
}, },
dom.a( dom.a(
{ {
className: "undecorated-link debug-target-pane__title " + className:
"qa-debug-target-pane-title", "undecorated-link debug-target-pane__title " +
"qa-debug-target-pane-title",
title, title,
onClick: e => this.toggleCollapsibility(), onClick: e => this.toggleCollapsibility(),
}, },
dom.h2( dom.h2(
{ className: "main-subheading debug-target-pane__heading" }, { className: "main-subheading debug-target-pane__heading" },
dom.img( dom.img({
{ className: "main-subheading__icon",
className: "main-subheading__icon", src: icon,
src: icon, }),
} `${name} (${targets.length})`,
), dom.img({
`${ name } (${ targets.length })`, className:
dom.img( "main-subheading__icon debug-target-pane__icon" +
{ (isCollapsed ? " debug-target-pane__icon--collapsed" : ""),
className: "main-subheading__icon debug-target-pane__icon" + src: "chrome://devtools/skin/images/arrow-e.svg",
(isCollapsed ? " debug-target-pane__icon--collapsed" : ""), })
src: "chrome://devtools/skin/images/arrow-e.svg",
}
),
) )
), ),
dom.div( dom.div(
{ {
className: "debug-target-pane__collapsable qa-debug-target-pane__collapsable" + className:
(isCollapsed ? " debug-target-pane__collapsable--collapsed" : ""), "debug-target-pane__collapsable qa-debug-target-pane__collapsable" +
(isCollapsed ? " debug-target-pane__collapsable--collapsed" : ""),
ref: this.collapsableRef, ref: this.collapsableRef,
}, },
children, children,
@ -129,8 +136,8 @@ class DebugTargetPane extends PureComponent {
dispatch, dispatch,
isCollapsed, isCollapsed,
targets, targets,
}), })
), )
); );
} }
} }

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const {
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
@ -58,7 +61,7 @@ class ExtensionDetail extends PureComponent {
className: "technical-text", className: "technical-text",
}, },
warning warning
), )
) )
); );
}) })
@ -76,12 +79,10 @@ class ExtensionDetail extends PureComponent {
id: "about-debugging-extension-uuid", id: "about-debugging-extension-uuid",
attrs: { label: true }, attrs: { label: true },
}, },
FieldPair( FieldPair({
{ label: "Internal UUID",
label: "Internal UUID", value: uuid,
value: uuid, })
}
)
); );
} }
@ -93,12 +94,10 @@ class ExtensionDetail extends PureComponent {
id: "about-debugging-extension-id", id: "about-debugging-extension-id",
attrs: { label: true }, attrs: { label: true },
}, },
FieldPair( FieldPair({
{ label: "Extension ID",
label: "Extension ID", value: id,
value: id, })
}
)
); );
} }
@ -113,12 +112,10 @@ class ExtensionDetail extends PureComponent {
id: "about-debugging-extension-location", id: "about-debugging-extension-location",
attrs: { label: true }, attrs: { label: true },
}, },
FieldPair( FieldPair({
{ label: "Location",
label: "Location", value: location,
value: location, })
}
)
); );
} }
@ -134,7 +131,7 @@ class ExtensionDetail extends PureComponent {
href: manifestURL, href: manifestURL,
target: "_blank", target: "_blank",
}, },
manifestURL, manifestURL
); );
return Localized( return Localized(
@ -142,12 +139,10 @@ class ExtensionDetail extends PureComponent {
id: "about-debugging-extension-manifest-url", id: "about-debugging-extension-manifest-url",
attrs: { label: true }, attrs: { label: true },
}, },
FieldPair( FieldPair({
{ label: "Manifest URL",
label: "Manifest URL", value: link,
value: link, })
}
)
); );
} }
@ -163,8 +158,8 @@ class ExtensionDetail extends PureComponent {
this.renderExtensionId(), this.renderExtensionId(),
this.renderUUID(), this.renderUUID(),
this.renderManifest(), this.renderManifest(),
this.props.children, this.props.children
), )
); );
} }
} }

View file

@ -26,16 +26,20 @@ class FieldPair extends PureComponent {
}, },
dom.dt( dom.dt(
{ {
className: "fieldpair__title " + className:
(this.props.className ? this.props.className : ""), "fieldpair__title " +
(this.props.className ? this.props.className : ""),
}, },
label label
), ),
value ? dom.dd( value
{ ? dom.dd(
className: "fieldpair__description ellipsis-text", {
}, className: "fieldpair__description ellipsis-text",
value) : null, },
value
)
: null
); );
} }
} }

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const {
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");

View file

@ -20,7 +20,10 @@ class ProcessDetail extends PureComponent {
render() { render() {
const { description } = this.props.target.details; const { description } = this.props.target.details;
return dom.p({ className: "debug-target-item__subname ellipsis-text" }, description); return dom.p(
{ className: "debug-target-item__subname ellipsis-text" },
description
);
} }
} }

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const {
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const { connect } = require("devtools/client/shared/vendor/react-redux"); const { connect } = require("devtools/client/shared/vendor/react-redux");
@ -12,7 +15,9 @@ const { connect } = require("devtools/client/shared/vendor/react-redux");
const FluentReact = require("devtools/client/shared/vendor/fluent-react"); const FluentReact = require("devtools/client/shared/vendor/fluent-react");
const Localized = createFactory(FluentReact.Localized); const Localized = createFactory(FluentReact.Localized);
const { getCurrentRuntimeDetails } = require("../../modules/runtimes-state-helper"); const {
getCurrentRuntimeDetails,
} = require("../../modules/runtimes-state-helper");
const InspectAction = createFactory(require("./InspectAction")); const InspectAction = createFactory(require("./InspectAction"));
@ -34,8 +39,9 @@ class ServiceWorkerAction extends PureComponent {
_renderInspectAction() { _renderInspectAction() {
const { status } = this.props.target.details; const { status } = this.props.target.details;
const shallRenderInspectAction = status === SERVICE_WORKER_STATUSES.RUNNING || const shallRenderInspectAction =
status === SERVICE_WORKER_STATUSES.REGISTERING; status === SERVICE_WORKER_STATUSES.RUNNING ||
status === SERVICE_WORKER_STATUSES.REGISTERING;
if (!shallRenderInspectAction) { if (!shallRenderInspectAction) {
return null; return null;
@ -64,8 +70,10 @@ class ServiceWorkerAction extends PureComponent {
_renderStatus() { _renderStatus() {
const status = this.props.target.details.status.toLowerCase(); const status = this.props.target.details.status.toLowerCase();
const statusClassName = status === SERVICE_WORKER_STATUSES.RUNNING.toLowerCase() const statusClassName =
? "service-worker-action__status--running" : ""; status === SERVICE_WORKER_STATUSES.RUNNING.toLowerCase()
? "service-worker-action__status--running"
: "";
return Localized( return Localized(
{ {
@ -73,8 +81,7 @@ class ServiceWorkerAction extends PureComponent {
}, },
dom.span( dom.span(
{ {
className: className: `service-worker-action__status qa-worker-status ${statusClassName}`,
`service-worker-action__status qa-worker-status ${ statusClassName }`,
}, },
status status
) )
@ -87,7 +94,7 @@ class ServiceWorkerAction extends PureComponent {
className: "service-worker-action", className: "service-worker-action",
}, },
this._renderStatus(), this._renderStatus(),
this._renderInspectAction(), this._renderInspectAction()
); );
} }
} }

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const {
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const { connect } = require("devtools/client/shared/vendor/react-redux"); const { connect } = require("devtools/client/shared/vendor/react-redux");
@ -12,7 +15,9 @@ const { connect } = require("devtools/client/shared/vendor/react-redux");
const FluentReact = require("devtools/client/shared/vendor/fluent-react"); const FluentReact = require("devtools/client/shared/vendor/fluent-react");
const Localized = createFactory(FluentReact.Localized); const Localized = createFactory(FluentReact.Localized);
const { getCurrentRuntimeDetails } = require("../../modules/runtimes-state-helper"); const {
getCurrentRuntimeDetails,
} = require("../../modules/runtimes-state-helper");
const Actions = require("../../actions/index"); const Actions = require("../../actions/index");
const Types = require("../../types/index"); const Types = require("../../types/index");
@ -60,7 +65,7 @@ class ServiceWorkerAdditionalActions extends PureComponent {
disabled, disabled,
onClick: e => onClick(), onClick: e => onClick(),
}, },
labelId, labelId
) )
); );
} }
@ -99,17 +104,11 @@ class ServiceWorkerAdditionalActions extends PureComponent {
switch (status) { switch (status) {
case SERVICE_WORKER_STATUSES.RUNNING: case SERVICE_WORKER_STATUSES.RUNNING:
return [ return [this._renderUnregisterButton(), this._renderPushButton()];
this._renderUnregisterButton(),
this._renderPushButton(),
];
case SERVICE_WORKER_STATUSES.REGISTERING: case SERVICE_WORKER_STATUSES.REGISTERING:
return null; return null;
case SERVICE_WORKER_STATUSES.STOPPED: case SERVICE_WORKER_STATUSES.STOPPED:
return [ return [this._renderUnregisterButton(), this._renderStartButton()];
this._renderUnregisterButton(),
this._renderStartButton(),
];
default: default:
console.error("Unexpected service worker status: " + status); console.error("Unexpected service worker status: " + status);
return null; return null;
@ -121,7 +120,7 @@ class ServiceWorkerAdditionalActions extends PureComponent {
{ {
className: "toolbar toolbar--right-align", className: "toolbar toolbar--right-align",
}, },
this._renderActionButtons(), this._renderActionButtons()
); );
} }
} }
@ -133,4 +132,5 @@ const mapStateToProps = state => {
}; };
module.exports = FluentReact.withLocalization( module.exports = FluentReact.withLocalization(
connect(mapStateToProps)(ServiceWorkerAdditionalActions)); connect(mapStateToProps)(ServiceWorkerAdditionalActions)
);

View file

@ -19,8 +19,10 @@ class TabDetail extends PureComponent {
} }
render() { render() {
return dom.div({ className: "debug-target-item__subname ellipsis-text" }, return dom.div(
this.props.target.details.url); { className: "debug-target-item__subname ellipsis-text" },
this.props.target.details.url
);
} }
} }

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const {
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
@ -61,7 +64,7 @@ class TemporaryExtensionAdditionalActions extends PureComponent {
className: "technical-text", className: "technical-text",
}, },
reloadError reloadError
), )
) )
); );
} }
@ -79,11 +82,12 @@ class TemporaryExtensionAdditionalActions extends PureComponent {
}, },
dom.button( dom.button(
{ {
className: "default-button default-button--micro " + className:
"qa-temporary-extension-reload-button", "default-button default-button--micro " +
"qa-temporary-extension-reload-button",
onClick: e => this.reload(), onClick: e => this.reload(),
}, },
"Reload", "Reload"
) )
), ),
Localized( Localized(
@ -92,13 +96,14 @@ class TemporaryExtensionAdditionalActions extends PureComponent {
}, },
dom.button( dom.button(
{ {
className: "default-button default-button--micro " + className:
"qa-temporary-extension-remove-button", "default-button default-button--micro " +
"qa-temporary-extension-remove-button",
onClick: e => this.remove(), onClick: e => this.remove(),
}, },
"Remove", "Remove"
) )
), )
), ),
this.renderReloadError(), this.renderReloadError(),
]; ];

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const {
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
@ -43,7 +46,7 @@ class TemporaryExtensionDetail extends PureComponent {
}, },
dom.div({ dom.div({
className: "qa-temporary-id-message", className: "qa-temporary-id-message",
}), })
); );
} }
@ -52,7 +55,7 @@ class TemporaryExtensionDetail extends PureComponent {
{ {
target: this.props.target, target: this.props.target,
}, },
FieldPair({ label: this.renderTemporaryIdMessage() }), FieldPair({ label: this.renderTemporaryIdMessage() })
); );
} }
} }

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const {
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
@ -13,8 +16,9 @@ const Localized = createFactory(FluentReact.Localized);
const DetailsLog = createFactory(require("../shared/DetailsLog")); const DetailsLog = createFactory(require("../shared/DetailsLog"));
const Message = createFactory(require("../shared/Message")); const Message = createFactory(require("../shared/Message"));
const TemporaryExtensionInstaller = const TemporaryExtensionInstaller = createFactory(
createFactory(require("./TemporaryExtensionInstaller")); require("./TemporaryExtensionInstaller")
);
const { MESSAGE_LEVEL } = require("../../constants"); const { MESSAGE_LEVEL } = require("../../constants");
@ -61,10 +65,7 @@ class TemporaryExtensionInstallSection extends PureComponent {
{ {
id: "about-debugging-tmp-extension-install-error", id: "about-debugging-tmp-extension-install-error",
}, },
dom.p( dom.p({}, "about-debugging-tmp-extension-install-error")
{ },
"about-debugging-tmp-extension-install-error"
)
), ),
DetailsLog( DetailsLog(
{ {
@ -84,9 +85,9 @@ class TemporaryExtensionInstallSection extends PureComponent {
{ {
className: "temporary-extension-install-section__toolbar", className: "temporary-extension-install-section__toolbar",
}, },
TemporaryExtensionInstaller({ dispatch }), TemporaryExtensionInstaller({ dispatch })
), ),
this.renderError(), this.renderError()
); );
} }
} }

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const {
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
@ -37,8 +40,7 @@ class TemporaryExtensionInstaller extends PureComponent {
}, },
dom.button( dom.button(
{ {
className: className: `${className} default-button qa-temporary-extension-install-button`,
`${ className } default-button qa-temporary-extension-install-button`,
onClick: e => this.install(), onClick: e => this.install(),
}, },
"Load Temporary Add-on…" "Load Temporary Add-on…"

View file

@ -4,16 +4,17 @@
"use strict"; "use strict";
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const {
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const FluentReact = require("devtools/client/shared/vendor/fluent-react"); const FluentReact = require("devtools/client/shared/vendor/fluent-react");
const Localized = createFactory(FluentReact.Localized); const Localized = createFactory(FluentReact.Localized);
const { const { SERVICE_WORKER_FETCH_STATES } = require("../../constants");
SERVICE_WORKER_FETCH_STATES,
} = require("../../constants");
const FieldPair = createFactory(require("./FieldPair")); const FieldPair = createFactory(require("./FieldPair"));
@ -35,8 +36,8 @@ class WorkerDetail extends PureComponent {
const { fetch } = this.props.target.details; const { fetch } = this.props.target.details;
const isListening = fetch === SERVICE_WORKER_FETCH_STATES.LISTENING; const isListening = fetch === SERVICE_WORKER_FETCH_STATES.LISTENING;
const localizationId = isListening const localizationId = isListening
? "about-debugging-worker-fetch-listening" ? "about-debugging-worker-fetch-listening"
: "about-debugging-worker-fetch-not-listening"; : "about-debugging-worker-fetch-not-listening";
return Localized( return Localized(
{ {
@ -46,15 +47,14 @@ class WorkerDetail extends PureComponent {
value: true, value: true,
}, },
}, },
FieldPair( FieldPair({
{ className: isListening
className: isListening ? ? "qa-worker-fetch-listening"
"qa-worker-fetch-listening" : "qa-worker-fetch-not-listening", : "qa-worker-fetch-not-listening",
label: "Fetch", label: "Fetch",
slug: "fetch", slug: "fetch",
value: "about-debugging-worker-fetch-value", value: "about-debugging-worker-fetch-value",
} })
)
); );
} }
@ -66,18 +66,16 @@ class WorkerDetail extends PureComponent {
id: "about-debugging-worker-push-service", id: "about-debugging-worker-push-service",
attrs: { label: true }, attrs: { label: true },
}, },
FieldPair( FieldPair({
{ slug: "push-service",
slug: "push-service", label: "Push Service",
label: "Push Service", value: dom.span(
value: dom.span( {
{ className: "qa-worker-push-service-value",
className: "qa-worker-push-service-value", },
}, pushServiceEndpoint
pushServiceEndpoint, ),
), })
}
),
); );
} }
@ -89,13 +87,11 @@ class WorkerDetail extends PureComponent {
id: "about-debugging-worker-scope", id: "about-debugging-worker-scope",
attrs: { label: true }, attrs: { label: true },
}, },
FieldPair( FieldPair({
{ slug: "scope",
slug: "scope", label: "Scope",
label: "Scope", value: scope,
value: scope, })
}
),
); );
} }
@ -106,12 +102,13 @@ class WorkerDetail extends PureComponent {
return dom.dl( return dom.dl(
{ {
className: "debug-target-item__detail" + className:
(isEmptyList ? " debug-target-item__detail--empty" : ""), "debug-target-item__detail" +
(isEmptyList ? " debug-target-item__detail--empty" : ""),
}, },
pushServiceEndpoint ? this.renderPushService() : null, pushServiceEndpoint ? this.renderPushService() : null,
fetch ? this.renderFetch() : null, fetch ? this.renderFetch() : null,
scope ? this.renderScope() : null, scope ? this.renderScope() : null
); );
} }
} }

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const {
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
@ -45,13 +48,11 @@ class DetailsLog extends PureComponent {
{ {
className: "details--log", className: "details--log",
}, },
Localized({ Localized(
{
id: this.getLocalizationString(), id: this.getLocalizationString(),
}, },
dom.summary( dom.summary({}, this.getLocalizationString())
{},
this.getLocalizationString()
)
), ),
children children
); );

View file

@ -32,13 +32,11 @@ class IconLabel extends PureComponent {
{ {
className: `icon-label icon-label--${level} ${className || ""}`, className: `icon-label icon-label--${level} ${className || ""}`,
}, },
dom.img( dom.img({
{ className: "icon-label__icon",
className: "icon-label__icon", src: ICONS[level],
src: ICONS[level], }),
} children
),
children,
); );
} }
} }

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const {
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
@ -14,8 +17,10 @@ const Localized = createFactory(FluentReact.Localized);
const { MESSAGE_LEVEL } = require("../../constants"); const { MESSAGE_LEVEL } = require("../../constants");
const ICONS = { const ICONS = {
[MESSAGE_LEVEL.ERROR]: "chrome://devtools/skin/images/aboutdebugging-error.svg", [MESSAGE_LEVEL.ERROR]:
[MESSAGE_LEVEL.INFO]: "chrome://devtools/skin/images/aboutdebugging-information.svg", "chrome://devtools/skin/images/aboutdebugging-error.svg",
[MESSAGE_LEVEL.INFO]:
"chrome://devtools/skin/images/aboutdebugging-information.svg",
[MESSAGE_LEVEL.WARNING]: "chrome://global/skin/icons/warning.svg", [MESSAGE_LEVEL.WARNING]: "chrome://global/skin/icons/warning.svg",
}; };
const CLOSE_ICON_SRC = "chrome://devtools/skin/images/close.svg"; const CLOSE_ICON_SRC = "chrome://devtools/skin/images/close.svg";
@ -49,7 +54,8 @@ class Message extends PureComponent {
renderButton(level) { renderButton(level) {
return dom.button( return dom.button(
{ {
className: `ghost-button message__button message__button--${level} ` + className:
`ghost-button message__button message__button--${level} ` +
`qa-message-button-close-button`, `qa-message-button-close-button`,
onClick: () => this.closeMessage(), onClick: () => this.closeMessage(),
}, },
@ -60,13 +66,11 @@ class Message extends PureComponent {
alt: true, alt: true,
}, },
}, },
dom.img( dom.img({
{ className: "qa-message-button-close-icon",
className: "qa-message-button-close-icon", src: CLOSE_ICON_SRC,
src: CLOSE_ICON_SRC, })
}, )
),
),
); );
} }
@ -80,15 +84,14 @@ class Message extends PureComponent {
return dom.aside( return dom.aside(
{ {
className: `message message--level-${level} qa-message` + className:
(className ? ` ${ className }` : ""), `message message--level-${level} qa-message` +
(className ? ` ${className}` : ""),
}, },
dom.img( dom.img({
{ className: "message__icon",
className: "message__icon", src: ICONS[level],
src: ICONS[level], }),
}
),
dom.div( dom.div(
{ {
className: "message__body", className: "message__body",
@ -96,9 +99,7 @@ class Message extends PureComponent {
children children
), ),
// if the message is closeable, render a closing button // if the message is closeable, render a closing button
isCloseable isCloseable ? this.renderButton(level) : null
? this.renderButton(level)
: null,
); );
} }
} }

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const {
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const FluentReact = require("devtools/client/shared/vendor/fluent-react"); const FluentReact = require("devtools/client/shared/vendor/fluent-react");

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const {
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
@ -13,17 +16,25 @@ const Localized = createFactory(FluentReact.Localized);
const { ICON_LABEL_LEVEL, PAGE_TYPES, RUNTIMES } = require("../../constants"); const { ICON_LABEL_LEVEL, PAGE_TYPES, RUNTIMES } = require("../../constants");
const Types = require("../../types/index"); const Types = require("../../types/index");
loader.lazyRequireGetter(this, "ADB_ADDON_STATES", "devtools/shared/adb/adb-addon", true); loader.lazyRequireGetter(
this,
"ADB_ADDON_STATES",
"devtools/shared/adb/adb-addon",
true
);
const IconLabel = createFactory(require("../shared/IconLabel")); const IconLabel = createFactory(require("../shared/IconLabel"));
const SidebarItem = createFactory(require("./SidebarItem")); const SidebarItem = createFactory(require("./SidebarItem"));
const SidebarFixedItem = createFactory(require("./SidebarFixedItem")); const SidebarFixedItem = createFactory(require("./SidebarFixedItem"));
const SidebarRuntimeItem = createFactory(require("./SidebarRuntimeItem")); const SidebarRuntimeItem = createFactory(require("./SidebarRuntimeItem"));
const RefreshDevicesButton = createFactory(require("./RefreshDevicesButton")); const RefreshDevicesButton = createFactory(require("./RefreshDevicesButton"));
const FIREFOX_ICON = "chrome://devtools/skin/images/aboutdebugging-firefox-logo.svg"; const FIREFOX_ICON =
"chrome://devtools/skin/images/aboutdebugging-firefox-logo.svg";
const CONNECT_ICON = "chrome://devtools/skin/images/settings.svg"; const CONNECT_ICON = "chrome://devtools/skin/images/settings.svg";
const GLOBE_ICON = "chrome://devtools/skin/images/aboutdebugging-globe-icon.svg"; const GLOBE_ICON =
const USB_ICON = "chrome://devtools/skin/images/aboutdebugging-connect-icon.svg"; "chrome://devtools/skin/images/aboutdebugging-globe-icon.svg";
const USB_ICON =
"chrome://devtools/skin/images/aboutdebugging-connect-icon.svg";
class Sidebar extends PureComponent { class Sidebar extends PureComponent {
static get propTypes() { static get propTypes() {
@ -41,13 +52,15 @@ class Sidebar extends PureComponent {
} }
renderAdbStatus() { renderAdbStatus() {
const isUsbEnabled = this.props.isAdbReady && const isUsbEnabled =
this.props.isAdbReady &&
this.props.adbAddonStatus === ADB_ADDON_STATES.INSTALLED; this.props.adbAddonStatus === ADB_ADDON_STATES.INSTALLED;
const localizationId = isUsbEnabled ? "about-debugging-sidebar-usb-enabled" : const localizationId = isUsbEnabled
"about-debugging-sidebar-usb-disabled"; ? "about-debugging-sidebar-usb-enabled"
: "about-debugging-sidebar-usb-disabled";
return IconLabel( return IconLabel(
{ {
level: isUsbEnabled ? ICON_LABEL_LEVEL.OK : ICON_LABEL_LEVEL.INFO, level: isUsbEnabled ? ICON_LABEL_LEVEL.OK : ICON_LABEL_LEVEL.INFO,
}, },
Localized( Localized(
{ {
@ -100,8 +113,8 @@ class Sidebar extends PureComponent {
return runtimes.map(runtime => { return runtimes.map(runtime => {
const keyId = `${runtime.type}-${runtime.id}`; const keyId = `${runtime.type}-${runtime.id}`;
const runtimeHasDetails = !!runtime.runtimeDetails; const runtimeHasDetails = !!runtime.runtimeDetails;
const isSelected = selectedPage === PAGE_TYPES.RUNTIME && const isSelected =
runtime.id === selectedRuntimeId; selectedPage === PAGE_TYPES.RUNTIME && runtime.id === selectedRuntimeId;
let name = runtime.name; let name = runtime.name;
if (runtime.type === RUNTIMES.USB && runtimeHasDetails) { if (runtime.type === RUNTIMES.USB && runtimeHasDetails) {
@ -130,7 +143,8 @@ class Sidebar extends PureComponent {
renderFooter() { renderFooter() {
const HELP_ICON_SRC = "chrome://global/skin/icons/help.svg"; const HELP_ICON_SRC = "chrome://global/skin/icons/help.svg";
const SUPPORT_URL = "https://developer.mozilla.org/docs/Tools/about:debugging"; const SUPPORT_URL =
"https://developer.mozilla.org/docs/Tools/about:debugging";
return dom.footer( return dom.footer(
{ {
@ -154,27 +168,30 @@ class Sidebar extends PureComponent {
alt: true, alt: true,
}, },
}, },
dom.img( dom.img({
{ className: "sidebar__footer__icon",
className: "sidebar__footer__icon", src: HELP_ICON_SRC,
src: HELP_ICON_SRC, })
}
),
), ),
Localized( Localized(
{ {
id: "about-debugging-sidebar-support", id: "about-debugging-sidebar-support",
}, },
dom.span({}, "about-debugging-sidebar-support"), dom.span({}, "about-debugging-sidebar-support")
) )
) )
), )
) )
); );
} }
render() { render() {
const { dispatch, selectedPage, selectedRuntimeId, isScanningUsb } = this.props; const {
dispatch,
selectedPage,
selectedRuntimeId,
isScanningUsb,
} = this.props;
return dom.aside( return dom.aside(
{ {
@ -197,7 +214,8 @@ class Sidebar extends PureComponent {
{ id: "about-debugging-sidebar-this-firefox", attrs: { name: true } }, { id: "about-debugging-sidebar-this-firefox", attrs: { name: true } },
SidebarFixedItem({ SidebarFixedItem({
icon: FIREFOX_ICON, icon: FIREFOX_ICON,
isSelected: PAGE_TYPES.RUNTIME === selectedPage && isSelected:
PAGE_TYPES.RUNTIME === selectedPage &&
selectedRuntimeId === RUNTIMES.THIS_FIREFOX, selectedRuntimeId === RUNTIMES.THIS_FIREFOX,
key: RUNTIMES.THIS_FIREFOX, key: RUNTIMES.THIS_FIREFOX,
name: "This Firefox", name: "This Firefox",
@ -209,7 +227,7 @@ class Sidebar extends PureComponent {
className: "sidebar__adb-status", className: "sidebar__adb-status",
}, },
dom.hr({ className: "separator separator--breathe" }), dom.hr({ className: "separator separator--breathe" }),
this.renderAdbStatus(), this.renderAdbStatus()
), ),
this.renderDevices(), this.renderDevices(),
SidebarItem( SidebarItem(
@ -221,9 +239,9 @@ class Sidebar extends PureComponent {
dispatch, dispatch,
isScanning: isScanningUsb, isScanning: isScanningUsb,
}) })
), )
), ),
this.renderFooter(), this.renderFooter()
); );
} }
} }

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
const { PureComponent, createFactory } = require("devtools/client/shared/vendor/react"); const {
PureComponent,
createFactory,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
@ -24,12 +27,7 @@ class SidebarFixedItem extends PureComponent {
} }
render() { render() {
const { const { icon, isSelected, name, to } = this.props;
icon,
isSelected,
name,
to,
} = this.props;
return SidebarItem( return SidebarItem(
{ {
@ -41,12 +39,10 @@ class SidebarFixedItem extends PureComponent {
{ {
className: "sidebar-fixed-item__container", className: "sidebar-fixed-item__container",
}, },
dom.img( dom.img({
{ className: "sidebar-fixed-item__icon",
className: "sidebar-fixed-item__icon", src: icon,
src: icon, }),
}
),
dom.span( dom.span(
{ {
className: "ellipsis-text", className: "ellipsis-text",

View file

@ -4,10 +4,15 @@
"use strict"; "use strict";
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const {
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const Link = createFactory(require("devtools/client/shared/vendor/react-router-dom").Link); const Link = createFactory(
require("devtools/client/shared/vendor/react-router-dom").Link
);
/** /**
* This component is used as a wrapper by items in the sidebar. * This component is used as a wrapper by items in the sidebar.
@ -36,20 +41,20 @@ class SidebarItem extends PureComponent {
return isExternalUrl return isExternalUrl
? dom.a( ? dom.a(
{ {
className: "sidebar-item__link", className: "sidebar-item__link",
href: to, href: to,
target: "_blank", target: "_blank",
}, },
children, children
) )
: Link( : Link(
{ {
className: "sidebar-item__link qa-sidebar-link", className: "sidebar-item__link qa-sidebar-link",
to, to,
}, },
children, children
); );
} }
return children; return children;
@ -60,13 +65,13 @@ class SidebarItem extends PureComponent {
return dom.li( return dom.li(
{ {
className: "sidebar-item qa-sidebar-item" + className:
(className ? ` ${className}` : "") + "sidebar-item qa-sidebar-item" +
(isSelected ? (className ? ` ${className}` : "") +
" sidebar-item--selected qa-sidebar-item-selected" : (isSelected
"" ? " sidebar-item--selected qa-sidebar-item-selected"
) + : "") +
(to ? " sidebar-item--selectable" : ""), (to ? " sidebar-item--selectable" : ""),
}, },
this.renderContent() this.renderContent()
); );

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
const { createFactory, PureComponent } = require("devtools/client/shared/vendor/react"); const {
createFactory,
PureComponent,
} = require("devtools/client/shared/vendor/react");
const dom = require("devtools/client/shared/vendor/react-dom-factories"); const dom = require("devtools/client/shared/vendor/react-dom-factories");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
@ -43,8 +46,8 @@ class SidebarRuntimeItem extends PureComponent {
renderConnectButton() { renderConnectButton() {
const { isConnecting } = this.props; const { isConnecting } = this.props;
const localizationId = isConnecting const localizationId = isConnecting
? "about-debugging-sidebar-item-connect-button-connecting" ? "about-debugging-sidebar-item-connect-button-connecting"
: "about-debugging-sidebar-item-connect-button"; : "about-debugging-sidebar-item-connect-button";
return Localized( return Localized(
{ {
id: localizationId, id: localizationId,
@ -84,14 +87,22 @@ class SidebarRuntimeItem extends PureComponent {
} }
renderName() { renderName() {
const { deviceName, getString, isUnavailable, isUnplugged, name } = this.props; const {
deviceName,
getString,
isUnavailable,
isUnplugged,
name,
} = this.props;
let displayName, qaClassName; let displayName, qaClassName;
if (isUnplugged) { if (isUnplugged) {
displayName = getString("about-debugging-sidebar-runtime-item-unplugged"); displayName = getString("about-debugging-sidebar-runtime-item-unplugged");
qaClassName = "qa-runtime-item-unplugged"; qaClassName = "qa-runtime-item-unplugged";
} else if (isUnavailable) { } else if (isUnavailable) {
displayName = getString("about-debugging-sidebar-runtime-item-waiting-for-browser"); displayName = getString(
"about-debugging-sidebar-runtime-item-waiting-for-browser"
);
qaClassName = "qa-runtime-item-waiting-for-browser"; qaClassName = "qa-runtime-item-waiting-for-browser";
} else { } else {
displayName = name; displayName = name;
@ -116,8 +127,8 @@ class SidebarRuntimeItem extends PureComponent {
{ {
className: `sidebar-runtime-item__runtime__details ${qaClassName}`, className: `sidebar-runtime-item__runtime__details ${qaClassName}`,
}, },
displayName, displayName
), )
); );
} }
@ -127,7 +138,7 @@ class SidebarRuntimeItem extends PureComponent {
className, className,
title: localizationId, title: localizationId,
}, },
displayName, displayName
); );
} }
@ -138,7 +149,7 @@ class SidebarRuntimeItem extends PureComponent {
$deviceName: deviceName, $deviceName: deviceName,
$displayName: displayName, $displayName: displayName,
}, },
deviceName ? renderWithDevice() : renderNoDevice(), deviceName ? renderWithDevice() : renderNoDevice()
); );
} }
@ -155,9 +166,11 @@ class SidebarRuntimeItem extends PureComponent {
runtimeId, runtimeId,
} = this.props; } = this.props;
const connectionStatus = isConnected ? const connectionStatus = isConnected
getString("aboutdebugging-sidebar-runtime-connection-status-connected") : ? getString("aboutdebugging-sidebar-runtime-connection-status-connected")
getString("aboutdebugging-sidebar-runtime-connection-status-disconnected"); : getString(
"aboutdebugging-sidebar-runtime-connection-status-disconnected"
);
return SidebarItem( return SidebarItem(
{ {
@ -168,14 +181,12 @@ class SidebarRuntimeItem extends PureComponent {
{ {
className: "sidebar-runtime-item__container", className: "sidebar-runtime-item__container",
}, },
dom.img( dom.img({
{ className: "sidebar-runtime-item__icon ",
className: "sidebar-runtime-item__icon ", src: icon,
src: icon, alt: connectionStatus,
alt: connectionStatus, title: connectionStatus,
title: connectionStatus, }),
}
),
this.renderName(), this.renderName(),
!isUnavailable && !isConnected ? this.renderConnectButton() : null !isUnavailable && !isConnected ? this.renderConnectButton() : null
), ),
@ -196,7 +207,7 @@ class SidebarRuntimeItem extends PureComponent {
MESSAGE_LEVEL.WARNING, MESSAGE_LEVEL.WARNING,
"about-debugging-sidebar-item-connect-button-connection-not-responding", "about-debugging-sidebar-item-connect-button-connection-not-responding",
"qa-connection-not-responding" "qa-connection-not-responding"
), )
); );
} }
} }

View file

@ -4,8 +4,10 @@
"use strict"; "use strict";
const { CONNECTION_TYPES, DEBUG_TARGET_TYPES } = const {
require("devtools/client/shared/remote-debugging/constants"); CONNECTION_TYPES,
DEBUG_TARGET_TYPES,
} = require("devtools/client/shared/remote-debugging/constants");
const actionTypes = { const actionTypes = {
ADB_ADDON_INSTALL_START: "ADB_ADDON_INSTALL_START", ADB_ADDON_INSTALL_START: "ADB_ADDON_INSTALL_START",
@ -58,9 +60,12 @@ const actionTypes = {
UNWATCH_RUNTIME_FAILURE: "UNWATCH_RUNTIME_FAILURE", UNWATCH_RUNTIME_FAILURE: "UNWATCH_RUNTIME_FAILURE",
UNWATCH_RUNTIME_START: "UNWATCH_RUNTIME_START", UNWATCH_RUNTIME_START: "UNWATCH_RUNTIME_START",
UNWATCH_RUNTIME_SUCCESS: "UNWATCH_RUNTIME_SUCCESS", UNWATCH_RUNTIME_SUCCESS: "UNWATCH_RUNTIME_SUCCESS",
UPDATE_CONNECTION_PROMPT_SETTING_FAILURE: "UPDATE_CONNECTION_PROMPT_SETTING_FAILURE", UPDATE_CONNECTION_PROMPT_SETTING_FAILURE:
UPDATE_CONNECTION_PROMPT_SETTING_START: "UPDATE_CONNECTION_PROMPT_SETTING_START", "UPDATE_CONNECTION_PROMPT_SETTING_FAILURE",
UPDATE_CONNECTION_PROMPT_SETTING_SUCCESS: "UPDATE_CONNECTION_PROMPT_SETTING_SUCCESS", UPDATE_CONNECTION_PROMPT_SETTING_START:
"UPDATE_CONNECTION_PROMPT_SETTING_START",
UPDATE_CONNECTION_PROMPT_SETTING_SUCCESS:
"UPDATE_CONNECTION_PROMPT_SETTING_SUCCESS",
UPDATE_RUNTIME_MULTIE10S_FAILURE: "UPDATE_RUNTIME_MULTIE10S_FAILURE", UPDATE_RUNTIME_MULTIE10S_FAILURE: "UPDATE_RUNTIME_MULTIE10S_FAILURE",
UPDATE_RUNTIME_MULTIE10S_START: "UPDATE_RUNTIME_MULTIE10S_START", UPDATE_RUNTIME_MULTIE10S_START: "UPDATE_RUNTIME_MULTIE10S_START",
UPDATE_RUNTIME_MULTIE10S_SUCCESS: "UPDATE_RUNTIME_MULTIE10S_SUCCESS", UPDATE_RUNTIME_MULTIE10S_SUCCESS: "UPDATE_RUNTIME_MULTIE10S_SUCCESS",
@ -142,16 +147,20 @@ const USB_STATES = {
}; };
// flatten constants // flatten constants
module.exports = Object.assign({}, { module.exports = Object.assign(
DEBUG_TARGETS, {},
DEBUG_TARGET_PANE, {
ICON_LABEL_LEVEL, DEBUG_TARGETS,
MESSAGE_LEVEL, DEBUG_TARGET_PANE,
PAGE_TYPES, ICON_LABEL_LEVEL,
PREFERENCES, MESSAGE_LEVEL,
RUNTIME_PREFERENCE, PAGE_TYPES,
RUNTIMES, PREFERENCES,
SERVICE_WORKER_FETCH_STATES, RUNTIME_PREFERENCE,
SERVICE_WORKER_STATUSES, RUNTIMES,
USB_STATES, SERVICE_WORKER_FETCH_STATES,
}, actionTypes); SERVICE_WORKER_STATUSES,
USB_STATES,
},
actionTypes
);

View file

@ -6,9 +6,14 @@
const Services = require("Services"); const Services = require("Services");
const { applyMiddleware, createStore } = require("devtools/client/shared/vendor/redux"); const {
applyMiddleware,
createStore,
} = require("devtools/client/shared/vendor/redux");
const { thunk } = require("devtools/client/shared/redux/middleware/thunk.js"); const { thunk } = require("devtools/client/shared/redux/middleware/thunk.js");
const { waitUntilService } = require("devtools/client/shared/redux/middleware/wait-service.js"); const {
waitUntilService,
} = require("devtools/client/shared/redux/middleware/wait-service.js");
const rootReducer = require("./reducers/index"); const rootReducer = require("./reducers/index");
const { DebugTargetsState } = require("./reducers/debug-targets-state"); const { DebugTargetsState } = require("./reducers/debug-targets-state");
@ -21,7 +26,9 @@ const extensionComponentDataMiddleware = require("./middleware/extension-compone
const processComponentDataMiddleware = require("./middleware/process-component-data"); const processComponentDataMiddleware = require("./middleware/process-component-data");
const tabComponentDataMiddleware = require("./middleware/tab-component-data"); const tabComponentDataMiddleware = require("./middleware/tab-component-data");
const workerComponentDataMiddleware = require("./middleware/worker-component-data"); const workerComponentDataMiddleware = require("./middleware/worker-component-data");
const { getDebugTargetCollapsibilities } = require("./modules/debug-target-collapsibilities"); const {
getDebugTargetCollapsibilities,
} = require("./modules/debug-target-collapsibilities");
const { getNetworkLocations } = require("./modules/network-locations"); const { getNetworkLocations } = require("./modules/network-locations");
const { PREFERENCES } = require("./constants"); const { PREFERENCES } = require("./constants");
@ -33,15 +40,17 @@ function configureStore() {
ui: getUiState(), ui: getUiState(),
}; };
const middleware = applyMiddleware(thunk, const middleware = applyMiddleware(
debugTargetListenerMiddleware, thunk,
errorLoggingMiddleware, debugTargetListenerMiddleware,
eventRecordingMiddleware, errorLoggingMiddleware,
extensionComponentDataMiddleware, eventRecordingMiddleware,
processComponentDataMiddleware, extensionComponentDataMiddleware,
tabComponentDataMiddleware, processComponentDataMiddleware,
workerComponentDataMiddleware, tabComponentDataMiddleware,
waitUntilService); workerComponentDataMiddleware,
waitUntilService
);
return createStore(rootReducer, initialState, middleware); return createStore(rootReducer, initialState, middleware);
} }
@ -49,8 +58,10 @@ function configureStore() {
function getUiState() { function getUiState() {
const collapsibilities = getDebugTargetCollapsibilities(); const collapsibilities = getDebugTargetCollapsibilities();
const locations = getNetworkLocations(); const locations = getNetworkLocations();
const showHiddenAddons = Services.prefs.getBoolPref(PREFERENCES.SHOW_HIDDEN_ADDONS, const showHiddenAddons = Services.prefs.getBoolPref(
false); PREFERENCES.SHOW_HIDDEN_ADDONS,
false
);
return new UiState(locations, collapsibilities, showHiddenAddons); return new UiState(locations, collapsibilities, showHiddenAddons);
} }

View file

@ -18,7 +18,9 @@ function errorLoggingMiddleware() {
// All failure actions should dispatch an error object instead of a message. // All failure actions should dispatch an error object instead of a message.
// We allow some flexibility to still provide some error logging. // We allow some flexibility to still provide some error logging.
console.error(`[ACTION FAILED] ${action.type}: ${error}`); console.error(`[ACTION FAILED] ${action.type}: ${error}`);
console.error(`[ACTION FAILED] ${action.type} should dispatch the error object!`); console.error(
`[ACTION FAILED] ${action.type} should dispatch the error object!`
);
} }
if (error.stack) { if (error.stack) {

View file

@ -7,7 +7,9 @@
const Telemetry = require("devtools/client/shared/telemetry"); const Telemetry = require("devtools/client/shared/telemetry");
loader.lazyGetter(this, "telemetry", () => new Telemetry()); loader.lazyGetter(this, "telemetry", () => new Telemetry());
// This is a unique id that should be submitted with all about:debugging events. // This is a unique id that should be submitted with all about:debugging events.
loader.lazyGetter(this, "sessionId", () => parseInt(telemetry.msSinceProcessStart(), 10)); loader.lazyGetter(this, "sessionId", () =>
parseInt(telemetry.msSinceProcessStart(), 10)
);
const { const {
CONNECT_RUNTIME_CANCEL, CONNECT_RUNTIME_CANCEL,
@ -32,7 +34,7 @@ const {
function recordEvent(method, details) { function recordEvent(method, details) {
// Add the session id to the event details. // Add the session id to the event details.
const eventDetails = Object.assign({}, details, { "session_id": sessionId }); const eventDetails = Object.assign({}, details, { session_id: sessionId });
telemetry.recordEvent(method, "aboutdebugging", null, eventDetails); telemetry.recordEvent(method, "aboutdebugging", null, eventDetails);
} }
@ -56,14 +58,14 @@ function getRuntimeEventExtras(runtime) {
const { extra, runtimeDetails } = runtime; const { extra, runtimeDetails } = runtime;
// deviceName can be undefined for non-usb devices, but we should not log "undefined". // deviceName can be undefined for non-usb devices, but we should not log "undefined".
const deviceName = extra && extra.deviceName || ""; const deviceName = (extra && extra.deviceName) || "";
const runtimeShortName = runtime.type === RUNTIMES.USB ? runtime.name : ""; const runtimeShortName = runtime.type === RUNTIMES.USB ? runtime.name : "";
const runtimeName = runtimeDetails && runtimeDetails.info.name || ""; const runtimeName = (runtimeDetails && runtimeDetails.info.name) || "";
return { return {
"connection_type": runtime.type, connection_type: runtime.type,
"device_name": deviceName, device_name: deviceName,
"runtime_id": getTelemetryRuntimeId(runtime.id), runtime_id: getTelemetryRuntimeId(runtime.id),
"runtime_name": runtimeName || runtimeShortName, runtime_name: runtimeName || runtimeShortName,
}; };
} }
@ -74,13 +76,16 @@ function onConnectRuntimeSuccess(action, store) {
} }
// When we just connected to a runtime, the runtimeDetails are not in the store yet, // When we just connected to a runtime, the runtimeDetails are not in the store yet,
// so we merge it here to retrieve the expected telemetry data. // so we merge it here to retrieve the expected telemetry data.
const storeRuntime = findRuntimeById(action.runtime.id, store.getState().runtimes); const storeRuntime = findRuntimeById(
action.runtime.id,
store.getState().runtimes
);
const runtime = Object.assign({}, storeRuntime, { const runtime = Object.assign({}, storeRuntime, {
runtimeDetails: action.runtime.runtimeDetails, runtimeDetails: action.runtime.runtimeDetails,
}); });
const extras = Object.assign({}, getRuntimeEventExtras(runtime), { const extras = Object.assign({}, getRuntimeEventExtras(runtime), {
"runtime_os": action.runtime.runtimeDetails.info.os, runtime_os: action.runtime.runtimeDetails.info.os,
"runtime_version": action.runtime.runtimeDetails.info.version, runtime_version: action.runtime.runtimeDetails.info.version,
}); });
recordEvent("runtime_connected", extras); recordEvent("runtime_connected", extras);
} }
@ -114,13 +119,18 @@ function onRemoteRuntimesUpdated(action, store) {
// Using device names as unique IDs is inaccurate. See Bug 1544582. // Using device names as unique IDs is inaccurate. See Bug 1544582.
const oldDeviceNames = new Set(oldRuntimes.map(r => r.extra.deviceName)); const oldDeviceNames = new Set(oldRuntimes.map(r => r.extra.deviceName));
for (const oldDeviceName of oldDeviceNames) { for (const oldDeviceName of oldDeviceNames) {
const newRuntime = newRuntimes.find(r => r.extra.deviceName === oldDeviceName); const newRuntime = newRuntimes.find(
const oldRuntime = oldRuntimes.find(r => r.extra.deviceName === oldDeviceName); r => r.extra.deviceName === oldDeviceName
const isUnplugged = newRuntime && newRuntime.isUnplugged && !oldRuntime.isUnplugged; );
const oldRuntime = oldRuntimes.find(
r => r.extra.deviceName === oldDeviceName
);
const isUnplugged =
newRuntime && newRuntime.isUnplugged && !oldRuntime.isUnplugged;
if (oldDeviceName && (!newRuntime || isUnplugged)) { if (oldDeviceName && (!newRuntime || isUnplugged)) {
recordEvent("device_removed", { recordEvent("device_removed", {
"connection_type": action.runtimeType, connection_type: action.runtimeType,
"device_name": oldDeviceName, device_name: oldDeviceName,
}); });
} }
} }
@ -137,14 +147,19 @@ function onRemoteRuntimesUpdated(action, store) {
// Using device names as unique IDs is inaccurate. See Bug 1544582. // Using device names as unique IDs is inaccurate. See Bug 1544582.
const newDeviceNames = new Set(newRuntimes.map(r => r.extra.deviceName)); const newDeviceNames = new Set(newRuntimes.map(r => r.extra.deviceName));
for (const newDeviceName of newDeviceNames) { for (const newDeviceName of newDeviceNames) {
const newRuntime = newRuntimes.find(r => r.extra.deviceName === newDeviceName); const newRuntime = newRuntimes.find(
const oldRuntime = oldRuntimes.find(r => r.extra.deviceName === newDeviceName); r => r.extra.deviceName === newDeviceName
const isPlugged = oldRuntime && oldRuntime.isUnplugged && !newRuntime.isUnplugged; );
const oldRuntime = oldRuntimes.find(
r => r.extra.deviceName === newDeviceName
);
const isPlugged =
oldRuntime && oldRuntime.isUnplugged && !newRuntime.isUnplugged;
if (newDeviceName && (!oldRuntime || isPlugged)) { if (newDeviceName && (!oldRuntime || isPlugged)) {
recordEvent("device_added", { recordEvent("device_added", {
"connection_type": action.runtimeType, connection_type: action.runtimeType,
"device_name": newDeviceName, device_name: newDeviceName,
}); });
} }
} }
@ -158,10 +173,10 @@ function recordConnectionAttempt(connectionId, runtimeId, status, store) {
} }
recordEvent("connection_attempt", { recordEvent("connection_attempt", {
"connection_id": connectionId, connection_id: connectionId,
"connection_type": runtime.type, connection_type: runtime.type,
"runtime_id": getTelemetryRuntimeId(runtimeId), runtime_id: getTelemetryRuntimeId(runtimeId),
"status": status, status: status,
}); });
} }
@ -172,19 +187,39 @@ function eventRecordingMiddleware(store) {
return next => action => { return next => action => {
switch (action.type) { switch (action.type) {
case CONNECT_RUNTIME_CANCEL: case CONNECT_RUNTIME_CANCEL:
recordConnectionAttempt(action.connectionId, action.id, "cancelled", store); recordConnectionAttempt(
action.connectionId,
action.id,
"cancelled",
store
);
break; break;
case CONNECT_RUNTIME_FAILURE: case CONNECT_RUNTIME_FAILURE:
recordConnectionAttempt(action.connectionId, action.id, "failed", store); recordConnectionAttempt(
action.connectionId,
action.id,
"failed",
store
);
break; break;
case CONNECT_RUNTIME_NOT_RESPONDING: case CONNECT_RUNTIME_NOT_RESPONDING:
recordConnectionAttempt(action.connectionId, action.id, "not responding", store); recordConnectionAttempt(
action.connectionId,
action.id,
"not responding",
store
);
break; break;
case CONNECT_RUNTIME_START: case CONNECT_RUNTIME_START:
recordConnectionAttempt(action.connectionId, action.id, "start", store); recordConnectionAttempt(action.connectionId, action.id, "start", store);
break; break;
case CONNECT_RUNTIME_SUCCESS: case CONNECT_RUNTIME_SUCCESS:
recordConnectionAttempt(action.connectionId, action.runtime.id, "success", store); recordConnectionAttempt(
action.connectionId,
action.runtime.id,
"success",
store
);
onConnectRuntimeSuccess(action, store); onConnectRuntimeSuccess(action, store);
break; break;
case DISCONNECT_RUNTIME_SUCCESS: case DISCONNECT_RUNTIME_SUCCESS:
@ -194,11 +229,11 @@ function eventRecordingMiddleware(store) {
onRemoteRuntimesUpdated(action, store); onRemoteRuntimesUpdated(action, store);
break; break;
case SELECT_PAGE_SUCCESS: case SELECT_PAGE_SUCCESS:
recordEvent("select_page", { "page_type": action.page }); recordEvent("select_page", { page_type: action.page });
break; break;
case SHOW_PROFILER_DIALOG: case SHOW_PROFILER_DIALOG:
recordEvent("show_profiler", { recordEvent("show_profiler", {
"runtime_id": getCurrentRuntimeIdForTelemetry(store), runtime_id: getCurrentRuntimeIdForTelemetry(store),
}); });
break; break;
case TELEMETRY_RECORD: case TELEMETRY_RECORD:
@ -206,13 +241,15 @@ function eventRecordingMiddleware(store) {
if (method) { if (method) {
recordEvent(method, details); recordEvent(method, details);
} else { } else {
console.error(`[RECORD EVENT FAILED] ${action.type}: no "method" property`); console.error(
`[RECORD EVENT FAILED] ${action.type}: no "method" property`
);
} }
break; break;
case UPDATE_CONNECTION_PROMPT_SETTING_SUCCESS: case UPDATE_CONNECTION_PROMPT_SETTING_SUCCESS:
recordEvent("update_conn_prompt", { recordEvent("update_conn_prompt", {
"prompt_enabled": `${action.connectionPromptEnabled}`, prompt_enabled: `${action.connectionPromptEnabled}`,
"runtime_id": getCurrentRuntimeIdForTelemetry(store), runtime_id: getCurrentRuntimeIdForTelemetry(store),
}); });
break; break;
} }

View file

@ -4,10 +4,7 @@
"use strict"; "use strict";
const { const { DEBUG_TARGETS, REQUEST_EXTENSIONS_SUCCESS } = require("../constants");
DEBUG_TARGETS,
REQUEST_EXTENSIONS_SUCCESS,
} = require("../constants");
const { const {
getExtensionUuid, getExtensionUuid,
@ -32,9 +29,11 @@ const extensionComponentDataMiddleware = store => next => action => {
function getFilePath(extension) { function getFilePath(extension) {
// Only show file system paths, and only for temporarily installed add-ons. // Only show file system paths, and only for temporarily installed add-ons.
if (!extension.temporarilyInstalled || if (
!extension.url || !extension.temporarilyInstalled ||
!extension.url.startsWith("file://")) { !extension.url ||
!extension.url.startsWith("file://")
) {
return null; return null;
} }
@ -44,9 +43,19 @@ function getFilePath(extension) {
function toComponentData(extensions) { function toComponentData(extensions) {
return extensions.map(extension => { return extensions.map(extension => {
const type = DEBUG_TARGETS.EXTENSION; const type = DEBUG_TARGETS.EXTENSION;
const { actor, iconDataURL, iconURL, id, manifestURL, name, warnings } = extension; const {
actor,
iconDataURL,
iconURL,
id,
manifestURL,
name,
warnings,
} = extension;
const icon = const icon =
iconDataURL || iconURL || "chrome://mozapps/skin/extensions/extensionGeneric.svg"; iconDataURL ||
iconURL ||
"chrome://mozapps/skin/extensions/extensionGeneric.svg";
const location = getFilePath(extension); const location = getFilePath(extension);
const uuid = getExtensionUuid(extension); const uuid = getExtensionUuid(extension);
return { return {

View file

@ -6,10 +6,7 @@
const { l10n } = require("../modules/l10n"); const { l10n } = require("../modules/l10n");
const { const { DEBUG_TARGETS, REQUEST_PROCESSES_SUCCESS } = require("../constants");
DEBUG_TARGETS,
REQUEST_PROCESSES_SUCCESS,
} = require("../constants");
/** /**
* This middleware converts tabs object that get from DebuggerClient.listProcesses() to * This middleware converts tabs object that get from DebuggerClient.listProcesses() to
@ -18,7 +15,9 @@ const {
const processComponentDataMiddleware = store => next => action => { const processComponentDataMiddleware = store => next => action => {
switch (action.type) { switch (action.type) {
case REQUEST_PROCESSES_SUCCESS: { case REQUEST_PROCESSES_SUCCESS: {
const mainProcessComponentData = toMainProcessComponentData(action.mainProcess); const mainProcessComponentData = toMainProcessComponentData(
action.mainProcess
);
action.processes = [mainProcessComponentData]; action.processes = [mainProcessComponentData];
break; break;
} }
@ -32,7 +31,9 @@ function toMainProcessComponentData(process) {
const id = process.processFront.actorID; const id = process.processFront.actorID;
const icon = "chrome://devtools/skin/images/aboutdebugging-process-icon.svg"; const icon = "chrome://devtools/skin/images/aboutdebugging-process-icon.svg";
const name = l10n.getString("about-debugging-main-process-name"); const name = l10n.getString("about-debugging-main-process-name");
const description = l10n.getString("about-debugging-main-process-description2"); const description = l10n.getString(
"about-debugging-main-process-description2"
);
return { return {
name, name,

View file

@ -4,10 +4,7 @@
"use strict"; "use strict";
const { const { DEBUG_TARGETS, REQUEST_TABS_SUCCESS } = require("../constants");
DEBUG_TARGETS,
REQUEST_TABS_SUCCESS,
} = require("../constants");
/** /**
* This middleware converts tabs object that get from DebuggerClient.listTabs() to data * This middleware converts tabs object that get from DebuggerClient.listTabs() to data
@ -29,7 +26,9 @@ function toComponentData(tabs) {
const type = DEBUG_TARGETS.TAB; const type = DEBUG_TARGETS.TAB;
const id = tab.outerWindowID; const id = tab.outerWindowID;
const icon = tab.favicon const icon = tab.favicon
? `data:image/png;base64,${ btoa(String.fromCharCode.apply(String, tab.favicon)) }` ? `data:image/png;base64,${btoa(
String.fromCharCode.apply(String, tab.favicon)
)}`
: "chrome://devtools/skin/images/globe.svg"; : "chrome://devtools/skin/images/globe.svg";
const name = tab.title || tab.url; const name = tab.title || tab.url;
const url = tab.url; const url = tab.url;

View file

@ -49,20 +49,15 @@ function toComponentData(workers, isServiceWorker) {
const type = DEBUG_TARGETS.WORKER; const type = DEBUG_TARGETS.WORKER;
const icon = "chrome://devtools/skin/images/debugging-workers.svg"; const icon = "chrome://devtools/skin/images/debugging-workers.svg";
let { fetch } = worker; let { fetch } = worker;
const { const { id, name, registrationFront, scope, subscription } = worker;
id,
name,
registrationFront,
scope,
subscription,
} = worker;
let pushServiceEndpoint = null; let pushServiceEndpoint = null;
let status = null; let status = null;
if (isServiceWorker) { if (isServiceWorker) {
fetch = fetch ? SERVICE_WORKER_FETCH_STATES.LISTENING fetch = fetch
: SERVICE_WORKER_FETCH_STATES.NOT_LISTENING; ? SERVICE_WORKER_FETCH_STATES.LISTENING
: SERVICE_WORKER_FETCH_STATES.NOT_LISTENING;
status = getServiceWorkerStatus(worker); status = getServiceWorkerStatus(worker);
pushServiceEndpoint = subscription ? subscription.endpoint : null; pushServiceEndpoint = subscription ? subscription.endpoint : null;
} }

View file

@ -4,12 +4,12 @@
"use strict"; "use strict";
const { checkVersionCompatibility } = const {
require("devtools/client/shared/remote-debugging/version-checker"); checkVersionCompatibility,
} = require("devtools/client/shared/remote-debugging/version-checker");
const { RUNTIME_PREFERENCE } = require("../constants"); const { RUNTIME_PREFERENCE } = require("../constants");
const { WorkersListener } = const { WorkersListener } = require("devtools/client/shared/workers-listener");
require("devtools/client/shared/workers-listener");
const PREF_TYPES = { const PREF_TYPES = {
BOOL: "BOOL", BOOL: "BOOL",
@ -25,10 +25,7 @@ const PREF_TO_TYPE = {
}; };
// Some events are fired by mainRoot rather than client. // Some events are fired by mainRoot rather than client.
const MAIN_ROOT_EVENTS = [ const MAIN_ROOT_EVENTS = ["addonListChanged", "tabListChanged"];
"addonListChanged",
"tabListChanged",
];
/** /**
* The ClientWrapper class is used to isolate aboutdebugging from the DevTools client API * The ClientWrapper class is used to isolate aboutdebugging from the DevTools client API
@ -107,8 +104,10 @@ class ClientWrapper {
async getPreference(prefName, defaultValue) { async getPreference(prefName, defaultValue) {
if (typeof defaultValue === "undefined") { if (typeof defaultValue === "undefined") {
throw new Error("Default value is mandatory for getPreference, the actor will " + throw new Error(
"throw if the preference is not set on the target runtime"); "Default value is mandatory for getPreference, the actor will " +
"throw if the preference is not set on the target runtime"
);
} }
const prefType = PREF_TO_TYPE[prefName]; const prefType = PREF_TO_TYPE[prefName];
@ -150,7 +149,11 @@ class ClientWrapper {
} }
async listWorkers() { async listWorkers() {
const { other, service, shared } = await this.client.mainRoot.listAllWorkers(); const {
other,
service,
shared,
} = await this.client.mainRoot.listAllWorkers();
return { return {
otherWorkers: other, otherWorkers: other,

View file

@ -10,12 +10,18 @@ const Services = require("Services");
// Process target debugging is disabled by default. // Process target debugging is disabled by default.
function isProcessDebuggingSupported() { function isProcessDebuggingSupported() {
return Services.prefs.getBoolPref(PREFERENCES.PROCESS_DEBUGGING_ENABLED, false); return Services.prefs.getBoolPref(
PREFERENCES.PROCESS_DEBUGGING_ENABLED,
false
);
} }
// Process target debugging is disabled by default. // Process target debugging is disabled by default.
function isLocalTabDebuggingSupported() { function isLocalTabDebuggingSupported() {
return Services.prefs.getBoolPref(PREFERENCES.LOCAL_TAB_DEBUGGING_ENABLED, false); return Services.prefs.getBoolPref(
PREFERENCES.LOCAL_TAB_DEBUGGING_ENABLED,
false
);
} }
// Installing extensions can be disabled in enterprise policy. // Installing extensions can be disabled in enterprise policy.
@ -33,12 +39,15 @@ const ALL_DEBUG_TARGET_PANES = [
DEBUG_TARGET_PANE.SERVICE_WORKER, DEBUG_TARGET_PANE.SERVICE_WORKER,
DEBUG_TARGET_PANE.SHARED_WORKER, DEBUG_TARGET_PANE.SHARED_WORKER,
DEBUG_TARGET_PANE.TAB, DEBUG_TARGET_PANE.TAB,
...(isTemporaryExtensionSupported() ? [DEBUG_TARGET_PANE.TEMPORARY_EXTENSION] : []), ...(isTemporaryExtensionSupported()
? [DEBUG_TARGET_PANE.TEMPORARY_EXTENSION]
: []),
]; ];
// All debug target panes except temporary extensions // All debug target panes except temporary extensions
const REMOTE_DEBUG_TARGET_PANES = ALL_DEBUG_TARGET_PANES.filter(p => const REMOTE_DEBUG_TARGET_PANES = ALL_DEBUG_TARGET_PANES.filter(
p !== DEBUG_TARGET_PANE.TEMPORARY_EXTENSION); p => p !== DEBUG_TARGET_PANE.TEMPORARY_EXTENSION
);
const THIS_FIREFOX_DEBUG_TARGET_PANES = ALL_DEBUG_TARGET_PANES const THIS_FIREFOX_DEBUG_TARGET_PANES = ALL_DEBUG_TARGET_PANES
// Main process debugging is not available for This Firefox. // Main process debugging is not available for This Firefox.
@ -59,6 +68,8 @@ const SUPPORTED_TARGET_PANE_BY_RUNTIME = {
* a DEBUG_TARGET but INSTALLED_EXTENSION and TEMPORARY_EXTENSION are DEBUG_TARGET_PANES. * a DEBUG_TARGET but INSTALLED_EXTENSION and TEMPORARY_EXTENSION are DEBUG_TARGET_PANES.
*/ */
function isSupportedDebugTargetPane(runtimeType, debugTargetPaneKey) { function isSupportedDebugTargetPane(runtimeType, debugTargetPaneKey) {
return SUPPORTED_TARGET_PANE_BY_RUNTIME[runtimeType].includes(debugTargetPaneKey); return SUPPORTED_TARGET_PANE_BY_RUNTIME[runtimeType].includes(
debugTargetPaneKey
);
} }
exports.isSupportedDebugTargetPane = isSupportedDebugTargetPane; exports.isSupportedDebugTargetPane = isSupportedDebugTargetPane;

View file

@ -6,11 +6,20 @@
const { Cc, Ci } = require("chrome"); const { Cc, Ci } = require("chrome");
const Services = require("Services"); const Services = require("Services");
loader.lazyImporter(this, "AddonManager", "resource://gre/modules/AddonManager.jsm"); loader.lazyImporter(
loader.lazyRequireGetter(this, "FileUtils", "resource://gre/modules/FileUtils.jsm", true); this,
"AddonManager",
"resource://gre/modules/AddonManager.jsm"
);
loader.lazyRequireGetter(
this,
"FileUtils",
"resource://gre/modules/FileUtils.jsm",
true
);
const {Toolbox} = require("devtools/client/framework/toolbox"); const { Toolbox } = require("devtools/client/framework/toolbox");
const {gDevTools} = require("devtools/client/framework/devtools"); const { gDevTools } = require("devtools/client/framework/devtools");
const { PREFERENCES } = require("../constants"); const { PREFERENCES } = require("../constants");
@ -91,8 +100,10 @@ exports.openTemporaryExtension = function(win, message) {
// Try to set the last directory used as "displayDirectory". // Try to set the last directory used as "displayDirectory".
try { try {
const lastDirPath = const lastDirPath = Services.prefs.getCharPref(
Services.prefs.getCharPref(PREFERENCES.TEMPORARY_EXTENSION_PATH, ""); PREFERENCES.TEMPORARY_EXTENSION_PATH,
""
);
const lastDir = new FileUtils.File(lastDirPath); const lastDir = new FileUtils.File(lastDirPath);
fp.displayDirectory = lastDir; fp.displayDirectory = lastDir;
} catch (e) { } catch (e) {
@ -106,13 +117,19 @@ exports.openTemporaryExtension = function(win, message) {
let file = fp.file; let file = fp.file;
// AddonManager.installTemporaryAddon accepts either // AddonManager.installTemporaryAddon accepts either
// addon directory or final xpi file. // addon directory or final xpi file.
if (!file.isDirectory() && if (
!file.leafName.endsWith(".xpi") && !file.leafName.endsWith(".zip")) { !file.isDirectory() &&
!file.leafName.endsWith(".xpi") &&
!file.leafName.endsWith(".zip")
) {
file = file.parent; file = file.parent;
} }
// We are about to resolve, store the path to the file for the next call. // We are about to resolve, store the path to the file for the next call.
Services.prefs.setCharPref(PREFERENCES.TEMPORARY_EXTENSION_PATH, file.path); Services.prefs.setCharPref(
PREFERENCES.TEMPORARY_EXTENSION_PATH,
file.path
);
resolve(file); resolve(file);
}); });

View file

@ -4,7 +4,9 @@
"use strict"; "use strict";
const { FluentL10n } = require("devtools/client/shared/fluent-l10n/fluent-l10n"); const {
FluentL10n,
} = require("devtools/client/shared/fluent-l10n/fluent-l10n");
// exports a singleton, which will be used across all aboutdebugging-new modules // exports a singleton, which will be used across all aboutdebugging-new modules
exports.l10n = new FluentL10n(); exports.l10n = new FluentL10n();

View file

@ -51,8 +51,10 @@ function addNetworkLocation(location) {
const locationsSet = new Set(locations); const locationsSet = new Set(locations);
locationsSet.add(location); locationsSet.add(location);
Services.prefs.setStringPref(NETWORK_LOCATIONS_PREF, Services.prefs.setStringPref(
JSON.stringify([...locationsSet])); NETWORK_LOCATIONS_PREF,
JSON.stringify([...locationsSet])
);
} }
exports.addNetworkLocation = addNetworkLocation; exports.addNetworkLocation = addNetworkLocation;
@ -61,7 +63,9 @@ function removeNetworkLocation(location) {
const locationsSet = new Set(locations); const locationsSet = new Set(locations);
locationsSet.delete(location); locationsSet.delete(location);
Services.prefs.setStringPref(NETWORK_LOCATIONS_PREF, Services.prefs.setStringPref(
JSON.stringify([...locationsSet])); NETWORK_LOCATIONS_PREF,
JSON.stringify([...locationsSet])
);
} }
exports.removeNetworkLocation = removeNetworkLocation; exports.removeNetworkLocation = removeNetworkLocation;

View file

@ -8,8 +8,9 @@ const { prepareTCPConnection } = require("devtools/shared/adb/commands/index");
const { DebuggerClient } = require("devtools/shared/client/debugger-client"); const { DebuggerClient } = require("devtools/shared/client/debugger-client");
const { DebuggerServer } = require("devtools/server/main"); const { DebuggerServer } = require("devtools/server/main");
const { ClientWrapper } = require("./client-wrapper"); const { ClientWrapper } = require("./client-wrapper");
const { remoteClientManager } = const {
require("devtools/client/shared/remote-debugging/remote-client-manager"); remoteClientManager,
} = require("devtools/client/shared/remote-debugging/remote-client-manager");
const { RUNTIMES } = require("../constants"); const { RUNTIMES } = require("../constants");

View file

@ -80,7 +80,8 @@ async function getUSBRuntimes() {
// Get devices found by ADB, but without any available runtime. // Get devices found by ADB, but without any available runtime.
const runtimeDevices = runtimes.map(r => r.deviceId); const runtimeDevices = runtimes.map(r => r.deviceId);
const unavailableRuntimes = adb.getDevices() const unavailableRuntimes = adb
.getDevices()
.filter(d => !runtimeDevices.includes(d.id)) .filter(d => !runtimeDevices.includes(d.id))
.map(d => new UnavailableUsbRuntime(d)); .map(d => new UnavailableUsbRuntime(d));
@ -93,7 +94,9 @@ async function getUSBRuntimes() {
// Get devices previously found by ADB but no longer available. // Get devices previously found by ADB but no longer available.
const currentDevices = allRuntimes.map(r => r.deviceId); const currentDevices = allRuntimes.map(r => r.deviceId);
const detectedDevices = [...devices.keys()]; const detectedDevices = [...devices.keys()];
const unpluggedDevices = detectedDevices.filter(id => !currentDevices.includes(id)); const unpluggedDevices = detectedDevices.filter(
id => !currentDevices.includes(id)
);
const unpluggedRuntimes = unpluggedDevices.map(deviceId => { const unpluggedRuntimes = unpluggedDevices.map(deviceId => {
const deviceName = devices.get(deviceId); const deviceName = devices.get(deviceId);
return new UnpluggedUsbRuntime(deviceId, deviceName); return new UnpluggedUsbRuntime(deviceId, deviceName);

View file

@ -43,7 +43,10 @@ function debugTargetsReducer(state = DebugTargetsState(), action) {
} }
case REQUEST_EXTENSIONS_SUCCESS: { case REQUEST_EXTENSIONS_SUCCESS: {
const { installedExtensions, temporaryExtensions } = action; const { installedExtensions, temporaryExtensions } = action;
return Object.assign({}, state, { installedExtensions, temporaryExtensions }); return Object.assign({}, state, {
installedExtensions,
temporaryExtensions,
});
} }
case REQUEST_PROCESSES_SUCCESS: { case REQUEST_PROCESSES_SUCCESS: {
const { processes } = action; const { processes } = action;
@ -55,18 +58,24 @@ function debugTargetsReducer(state = DebugTargetsState(), action) {
} }
case REQUEST_WORKERS_SUCCESS: { case REQUEST_WORKERS_SUCCESS: {
const { otherWorkers, serviceWorkers, sharedWorkers } = action; const { otherWorkers, serviceWorkers, sharedWorkers } = action;
return Object.assign({}, state, { otherWorkers, serviceWorkers, sharedWorkers }); return Object.assign({}, state, {
otherWorkers,
serviceWorkers,
sharedWorkers,
});
} }
case TEMPORARY_EXTENSION_RELOAD_FAILURE: { case TEMPORARY_EXTENSION_RELOAD_FAILURE: {
const { id, error } = action; const { id, error } = action;
const temporaryExtensions = const temporaryExtensions = updateTemporaryExtension(state, id, {
updateTemporaryExtension(state, id, { reloadError: error.message }); reloadError: error.message,
});
return Object.assign({}, state, { temporaryExtensions }); return Object.assign({}, state, { temporaryExtensions });
} }
case TEMPORARY_EXTENSION_RELOAD_START: { case TEMPORARY_EXTENSION_RELOAD_START: {
const { id } = action; const { id } = action;
const temporaryExtensions = const temporaryExtensions = updateTemporaryExtension(state, id, {
updateTemporaryExtension(state, id, { reloadError: null }); reloadError: null,
});
return Object.assign({}, state, { temporaryExtensions }); return Object.assign({}, state, { temporaryExtensions });
} }

View file

@ -19,12 +19,11 @@ const {
THIS_FIREFOX_RUNTIME_CREATED, THIS_FIREFOX_RUNTIME_CREATED,
} = require("../constants"); } = require("../constants");
const { const { findRuntimeById } = require("../modules/runtimes-state-helper");
findRuntimeById,
} = require("../modules/runtimes-state-helper");
const { remoteClientManager } = const {
require("devtools/client/shared/remote-debugging/remote-client-manager"); remoteClientManager,
} = require("devtools/client/shared/remote-debugging/remote-client-manager");
// Map between known runtime types and nodes in the runtimes state. // Map between known runtime types and nodes in the runtimes state.
const TYPE_TO_RUNTIMES_KEY = { const TYPE_TO_RUNTIMES_KEY = {
@ -146,8 +145,9 @@ function runtimesReducer(state = RuntimesState(), action) {
const { connectionPromptEnabled } = action; const { connectionPromptEnabled } = action;
const { id: runtimeId } = action.runtime; const { id: runtimeId } = action.runtime;
const runtime = findRuntimeById(runtimeId, state); const runtime = findRuntimeById(runtimeId, state);
const runtimeDetails = const runtimeDetails = Object.assign({}, runtime.runtimeDetails, {
Object.assign({}, runtime.runtimeDetails, { connectionPromptEnabled }); connectionPromptEnabled,
});
return _updateRuntimeById(runtimeId, { runtimeDetails }, state); return _updateRuntimeById(runtimeId, { runtimeDetails }, state);
} }
@ -155,8 +155,9 @@ function runtimesReducer(state = RuntimesState(), action) {
const { isMultiE10s } = action; const { isMultiE10s } = action;
const { id: runtimeId } = action.runtime; const { id: runtimeId } = action.runtime;
const runtime = findRuntimeById(runtimeId, state); const runtime = findRuntimeById(runtimeId, state);
const runtimeDetails = const runtimeDetails = Object.assign({}, runtime.runtimeDetails, {
Object.assign({}, runtime.runtimeDetails, { isMultiE10s }); isMultiE10s,
});
return _updateRuntimeById(runtimeId, { runtimeDetails }, state); return _updateRuntimeById(runtimeId, { runtimeDetails }, state);
} }

View file

@ -18,8 +18,11 @@ const {
USB_RUNTIMES_SCAN_SUCCESS, USB_RUNTIMES_SCAN_SUCCESS,
} = require("../constants"); } = require("../constants");
function UiState(locations = [], debugTargetCollapsibilities = {}, function UiState(
showHiddenAddons = false) { locations = [],
debugTargetCollapsibilities = {},
showHiddenAddons = false
) {
return { return {
adbAddonStatus: null, adbAddonStatus: null,
debugTargetCollapsibilities, debugTargetCollapsibilities,
@ -47,7 +50,9 @@ function uiReducer(state = UiState(), action) {
case DEBUG_TARGET_COLLAPSIBILITY_UPDATED: { case DEBUG_TARGET_COLLAPSIBILITY_UPDATED: {
const { isCollapsed, key } = action; const { isCollapsed, key } = action;
const debugTargetCollapsibilities = new Map(state.debugTargetCollapsibilities); const debugTargetCollapsibilities = new Map(
state.debugTargetCollapsibilities
);
debugTargetCollapsibilities.set(key, isCollapsed); debugTargetCollapsibilities.set(key, isCollapsed);
return Object.assign({}, state, { debugTargetCollapsibilities }); return Object.assign({}, state, { debugTargetCollapsibilities });
} }

View file

@ -8,8 +8,11 @@ const debugTargetTypes = require("./debug-target");
const runtimeTypes = require("./runtime"); const runtimeTypes = require("./runtime");
const uiTypes = require("./ui"); const uiTypes = require("./ui");
module.exports = Object.assign({}, { module.exports = Object.assign(
...debugTargetTypes, {},
...runtimeTypes, {
...uiTypes, ...debugTargetTypes,
}); ...runtimeTypes,
...uiTypes,
}
);

View file

@ -6,7 +6,9 @@
const PropTypes = require("devtools/client/shared/vendor/react-prop-types"); const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const { ClientWrapper } = require("../modules/client-wrapper"); const { ClientWrapper } = require("../modules/client-wrapper");
const { COMPATIBILITY_STATUS } = require("devtools/client/shared/remote-debugging/version-checker"); const {
COMPATIBILITY_STATUS,
} = require("devtools/client/shared/remote-debugging/version-checker");
const runtimeInfo = { const runtimeInfo = {
// device name which is running the runtime, // device name which is running the runtime,

View file

@ -12,12 +12,14 @@ function makeCollapsibilitiesType(isRequired) {
return (props, propName, componentName, _, propFullName) => { return (props, propName, componentName, _, propFullName) => {
if (isRequired && props[propName] === null) { if (isRequired && props[propName] === null) {
return new Error( return new Error(
`Missing prop ${propFullName} marked as required in ${componentName}`); `Missing prop ${propFullName} marked as required in ${componentName}`
);
} }
const error = new Error( const error = new Error(
`Invalid prop ${propFullName} (${props[propName]}) supplied to ` + `Invalid prop ${propFullName} (${props[propName]}) supplied to ` +
`${componentName}. Collapsibilities needs to be a Map<DEBUG_TARGET_PANE, bool>`); `${componentName}. Collapsibilities needs to be a Map<DEBUG_TARGET_PANE, bool>`
);
const map = props[propName]; const map = props[propName];
@ -27,8 +29,9 @@ function makeCollapsibilitiesType(isRequired) {
} }
// check that the keys refer to debug target panes // check that the keys refer to debug target panes
const areKeysValid = [...map.keys()] const areKeysValid = [...map.keys()].every(x =>
.every(x => Object.values(DEBUG_TARGET_PANE).includes(x)); Object.values(DEBUG_TARGET_PANE).includes(x)
);
// check that the values are boolean // check that the values are boolean
const areValuesValid = [...map.values()].every(x => typeof x === "boolean"); const areValuesValid = [...map.values()].every(x => typeof x === "boolean");
// error if values or keys fail their checks // error if values or keys fail their checks
@ -44,13 +47,16 @@ function makeLocationType(isRequired) {
return (props, propName, componentName, _, propFullName) => { return (props, propName, componentName, _, propFullName) => {
if (isRequired && props[propName] === null) { if (isRequired && props[propName] === null) {
return new Error( return new Error(
`Missing prop ${propFullName} marked as required in ${componentName}`); `Missing prop ${propFullName} marked as required in ${componentName}`
);
} }
// check that location is a string with a semicolon in it // check that location is a string with a semicolon in it
if (!/\:/.test(props[propName])) { if (!/\:/.test(props[propName])) {
return new Error(`Invalid prop ${propFullName} (${props[propName]}) supplied to ` + return new Error(
`${componentName}. Location needs to be a string with a host:port format`); `Invalid prop ${propFullName} (${props[propName]}) supplied to ` +
`${componentName}. Location needs to be a string with a host:port format`
);
} }
return null; return null;

View file

@ -7,7 +7,9 @@ Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-addons.js", this);
// There are shutdown issues for which multiple rejections are left uncaught. // There are shutdown issues for which multiple rejections are left uncaught.
// See bug 1018184 for resolving these issues. // See bug 1018184 for resolving these issues.
const { PromiseTestUtils } = ChromeUtils.import("resource://testing-common/PromiseTestUtils.jsm"); const { PromiseTestUtils } = ChromeUtils.import(
"resource://testing-common/PromiseTestUtils.jsm"
);
PromiseTestUtils.whitelistRejectionsGlobally(/File closed/); PromiseTestUtils.whitelistRejectionsGlobally(/File closed/);
// Avoid test timeouts that can occur while waiting for the "addon-console-works" message. // Avoid test timeouts that can occur while waiting for the "addon-console-works" message.
@ -29,19 +31,28 @@ add_task(async function testWebExtensionsToolboxWebConsole() {
const { document, tab, window } = await openAboutDebugging(); const { document, tab, window } = await openAboutDebugging();
await selectThisFirefoxPage(document, window.AboutDebugging.store); await selectThisFirefoxPage(document, window.AboutDebugging.store);
await installTemporaryExtensionFromXPI({ await installTemporaryExtensionFromXPI(
background: function() { {
window.myWebExtensionAddonFunction = function() { background: function() {
console.log("Background page function called", window.myWebExtensionAddonFunction = function() {
this.browser.runtime.getManifest()); console.log(
}; "Background page function called",
this.browser.runtime.getManifest()
);
};
},
id: ADDON_ID,
name: ADDON_NAME,
}, },
id: ADDON_ID, document
name: ADDON_NAME, );
}, document);
const { devtoolsTab, devtoolsWindow } = const { devtoolsTab, devtoolsWindow } = await openAboutDevtoolsToolbox(
await openAboutDevtoolsToolbox(document, tab, window, ADDON_NAME); document,
tab,
window,
ADDON_NAME
);
const toolbox = getToolbox(devtoolsWindow); const toolbox = getToolbox(devtoolsWindow);
const onToolboxClose = gDevTools.once("toolbox-destroyed"); const onToolboxClose = gDevTools.once("toolbox-destroyed");
@ -60,9 +71,8 @@ add_task(async function testWebExtensionsToolboxWebConsole() {
function toolboxTestScript(toolbox, devtoolsTab) { function toolboxTestScript(toolbox, devtoolsTab) {
function findMessages(hud, text, selector = ".message") { function findMessages(hud, text, selector = ".message") {
const messages = hud.ui.outputNode.querySelectorAll(selector); const messages = hud.ui.outputNode.querySelectorAll(selector);
const elements = Array.prototype.filter.call( const elements = Array.prototype.filter.call(messages, el =>
messages, el.textContent.includes(text)
(el) => el.textContent.includes(text)
); );
return elements; return elements;
} }
@ -73,7 +83,8 @@ function toolboxTestScript(toolbox, devtoolsTab) {
} }
} }
toolbox.selectTool("webconsole") toolbox
.selectTool("webconsole")
.then(async console => { .then(async console => {
const { hud } = console; const { hud } = console;
const { jsterm } = hud; const { jsterm } = hud;

View file

@ -11,40 +11,53 @@ add_task(async () => {
await enableExtensionDebugging(); await enableExtensionDebugging();
info("The debugger should show the source codes of extension even if " + info(
"devtools.chrome.enabled and devtools.debugger.remote-enabled are off"); "The debugger should show the source codes of extension even if " +
"devtools.chrome.enabled and devtools.debugger.remote-enabled are off"
);
await pushPref("devtools.chrome.enabled", false); await pushPref("devtools.chrome.enabled", false);
await pushPref("devtools.debugger.remote-enabled", false); await pushPref("devtools.debugger.remote-enabled", false);
const { document, tab, window } = await openAboutDebugging(); const { document, tab, window } = await openAboutDebugging();
await selectThisFirefoxPage(document, window.AboutDebugging.store); await selectThisFirefoxPage(document, window.AboutDebugging.store);
await installTemporaryExtensionFromXPI({ await installTemporaryExtensionFromXPI(
background: function() { {
window.someRandomMethodName = () => { background: function() {
// This will not be referred from anywhere. window.someRandomMethodName = () => {
// However this is necessary to show as the source code in the debugger. // This will not be referred from anywhere.
}; // However this is necessary to show as the source code in the debugger.
};
},
id: EXTENSION_ID,
name: EXTENSION_NAME,
}, },
id: EXTENSION_ID, document
name: EXTENSION_NAME, );
}, document);
const { devtoolsTab, devtoolsWindow } = const { devtoolsTab, devtoolsWindow } = await openAboutDevtoolsToolbox(
await openAboutDevtoolsToolbox(document, tab, window, EXTENSION_NAME); document,
tab,
window,
EXTENSION_NAME
);
const toolbox = getToolbox(devtoolsWindow); const toolbox = getToolbox(devtoolsWindow);
await toolbox.selectTool("jsdebugger"); await toolbox.selectTool("jsdebugger");
const { panelWin } = toolbox.getCurrentPanel(); const { panelWin } = toolbox.getCurrentPanel();
info("Check the state of redux"); info("Check the state of redux");
ok(panelWin.dbg.store.getState().debuggee.isWebExtension, ok(
"isWebExtension flag in debuggee is true"); panelWin.dbg.store.getState().debuggee.isWebExtension,
"isWebExtension flag in debuggee is true"
);
info("Check whether the element displays correctly"); info("Check whether the element displays correctly");
const sourceList = panelWin.document.querySelector(".sources-list"); const sourceList = panelWin.document.querySelector(".sources-list");
ok(sourceList, "Source list element displays correctly"); ok(sourceList, "Source list element displays correctly");
ok(sourceList.textContent.includes("temporary-web-extension"), ok(
"Extension name displays correctly"); sourceList.textContent.includes("temporary-web-extension"),
"Extension name displays correctly"
);
await closeAboutDevtoolsToolbox(document, devtoolsTab, window); await closeAboutDevtoolsToolbox(document, devtoolsTab, window);
await removeTemporaryExtension(EXTENSION_NAME, document); await removeTemporaryExtension(EXTENSION_NAME, document);

View file

@ -7,7 +7,9 @@ Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-addons.js", this);
// There are shutdown issues for which multiple rejections are left uncaught. // There are shutdown issues for which multiple rejections are left uncaught.
// See bug 1018184 for resolving these issues. // See bug 1018184 for resolving these issues.
const { PromiseTestUtils } = ChromeUtils.import("resource://testing-common/PromiseTestUtils.jsm"); const { PromiseTestUtils } = ChromeUtils.import(
"resource://testing-common/PromiseTestUtils.jsm"
);
PromiseTestUtils.whitelistRejectionsGlobally(/File closed/); PromiseTestUtils.whitelistRejectionsGlobally(/File closed/);
// Avoid test timeouts that can occur while waiting for the "addon-console-works" message. // Avoid test timeouts that can occur while waiting for the "addon-console-works" message.
@ -29,17 +31,24 @@ add_task(async function testWebExtensionsToolboxWebConsole() {
const { document, tab, window } = await openAboutDebugging(); const { document, tab, window } = await openAboutDebugging();
await selectThisFirefoxPage(document, window.AboutDebugging.store); await selectThisFirefoxPage(document, window.AboutDebugging.store);
await installTemporaryExtensionFromXPI({ await installTemporaryExtensionFromXPI(
background: function() { {
document.body.innerText = "Background Page Body Test Content"; background: function() {
document.body.innerText = "Background Page Body Test Content";
},
id: ADDON_ID,
name: ADDON_NAME,
}, },
id: ADDON_ID, document
name: ADDON_NAME, );
}, document);
info("Open a toolbox to debug the addon"); info("Open a toolbox to debug the addon");
const { devtoolsTab, devtoolsWindow } = const { devtoolsTab, devtoolsWindow } = await openAboutDevtoolsToolbox(
await openAboutDevtoolsToolbox(document, tab, window, ADDON_NAME); document,
tab,
window,
ADDON_NAME
);
const toolbox = getToolbox(devtoolsWindow); const toolbox = getToolbox(devtoolsWindow);
const onToolboxClose = gDevTools.once("toolbox-destroyed"); const onToolboxClose = gDevTools.once("toolbox-destroyed");
@ -56,18 +65,19 @@ add_task(async function testWebExtensionsToolboxWebConsole() {
}); });
async function toolboxTestScript(toolbox, devtoolsTab) { async function toolboxTestScript(toolbox, devtoolsTab) {
toolbox.selectTool("inspector") toolbox
.selectTool("inspector")
.then(inspector => { .then(inspector => {
return inspector.walker.querySelector(inspector.walker.rootNode, "body"); return inspector.walker.querySelector(inspector.walker.rootNode, "body");
}) })
.then((nodeActor) => { .then(nodeActor => {
if (!nodeActor) { if (!nodeActor) {
throw new Error("nodeActor not found"); throw new Error("nodeActor not found");
} }
dump("Got a nodeActor\n"); dump("Got a nodeActor\n");
if (!(nodeActor.inlineTextChild)) { if (!nodeActor.inlineTextChild) {
throw new Error("inlineTextChild not found"); throw new Error("inlineTextChild not found");
} }
@ -86,7 +96,7 @@ async function toolboxTestScript(toolbox, devtoolsTab) {
return Promise.resolve(); return Promise.resolve();
}) })
.then(() => removeTab(devtoolsTab)) .then(() => removeTab(devtoolsTab))
.catch((error) => { .catch(error => {
dump("Error while running code in the browser toolbox process:\n"); dump("Error while running code in the browser toolbox process:\n");
dump(error + "\n"); dump(error + "\n");
dump("stack:\n" + error.stack + "\n"); dump("stack:\n" + error.stack + "\n");

View file

@ -7,7 +7,9 @@ Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-addons.js", this);
// There are shutdown issues for which multiple rejections are left uncaught. // There are shutdown issues for which multiple rejections are left uncaught.
// See bug 1018184 for resolving these issues. // See bug 1018184 for resolving these issues.
const { PromiseTestUtils } = ChromeUtils.import("resource://testing-common/PromiseTestUtils.jsm"); const { PromiseTestUtils } = ChromeUtils.import(
"resource://testing-common/PromiseTestUtils.jsm"
);
PromiseTestUtils.whitelistRejectionsGlobally(/File closed/); PromiseTestUtils.whitelistRejectionsGlobally(/File closed/);
const ADDON_NOBG_ID = "test-devtools-webextension-nobg@mozilla.org"; const ADDON_NOBG_ID = "test-devtools-webextension-nobg@mozilla.org";
@ -26,15 +28,22 @@ add_task(async function testWebExtensionsToolboxNoBackgroundPage() {
const store = window.AboutDebugging.store; const store = window.AboutDebugging.store;
await selectThisFirefoxPage(document, window.AboutDebugging.store); await selectThisFirefoxPage(document, window.AboutDebugging.store);
await installTemporaryExtensionFromXPI({ await installTemporaryExtensionFromXPI(
// Do not pass any `background` script. {
id: ADDON_NOBG_ID, // Do not pass any `background` script.
name: ADDON_NOBG_NAME, id: ADDON_NOBG_ID,
}, document); name: ADDON_NOBG_NAME,
},
document
);
info("Open a toolbox to debug the addon"); info("Open a toolbox to debug the addon");
const { devtoolsTab, devtoolsWindow } = const { devtoolsTab, devtoolsWindow } = await openAboutDevtoolsToolbox(
await openAboutDevtoolsToolbox(document, tab, window, ADDON_NOBG_NAME); document,
tab,
window,
ADDON_NOBG_NAME
);
const toolbox = getToolbox(devtoolsWindow); const toolbox = getToolbox(devtoolsWindow);
const onToolboxClose = gDevTools.once("toolbox-destroyed"); const onToolboxClose = gDevTools.once("toolbox-destroyed");
@ -60,31 +69,37 @@ async function toolboxTestScript(toolbox, devtoolsTab) {
throw new Error("Toolbox doesn't have the expected target"); throw new Error("Toolbox doesn't have the expected target");
} }
toolbox.selectTool("inspector").then(async inspector => { toolbox
let nodeActor; .selectTool("inspector")
.then(async inspector => {
let nodeActor;
dump(`Wait the fallback window to be fully loaded\n`); dump(`Wait the fallback window to be fully loaded\n`);
await asyncWaitUntil(async () => { await asyncWaitUntil(async () => {
nodeActor = await inspector.walker.querySelector(inspector.walker.rootNode, "h1"); nodeActor = await inspector.walker.querySelector(
return nodeActor && nodeActor.inlineTextChild; inspector.walker.rootNode,
"h1"
);
return nodeActor && nodeActor.inlineTextChild;
});
dump("Got a nodeActor with an inline text child\n");
const expectedValue = "Your addon does not have any document opened yet.";
const actualValue = nodeActor.inlineTextChild._form.nodeValue;
if (actualValue !== expectedValue) {
throw new Error(
`mismatched inlineTextchild value: "${actualValue}" !== "${expectedValue}"`
);
}
dump("Got the expected inline text content in the selected node\n");
await removeTab(devtoolsTab);
})
.catch(error => {
dump("Error while running code in the browser toolbox process:\n");
dump(error + "\n");
dump("stack:\n" + error.stack + "\n");
}); });
dump("Got a nodeActor with an inline text child\n");
const expectedValue = "Your addon does not have any document opened yet.";
const actualValue = nodeActor.inlineTextChild._form.nodeValue;
if (actualValue !== expectedValue) {
throw new Error(
`mismatched inlineTextchild value: "${actualValue}" !== "${expectedValue}"`
);
}
dump("Got the expected inline text content in the selected node\n");
await removeTab(devtoolsTab);
}).catch((error) => {
dump("Error while running code in the browser toolbox process:\n");
dump(error + "\n");
dump("stack:\n" + error.stack + "\n");
});
} }

View file

@ -7,7 +7,9 @@ Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-addons.js", this);
// There are shutdown issues for which multiple rejections are left uncaught. // There are shutdown issues for which multiple rejections are left uncaught.
// See bug 1018184 for resolving these issues. // See bug 1018184 for resolving these issues.
const { PromiseTestUtils } = ChromeUtils.import("resource://testing-common/PromiseTestUtils.jsm"); const { PromiseTestUtils } = ChromeUtils.import(
"resource://testing-common/PromiseTestUtils.jsm"
);
PromiseTestUtils.whitelistRejectionsGlobally(/File closed/); PromiseTestUtils.whitelistRejectionsGlobally(/File closed/);
// Avoid test timeouts that can occur while waiting for the "addon-console-works" message. // Avoid test timeouts that can occur while waiting for the "addon-console-works" message.
@ -36,13 +38,19 @@ const ADDON_NAME = "test-devtools-webextension";
add_task(async function testWebExtensionsToolboxWebConsole() { add_task(async function testWebExtensionsToolboxWebConsole() {
await enableExtensionDebugging(); await enableExtensionDebugging();
is(Services.prefs.getBoolPref("ui.popup.disable_autohide"), false, is(
"disable_autohide should be initially false"); Services.prefs.getBoolPref("ui.popup.disable_autohide"),
false,
"disable_autohide should be initially false"
);
info("Create promises waiting for the messages emitted by the test addon"); info("Create promises waiting for the messages emitted by the test addon");
let onReadyForOpenPopup; let onReadyForOpenPopup;
let onPopupCustomMessage; let onPopupCustomMessage;
const { Management } = ChromeUtils.import("resource://gre/modules/Extension.jsm", null); const { Management } = ChromeUtils.import(
"resource://gre/modules/Extension.jsm",
null
);
Management.on("startup", function listener(event, extension) { Management.on("startup", function listener(event, extension) {
if (extension.name != ADDON_NAME) { if (extension.name != ADDON_NAME) {
return; return;
@ -53,7 +61,7 @@ add_task(async function testWebExtensionsToolboxWebConsole() {
function waitForExtensionTestMessage(expectedMessage) { function waitForExtensionTestMessage(expectedMessage) {
return new Promise(done => { return new Promise(done => {
extension.on("test-message", function testLogListener(evt, ...args) { extension.on("test-message", function testLogListener(evt, ...args) {
const [message ] = args; const [message] = args;
if (message !== expectedMessage) { if (message !== expectedMessage) {
return; return;
@ -71,27 +79,37 @@ add_task(async function testWebExtensionsToolboxWebConsole() {
// Wait for a notification sent by a script evaluated the test addon via // Wait for a notification sent by a script evaluated the test addon via
// the web console. // the web console.
onPopupCustomMessage = waitForExtensionTestMessage("popupPageFunctionCalled"); onPopupCustomMessage = waitForExtensionTestMessage(
"popupPageFunctionCalled"
);
}); });
const { document, tab, window: aboutDebuggingWindow } = await openAboutDebugging(); const {
await selectThisFirefoxPage(document, aboutDebuggingWindow.AboutDebugging.store); document,
tab,
window: aboutDebuggingWindow,
} = await openAboutDebugging();
await selectThisFirefoxPage(
document,
aboutDebuggingWindow.AboutDebugging.store
);
await installTemporaryExtensionFromXPI({ await installTemporaryExtensionFromXPI(
background: function() { {
const {browser} = this; background: function() {
window.myWebExtensionShowPopup = function() { const { browser } = this;
browser.test.sendMessage("readyForOpenPopup"); window.myWebExtensionShowPopup = function() {
}; browser.test.sendMessage("readyForOpenPopup");
}, };
extraProperties: {
browser_action: {
default_title: "WebExtension Popup Debugging",
default_popup: "popup.html",
}, },
}, extraProperties: {
files: { browser_action: {
"popup.html": `<!DOCTYPE html> default_title: "WebExtension Popup Debugging",
default_popup: "popup.html",
},
},
files: {
"popup.html": `<!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
@ -102,21 +120,29 @@ add_task(async function testWebExtensionsToolboxWebConsole() {
</body> </body>
</html> </html>
`, `,
"popup.js": function() { "popup.js": function() {
const {browser} = this; const { browser } = this;
window.myWebExtensionPopupAddonFunction = function() { window.myWebExtensionPopupAddonFunction = function() {
browser.test.sendMessage("popupPageFunctionCalled", browser.test.sendMessage(
browser.runtime.getManifest()); "popupPageFunctionCalled",
}; browser.runtime.getManifest()
);
};
},
}, },
id: ADDON_ID,
name: ADDON_NAME,
}, },
id: ADDON_ID, document
name: ADDON_NAME, );
}, document);
info("Open a toolbox to debug the addon"); info("Open a toolbox to debug the addon");
const { devtoolsTab, devtoolsWindow } = const { devtoolsTab, devtoolsWindow } = await openAboutDevtoolsToolbox(
await openAboutDevtoolsToolbox(document, tab, aboutDebuggingWindow, ADDON_NAME); document,
tab,
aboutDebuggingWindow,
ADDON_NAME
);
const toolbox = getToolbox(devtoolsWindow); const toolbox = getToolbox(devtoolsWindow);
const onToolboxClose = gDevTools.once("toolbox-destroyed"); const onToolboxClose = gDevTools.once("toolbox-destroyed");
@ -136,14 +162,20 @@ add_task(async function testWebExtensionsToolboxWebConsole() {
const args = await onPopupCustomMessage; const args = await onPopupCustomMessage;
ok(true, "Received console message from the popup page function as expected"); ok(true, "Received console message from the popup page function as expected");
is(args[0], "popupPageFunctionCalled", "Got the expected console message"); is(args[0], "popupPageFunctionCalled", "Got the expected console message");
is(args[1] && args[1].name, ADDON_NAME, is(
"Got the expected manifest from WebExtension API"); args[1] && args[1].name,
ADDON_NAME,
"Got the expected manifest from WebExtension API"
);
info("Wait for the toolbox to close"); info("Wait for the toolbox to close");
await onToolboxClose; await onToolboxClose;
is(Services.prefs.getBoolPref("ui.popup.disable_autohide"), false, is(
"disable_autohide should be reset to false when the toolbox is closed"); Services.prefs.getBoolPref("ui.popup.disable_autohide"),
false,
"disable_autohide should be reset to false when the toolbox is closed"
);
// The test script will not close the toolbox and will timeout if it fails, so reaching // The test script will not close the toolbox and will timeout if it fails, so reaching
// this point in the test is enough to assume the test was successful. // this point in the test is enough to assume the test was successful.
@ -157,7 +189,7 @@ async function toolboxTestScript(toolbox, devtoolsTab) {
let jsterm; let jsterm;
const popupFramePromise = new Promise(resolve => { const popupFramePromise = new Promise(resolve => {
const listener = data => { const listener = data => {
if (data.frames.some(({url}) => url && url.endsWith("popup.html"))) { if (data.frames.some(({ url }) => url && url.endsWith("popup.html"))) {
toolbox.target.off("frame-update", listener); toolbox.target.off("frame-update", listener);
resolve(); resolve();
} }
@ -167,17 +199,23 @@ async function toolboxTestScript(toolbox, devtoolsTab) {
const waitForFrameListUpdate = toolbox.target.once("frame-update"); const waitForFrameListUpdate = toolbox.target.once("frame-update");
toolbox.selectTool("webconsole") toolbox
.then(async (console) => { .selectTool("webconsole")
.then(async console => {
const clickNoAutoHideMenu = () => { const clickNoAutoHideMenu = () => {
return new Promise(resolve => { return new Promise(resolve => {
toolbox.doc.getElementById("toolbox-meatball-menu-button").click(); toolbox.doc.getElementById("toolbox-meatball-menu-button").click();
toolbox.doc.addEventListener("popupshown", () => { toolbox.doc.addEventListener(
const menuItem = "popupshown",
toolbox.doc.getElementById("toolbox-meatball-menu-noautohide"); () => {
menuItem.click(); const menuItem = toolbox.doc.getElementById(
resolve(); "toolbox-meatball-menu-noautohide"
}, { once: true }); );
menuItem.click();
resolve();
},
{ once: true }
);
}); });
}; };
@ -206,9 +244,13 @@ async function toolboxTestScript(toolbox, devtoolsTab) {
throw Error(`Number of frames found is wrong: ${frames.length} != 2`); throw Error(`Number of frames found is wrong: ${frames.length} != 2`);
} }
const popupFrameBtn = frames.filter((frame) => { const popupFrameBtn = frames
return frame.querySelector(".label").textContent.endsWith("popup.html"); .filter(frame => {
}).pop(); return frame
.querySelector(".label")
.textContent.endsWith("popup.html");
})
.pop();
if (!popupFrameBtn) { if (!popupFrameBtn) {
throw Error("Extension Popup frame not found in the listed frames"); throw Error("Extension Popup frame not found in the listed frames");
@ -218,7 +260,10 @@ async function toolboxTestScript(toolbox, devtoolsTab) {
popupFrameBtn.click(); popupFrameBtn.click();
// Clicking the menu item may do highlighting. // Clicking the menu item may do highlighting.
await waitUntil(() => toolbox.highlighter); await waitUntil(() => toolbox.highlighter);
await Promise.race([toolbox.highlighter.once("node-highlight"), wait(1000)]); await Promise.race([
toolbox.highlighter.once("node-highlight"),
wait(1000),
]);
await waitForNavigated; await waitForNavigated;
await jsterm.execute("myWebExtensionPopupAddonFunction()"); await jsterm.execute("myWebExtensionPopupAddonFunction()");
@ -227,7 +272,7 @@ async function toolboxTestScript(toolbox, devtoolsTab) {
await removeTab(devtoolsTab); await removeTab(devtoolsTab);
}) })
.catch((error) => { .catch(error => {
dump("Error while running code in the browser toolbox process:\n"); dump("Error while running code in the browser toolbox process:\n");
dump(error + "\n"); dump(error + "\n");
dump("stack:\n" + error.stack + "\n"); dump("stack:\n" + error.stack + "\n");

View file

@ -13,8 +13,10 @@ Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-adb.js", this);
// Test that manifest URLs for addon targets show the manifest correctly in a new tab. // Test that manifest URLs for addon targets show the manifest correctly in a new tab.
// This test reuses the ADB extension to be sure to have a valid manifest URL to open. // This test reuses the ADB extension to be sure to have a valid manifest URL to open.
add_task(async function() { add_task(async function() {
await pushPref("devtools.remote.adb.extensionURL", await pushPref(
CHROME_URL_ROOT + "resources/test-adb-extension/adb-extension-#OS#.xpi"); "devtools.remote.adb.extensionURL",
CHROME_URL_ROOT + "resources/test-adb-extension/adb-extension-#OS#.xpi"
);
await checkAdbNotRunning(); await checkAdbNotRunning();
const { document, tab, window } = await openAboutDebugging(); const { document, tab, window } = await openAboutDebugging();
@ -40,13 +42,21 @@ add_task(async function() {
await BrowserTestUtils.browserLoaded(target.linkedBrowser); await BrowserTestUtils.browserLoaded(target.linkedBrowser);
info("Retrieve the text content of the new tab"); info("Retrieve the text content of the new tab");
const textContent = await ContentTask.spawn(target.linkedBrowser, {}, function() { const textContent = await ContentTask.spawn(
return content.wrappedJSObject.document.body.textContent; target.linkedBrowser,
}); {},
function() {
return content.wrappedJSObject.document.body.textContent;
}
);
const manifestObject = JSON.parse(textContent); const manifestObject = JSON.parse(textContent);
ok(manifestObject, "The displayed content is a valid JSON object"); ok(manifestObject, "The displayed content is a valid JSON object");
is(manifestObject.name, ABD_ADDON_NAME, "Manifest tab shows the expected content"); is(
manifestObject.name,
ABD_ADDON_NAME,
"Manifest tab shows the expected content"
);
info("Close the manifest.json tab"); info("Close the manifest.json tab");
await removeTab(target); await removeTab(target);

View file

@ -26,7 +26,11 @@ add_task(async function() {
info("Test addons in runtime page for USB client"); info("Test addons in runtime page for USB client");
await connectToRuntime(USB_RUNTIME_DEVICE_NAME, document); await connectToRuntime(USB_RUNTIME_DEVICE_NAME, document);
await selectRuntime(USB_RUNTIME_DEVICE_NAME, USB_RUNTIME_APP_NAME, document); await selectRuntime(USB_RUNTIME_DEVICE_NAME, USB_RUNTIME_APP_NAME, document);
await testAddonsOnMockedRemoteClient(usbClient, mocks.thisFirefoxClient, document); await testAddonsOnMockedRemoteClient(
usbClient,
mocks.thisFirefoxClient,
document
);
info("Prepare Network client mock"); info("Prepare Network client mock");
const networkClient = mocks.createNetworkRuntime(NETWORK_RUNTIME_HOST, { const networkClient = mocks.createNetworkRuntime(NETWORK_RUNTIME_HOST, {
@ -36,7 +40,11 @@ add_task(async function() {
info("Test addons in runtime page for Network client"); info("Test addons in runtime page for Network client");
await connectToRuntime(NETWORK_RUNTIME_HOST, document); await connectToRuntime(NETWORK_RUNTIME_HOST, document);
await selectRuntime(NETWORK_RUNTIME_HOST, NETWORK_RUNTIME_APP_NAME, document); await selectRuntime(NETWORK_RUNTIME_HOST, NETWORK_RUNTIME_APP_NAME, document);
await testAddonsOnMockedRemoteClient(networkClient, mocks.thisFirefoxClient, document); await testAddonsOnMockedRemoteClient(
networkClient,
mocks.thisFirefoxClient,
document
);
await removeTab(tab); await removeTab(tab);
}); });
@ -44,11 +52,17 @@ add_task(async function() {
/** /**
* Check that addons are visible in the runtime page for a remote client (USB or network). * Check that addons are visible in the runtime page for a remote client (USB or network).
*/ */
async function testAddonsOnMockedRemoteClient(remoteClient, firefoxClient, document) { async function testAddonsOnMockedRemoteClient(
remoteClient,
firefoxClient,
document
) {
const extensionPane = getDebugTargetPane("Extensions", document); const extensionPane = getDebugTargetPane("Extensions", document);
info("Check an empty target pane message is displayed"); info("Check an empty target pane message is displayed");
ok(extensionPane.querySelector(".qa-debug-target-list-empty"), ok(
"Extensions list is empty"); extensionPane.querySelector(".qa-debug-target-list-empty"),
"Extensions list is empty"
);
info("Add an extension to the remote client"); info("Add an extension to the remote client");
const addon = { name: "Test extension name", debuggable: true }; const addon = { name: "Test extension name", debuggable: true };
@ -56,9 +70,14 @@ async function testAddonsOnMockedRemoteClient(remoteClient, firefoxClient, docum
remoteClient._eventEmitter.emit("addonListChanged"); remoteClient._eventEmitter.emit("addonListChanged");
info("Wait until the extension appears"); info("Wait until the extension appears");
await waitUntil(() => !extensionPane.querySelector(".qa-debug-target-list-empty")); await waitUntil(
() => !extensionPane.querySelector(".qa-debug-target-list-empty")
);
const extensionTarget = findDebugTargetByText("Test extension name", document); const extensionTarget = findDebugTargetByText(
"Test extension name",
document
);
ok(extensionTarget, "Extension target appeared for the remote runtime"); ok(extensionTarget, "Extension target appeared for the remote runtime");
// The goal here is to check that runtimes addons are only updated when the remote // The goal here is to check that runtimes addons are only updated when the remote
@ -78,12 +97,20 @@ async function testAddonsOnMockedRemoteClient(remoteClient, firefoxClient, docum
const testTab = { outerWindowID: 0, url: "http://some.random/url.com" }; const testTab = { outerWindowID: 0, url: "http://some.random/url.com" };
remoteClient.listTabs = () => [testTab]; remoteClient.listTabs = () => [testTab];
remoteClient._eventEmitter.emit("tabListChanged"); remoteClient._eventEmitter.emit("tabListChanged");
await waitUntil(() => findDebugTargetByText("http://some.random/url.com", document)); await waitUntil(() =>
findDebugTargetByText("http://some.random/url.com", document)
);
ok(findDebugTargetByText("Test extension name", document), ok(
"The test extension is still visible"); findDebugTargetByText("Test extension name", document),
"The test extension is still visible"
);
info("Emit `addonListChanged` on remoteClient and wait for the target list to update"); info(
"Emit `addonListChanged` on remoteClient and wait for the target list to update"
);
remoteClient._eventEmitter.emit("addonListChanged"); remoteClient._eventEmitter.emit("addonListChanged");
await waitUntil(() => !findDebugTargetByText("Test extension name", document)); await waitUntil(
() => !findDebugTargetByText("Test extension name", document)
);
} }

View file

@ -14,38 +14,62 @@ add_task(async function() {
const UPDATED_EXTENSION_NAME = "Temporary web extension (updated)"; const UPDATED_EXTENSION_NAME = "Temporary web extension (updated)";
const EXTENSION_ID = "test-devtools@mozilla.org"; const EXTENSION_ID = "test-devtools@mozilla.org";
const addonFile = await installTemporaryExtensionFromXPI({ const addonFile = await installTemporaryExtensionFromXPI(
id: EXTENSION_ID, {
name: ORIGINAL_EXTENSION_NAME, id: EXTENSION_ID,
}, document); name: ORIGINAL_EXTENSION_NAME,
},
document
);
const originalTarget = findDebugTargetByText(ORIGINAL_EXTENSION_NAME, document); const originalTarget = findDebugTargetByText(
ok(!!originalTarget, "The temporary extension isinstalled with the expected name"); ORIGINAL_EXTENSION_NAME,
document
);
ok(
!!originalTarget,
"The temporary extension isinstalled with the expected name"
);
info("Update the name of the temporary extension in the manifest"); info("Update the name of the temporary extension in the manifest");
updateTemporaryXPI({ id: EXTENSION_ID, name: UPDATED_EXTENSION_NAME }, addonFile); updateTemporaryXPI(
{ id: EXTENSION_ID, name: UPDATED_EXTENSION_NAME },
addonFile
);
info("Click on the reload button for the temporary extension"); info("Click on the reload button for the temporary extension");
const reloadButton = const reloadButton = originalTarget.querySelector(
originalTarget.querySelector(".qa-temporary-extension-reload-button"); ".qa-temporary-extension-reload-button"
);
reloadButton.click(); reloadButton.click();
info("Wait until the debug target with the original extension name disappears"); info(
await waitUntil(() => !findDebugTargetByText(ORIGINAL_EXTENSION_NAME, document)); "Wait until the debug target with the original extension name disappears"
);
await waitUntil(
() => !findDebugTargetByText(ORIGINAL_EXTENSION_NAME, document)
);
info("Wait until the debug target with the updated extension name appears"); info("Wait until the debug target with the updated extension name appears");
await waitUntil(() => findDebugTargetByText(UPDATED_EXTENSION_NAME, document)); await waitUntil(() =>
findDebugTargetByText(UPDATED_EXTENSION_NAME, document)
);
const updatedTarget = findDebugTargetByText(UPDATED_EXTENSION_NAME, document); const updatedTarget = findDebugTargetByText(UPDATED_EXTENSION_NAME, document);
ok(!!updatedTarget, "The temporary extension name has been updated"); ok(!!updatedTarget, "The temporary extension name has been updated");
info("Click on the remove button for the temporary extension"); info("Click on the remove button for the temporary extension");
const removeButton = const removeButton = updatedTarget.querySelector(
updatedTarget.querySelector(".qa-temporary-extension-remove-button"); ".qa-temporary-extension-remove-button"
);
removeButton.click(); removeButton.click();
info("Wait until the debug target with the updated extension name disappears"); info(
await waitUntil(() => !findDebugTargetByText(UPDATED_EXTENSION_NAME, document)); "Wait until the debug target with the updated extension name disappears"
);
await waitUntil(
() => !findDebugTargetByText(UPDATED_EXTENSION_NAME, document)
);
await removeTab(tab); await removeTab(tab);
}); });
@ -57,18 +81,36 @@ add_task(async function() {
const { document, tab, window } = await openAboutDebugging(); const { document, tab, window } = await openAboutDebugging();
await selectThisFirefoxPage(document, window.AboutDebugging.store); await selectThisFirefoxPage(document, window.AboutDebugging.store);
await installRegularExtension("resources/packaged-extension/packaged-extension.xpi"); await installRegularExtension(
"resources/packaged-extension/packaged-extension.xpi"
);
info("Wait until extension appears in about:debugging"); info("Wait until extension appears in about:debugging");
await waitUntil(() => findDebugTargetByText(PACKAGED_EXTENSION_NAME, document)); await waitUntil(() =>
findDebugTargetByText(PACKAGED_EXTENSION_NAME, document)
);
const target = findDebugTargetByText(PACKAGED_EXTENSION_NAME, document); const target = findDebugTargetByText(PACKAGED_EXTENSION_NAME, document);
const reloadButton = target.querySelector(".qa-temporary-extension-reload-button"); const reloadButton = target.querySelector(
ok(!reloadButton, "No reload button displayed for a regularly installed extension"); ".qa-temporary-extension-reload-button"
);
ok(
!reloadButton,
"No reload button displayed for a regularly installed extension"
);
const removeButton = target.querySelector(".qa-temporary-extension-remove-button"); const removeButton = target.querySelector(
ok(!removeButton, "No remove button displayed for a regularly installed extension"); ".qa-temporary-extension-remove-button"
);
ok(
!removeButton,
"No remove button displayed for a regularly installed extension"
);
await removeExtension(PACKAGED_EXTENSION_ID, PACKAGED_EXTENSION_NAME, document); await removeExtension(
PACKAGED_EXTENSION_ID,
PACKAGED_EXTENSION_NAME,
document
);
await removeTab(tab); await removeTab(tab);
}); });

View file

@ -14,10 +14,13 @@ add_task(async function() {
const { document, tab, window } = await openAboutDebugging(); const { document, tab, window } = await openAboutDebugging();
await selectThisFirefoxPage(document, window.AboutDebugging.store); await selectThisFirefoxPage(document, window.AboutDebugging.store);
await installTemporaryExtensionFromXPI({ await installTemporaryExtensionFromXPI(
id: EXTENSION_ID, {
name: EXTENSION_NAME, id: EXTENSION_ID,
}, document); name: EXTENSION_NAME,
},
document
);
info("Wait until a debug target item appears"); info("Wait until a debug target item appears");
await waitUntil(() => findDebugTargetByText(EXTENSION_NAME, document)); await waitUntil(() => findDebugTargetByText(EXTENSION_NAME, document));
@ -42,15 +45,26 @@ add_task(async function() {
const { document, tab, window } = await openAboutDebugging(); const { document, tab, window } = await openAboutDebugging();
await selectThisFirefoxPage(document, window.AboutDebugging.store); await selectThisFirefoxPage(document, window.AboutDebugging.store);
await installRegularExtension("resources/packaged-extension/packaged-extension.xpi"); await installRegularExtension(
"resources/packaged-extension/packaged-extension.xpi"
);
info("Wait until extension appears in about:debugging"); info("Wait until extension appears in about:debugging");
await waitUntil(() => findDebugTargetByText(PACKAGED_EXTENSION_NAME, document)); await waitUntil(() =>
findDebugTargetByText(PACKAGED_EXTENSION_NAME, document)
);
const target = findDebugTargetByText(PACKAGED_EXTENSION_NAME, document); const target = findDebugTargetByText(PACKAGED_EXTENSION_NAME, document);
const tmpIdMessage = target.querySelector(".qa-temporary-id-message"); const tmpIdMessage = target.querySelector(".qa-temporary-id-message");
ok(!tmpIdMessage, "No temporary id message is displayed for a regular extension"); ok(
!tmpIdMessage,
"No temporary id message is displayed for a regular extension"
);
await removeExtension(PACKAGED_EXTENSION_ID, PACKAGED_EXTENSION_NAME, document); await removeExtension(
PACKAGED_EXTENSION_ID,
PACKAGED_EXTENSION_NAME,
document
);
await removeTab(tab); await removeTab(tab);
}); });

View file

@ -11,7 +11,8 @@ Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-addons.js", this);
* extensions. * extensions.
*/ */
const INVALID_JSON_EXTENSION_PATH = "resources/bad-extensions/invalid-json/manifest.json"; const INVALID_JSON_EXTENSION_PATH =
"resources/bad-extensions/invalid-json/manifest.json";
const INVALID_PROP_EXTENSION_PATH = const INVALID_PROP_EXTENSION_PATH =
"resources/bad-extensions/invalid-property/manifest.json"; "resources/bad-extensions/invalid-property/manifest.json";
const EXTENSION_PATH = "resources/test-temporary-extension/manifest.json"; const EXTENSION_PATH = "resources/test-temporary-extension/manifest.json";
@ -23,15 +24,22 @@ add_task(async function testInvalidJsonExtension() {
const { document, tab, window } = await openAboutDebugging(); const { document, tab, window } = await openAboutDebugging();
await selectThisFirefoxPage(document, window.AboutDebugging.store); await selectThisFirefoxPage(document, window.AboutDebugging.store);
const installError = await installBadExtension(INVALID_JSON_EXTENSION_PATH, document); const installError = await installBadExtension(
ok(installError.textContent.includes("JSON.parse: unexpected keyword"), INVALID_JSON_EXTENSION_PATH,
"The expected installation error is displayed: " + installError.textContent); document
);
ok(
installError.textContent.includes("JSON.parse: unexpected keyword"),
"The expected installation error is displayed: " + installError.textContent
);
info("Install a valid extension to make the message disappear"); info("Install a valid extension to make the message disappear");
await installTemporaryExtension(EXTENSION_PATH, EXTENSION_NAME, document); await installTemporaryExtension(EXTENSION_PATH, EXTENSION_NAME, document);
info("Wait until the error message disappears"); info("Wait until the error message disappears");
await waitUntil(() => !document.querySelector(".qa-tmp-extension-install-error")); await waitUntil(
() => !document.querySelector(".qa-tmp-extension-install-error")
);
info("Wait for the temporary addon to be displayed as a debug target"); info("Wait for the temporary addon to be displayed as a debug target");
await waitUntil(() => findDebugTargetByText(EXTENSION_NAME, document)); await waitUntil(() => findDebugTargetByText(EXTENSION_NAME, document));
@ -47,13 +55,22 @@ add_task(async function testInvalidPropertyExtension() {
const { document, tab, window } = await openAboutDebugging(); const { document, tab, window } = await openAboutDebugging();
await selectThisFirefoxPage(document, window.AboutDebugging.store); await selectThisFirefoxPage(document, window.AboutDebugging.store);
const installError = await installBadExtension(INVALID_PROP_EXTENSION_PATH, document); const installError = await installBadExtension(
INVALID_PROP_EXTENSION_PATH,
document
);
ok(installError.textContent.includes("Extension is invalid"), ok(
"The basic installation error is displayed: " + installError.textContent); installError.textContent.includes("Extension is invalid"),
ok(installError.textContent.includes( "The basic installation error is displayed: " + installError.textContent
"Reading manifest: Error processing content_scripts.0.matches"), );
"The detailed installation error is also displayed: " + installError.textContent); ok(
installError.textContent.includes(
"Reading manifest: Error processing content_scripts.0.matches"
),
"The detailed installation error is also displayed: " +
installError.textContent
);
await removeTab(tab); await removeTab(tab);
}); });
@ -65,6 +82,8 @@ async function installBadExtension(path, document) {
document.querySelector(".qa-temporary-extension-install-button").click(); document.querySelector(".qa-temporary-extension-install-button").click();
info("Wait until the install error message appears"); info("Wait until the install error message appears");
await waitUntil(() => document.querySelector(".qa-tmp-extension-install-error")); await waitUntil(() =>
document.querySelector(".qa-tmp-extension-install-error")
);
return document.querySelector(".qa-tmp-extension-install-error"); return document.querySelector(".qa-tmp-extension-install-error");
} }

View file

@ -55,7 +55,11 @@ add_task(async function testPreferenceRetrievedWhenInstallingExtension() {
info("Check whether the shown dir is same as the pref"); info("Check whether the shown dir is same as the pref");
const fp = await onFilePickerShown; const fp = await onFilePickerShown;
is(fp.displayDirectory.path, selectedDir, "Shown directory sets as same as the pref"); is(
fp.displayDirectory.path,
selectedDir,
"Shown directory sets as same as the pref"
);
await removeTab(tab); await removeTab(tab);
}); });

View file

@ -13,10 +13,13 @@ add_task(async function() {
const EXTENSION_ID = "test-devtools@mozilla.org"; const EXTENSION_ID = "test-devtools@mozilla.org";
const EXTENSION_NAME = "Temporary web extension"; const EXTENSION_NAME = "Temporary web extension";
let addonFile = await installTemporaryExtensionFromXPI({ let addonFile = await installTemporaryExtensionFromXPI(
id: EXTENSION_ID, {
name: EXTENSION_NAME, id: EXTENSION_ID,
}, document); name: EXTENSION_NAME,
},
document
);
const target = findDebugTargetByText(EXTENSION_NAME, document); const target = findDebugTargetByText(EXTENSION_NAME, document);
ok(!!target, "The temporary extension is installed with the expected name"); ok(!!target, "The temporary extension is installed with the expected name");
@ -25,25 +28,37 @@ add_task(async function() {
addonFile = updateTemporaryXPI({ id: EXTENSION_ID }, addonFile); addonFile = updateTemporaryXPI({ id: EXTENSION_ID }, addonFile);
info("Click on the reload button for the invalid temporary extension"); info("Click on the reload button for the invalid temporary extension");
const waitForError = const waitForError = waitForDispatch(
waitForDispatch(window.AboutDebugging.store, "TEMPORARY_EXTENSION_RELOAD_FAILURE"); window.AboutDebugging.store,
const reloadButton = target.querySelector(".qa-temporary-extension-reload-button"); "TEMPORARY_EXTENSION_RELOAD_FAILURE"
);
const reloadButton = target.querySelector(
".qa-temporary-extension-reload-button"
);
reloadButton.click(); reloadButton.click();
await waitForError; await waitForError;
ok(target.querySelector(".qa-temporary-extension-reload-error"), ok(
"The error message of reloading appears"); target.querySelector(".qa-temporary-extension-reload-error"),
"The error message of reloading appears"
);
info("Click on the reload button for the valid temporary extension"); info("Click on the reload button for the valid temporary extension");
const waitForSuccess = const waitForSuccess = waitForDispatch(
waitForDispatch(window.AboutDebugging.store, "TEMPORARY_EXTENSION_RELOAD_SUCCESS"); window.AboutDebugging.store,
"TEMPORARY_EXTENSION_RELOAD_SUCCESS"
);
updateTemporaryXPI({ id: EXTENSION_ID, name: EXTENSION_NAME }, addonFile); updateTemporaryXPI({ id: EXTENSION_ID, name: EXTENSION_NAME }, addonFile);
reloadButton.click(); reloadButton.click();
await waitForSuccess; await waitForSuccess;
ok(!target.querySelector(".qa-temporary-extension-reload-error"), ok(
"The error message of reloading disappears"); !target.querySelector(".qa-temporary-extension-reload-error"),
"The error message of reloading disappears"
);
info("Click on the remove button for the temporary extension"); info("Click on the remove button for the temporary extension");
const removeButton = target.querySelector(".qa-temporary-extension-remove-button"); const removeButton = target.querySelector(
".qa-temporary-extension-remove-button"
);
removeButton.click(); removeButton.click();
info("Wait until the debug target with the extension disappears"); info("Wait until the debug target with the extension disappears");

View file

@ -14,24 +14,33 @@ add_task(async function() {
const { document, tab, window } = await openAboutDebugging(); const { document, tab, window } = await openAboutDebugging();
await selectThisFirefoxPage(document, window.AboutDebugging.store); await selectThisFirefoxPage(document, window.AboutDebugging.store);
await installTemporaryExtensionFromXPI({ await installTemporaryExtensionFromXPI(
id: EXTENSION_ID, {
name: EXTENSION_NAME, id: EXTENSION_ID,
extraProperties: { name: EXTENSION_NAME,
// This property is not expected in the manifest and should trigger a warning! extraProperties: {
"wrongProperty": {}, // This property is not expected in the manifest and should trigger a warning!
wrongProperty: {},
},
}, },
}, document); document
);
info("Wait until a debug target item appears"); info("Wait until a debug target item appears");
await waitUntil(() => findDebugTargetByText(EXTENSION_NAME, document)); await waitUntil(() => findDebugTargetByText(EXTENSION_NAME, document));
const target = findDebugTargetByText(EXTENSION_NAME, document); const target = findDebugTargetByText(EXTENSION_NAME, document);
const warningMessage = target.querySelector(".qa-message"); const warningMessage = target.querySelector(".qa-message");
ok(!!warningMessage, "A warning message is displayed for the installed addon"); ok(
!!warningMessage,
"A warning message is displayed for the installed addon"
);
const warningText = warningMessage.textContent; const warningText = warningMessage.textContent;
ok(warningText.includes("wrongProperty"), "The warning message mentions wrongProperty"); ok(
warningText.includes("wrongProperty"),
"The warning message mentions wrongProperty"
);
await removeTemporaryExtension(EXTENSION_NAME, document); await removeTemporaryExtension(EXTENSION_NAME, document);
await removeTab(tab); await removeTab(tab);

View file

@ -17,48 +17,66 @@ add_task(async function() {
await selectConnectPage(document); await selectConnectPage(document);
let networkLocations = document.querySelectorAll(".qa-network-location"); let networkLocations = document.querySelectorAll(".qa-network-location");
is(networkLocations.length, 0, "By default, no network locations are displayed"); is(
networkLocations.length,
0,
"By default, no network locations are displayed"
);
info("Check whether error message should show if the input value is invalid"); info("Check whether error message should show if the input value is invalid");
addNetworkLocation(TEST_NETWORK_LOCATION_INVALID, document); addNetworkLocation(TEST_NETWORK_LOCATION_INVALID, document);
await waitUntil(() => await waitUntil(() =>
document.querySelector(".qa-connect-page__network-form__error-message")); document.querySelector(".qa-connect-page__network-form__error-message")
);
info("Wait until the new network location is visible in the list"); info("Wait until the new network location is visible in the list");
addNetworkLocation(TEST_NETWORK_LOCATION, document); addNetworkLocation(TEST_NETWORK_LOCATION, document);
await waitUntil(() => document.querySelectorAll(".qa-network-location").length === 1); await waitUntil(
await waitUntil(() => () => document.querySelectorAll(".qa-network-location").length === 1
!document.querySelector(".qa-connect-page__network-form__error-message")); );
await waitUntil(
() =>
!document.querySelector(".qa-connect-page__network-form__error-message")
);
networkLocations = document.querySelectorAll(".qa-network-location"); networkLocations = document.querySelectorAll(".qa-network-location");
const networkLocationValue = const networkLocationValue = networkLocations[0].querySelector(
networkLocations[0].querySelector(".qa-network-location-value"); ".qa-network-location-value"
is(networkLocationValue.textContent, TEST_NETWORK_LOCATION, );
"Added network location has the expected value"); is(
networkLocationValue.textContent,
TEST_NETWORK_LOCATION,
"Added network location has the expected value"
);
info("Check whether error message should show if the input value was duplicate"); info(
"Check whether error message should show if the input value was duplicate"
);
addNetworkLocation(TEST_NETWORK_LOCATION, document); addNetworkLocation(TEST_NETWORK_LOCATION, document);
await waitUntil(() => await waitUntil(() =>
document.querySelector(".qa-connect-page__network-form__error-message")); document.querySelector(".qa-connect-page__network-form__error-message")
);
info("Wait until the new network location is removed from the list"); info("Wait until the new network location is removed from the list");
removeNetworkLocation(TEST_NETWORK_LOCATION, document); removeNetworkLocation(TEST_NETWORK_LOCATION, document);
await waitUntil(() => document.querySelectorAll(".qa-network-location").length === 0); await waitUntil(
() => document.querySelectorAll(".qa-network-location").length === 0
);
await removeTab(tab); await removeTab(tab);
}); });
function addNetworkLocation(location, document) { function addNetworkLocation(location, document) {
info("Setting a value in the network form input"); info("Setting a value in the network form input");
const networkLocationInput = const networkLocationInput = document.querySelector(".qa-network-form-input");
document.querySelector(".qa-network-form-input");
networkLocationInput.value = ""; networkLocationInput.value = "";
networkLocationInput.focus(); networkLocationInput.focus();
EventUtils.sendString(location, networkLocationInput.ownerGlobal); EventUtils.sendString(location, networkLocationInput.ownerGlobal);
info("Click on network form submit button"); info("Click on network form submit button");
const networkLocationSubmitButton = const networkLocationSubmitButton = document.querySelector(
document.querySelector(".qa-network-form-submit-button"); ".qa-network-form-submit-button"
);
networkLocationSubmitButton.click(); networkLocationSubmitButton.click();
} }
@ -67,8 +85,9 @@ function removeNetworkLocation(location, document) {
ok(networkLocation, "Network location container found."); ok(networkLocation, "Network location container found.");
info("Click on the remove button for the provided network location"); info("Click on the remove button for the provided network location");
const removeButton = const removeButton = networkLocation.querySelector(
networkLocation.querySelector(".qa-network-location-remove-button"); ".qa-network-location-remove-button"
);
removeButton.click(); removeButton.click();
} }
@ -76,6 +95,9 @@ function getNetworkLocation(location, document) {
info("Find the container for network location: " + location); info("Find the container for network location: " + location);
const networkLocations = document.querySelectorAll(".qa-network-location"); const networkLocations = document.querySelectorAll(".qa-network-location");
return [...networkLocations].find(element => { return [...networkLocations].find(element => {
return element.querySelector(".qa-network-location-value").textContent === location; return (
element.querySelector(".qa-network-location-value").textContent ===
location
);
}); });
} }

View file

@ -12,8 +12,10 @@ const { AddonManager } = require("resource://gre/modules/AddonManager.jsm");
* Check that USB Devices scanning can be enabled and disabled from the connect page. * Check that USB Devices scanning can be enabled and disabled from the connect page.
*/ */
add_task(async function() { add_task(async function() {
await pushPref("devtools.remote.adb.extensionURL", await pushPref(
CHROME_URL_ROOT + "resources/test-adb-extension/adb-extension-#OS#.xpi"); "devtools.remote.adb.extensionURL",
CHROME_URL_ROOT + "resources/test-adb-extension/adb-extension-#OS#.xpi"
);
await checkAdbNotRunning(); await checkAdbNotRunning();
const { document, tab } = await openAboutDebugging(); const { document, tab } = await openAboutDebugging();
@ -24,27 +26,40 @@ add_task(async function() {
await waitUntil(() => document.querySelector(".qa-connect-page")); await waitUntil(() => document.querySelector(".qa-connect-page"));
info("Check that by default USB devices are disabled"); info("Check that by default USB devices are disabled");
const usbDisabledMessage = document.querySelector(".qa-connect-usb-disabled-message"); const usbDisabledMessage = document.querySelector(
".qa-connect-usb-disabled-message"
);
ok(usbDisabledMessage, "A message about enabling USB devices is rendered"); ok(usbDisabledMessage, "A message about enabling USB devices is rendered");
const usbToggleButton = document.querySelector(".qa-connect-usb-toggle-button"); const usbToggleButton = document.querySelector(
".qa-connect-usb-toggle-button"
);
ok(usbToggleButton, "The button to toggle USB devices debugging is rendered"); ok(usbToggleButton, "The button to toggle USB devices debugging is rendered");
ok(usbToggleButton.textContent.includes("Enable"), ok(
"The text of the toggle USB button is correct"); usbToggleButton.textContent.includes("Enable"),
"The text of the toggle USB button is correct"
);
info("Click on the toggle button"); info("Click on the toggle button");
usbToggleButton.click(); usbToggleButton.click();
info("Wait until the toggle button text is updated"); info("Wait until the toggle button text is updated");
await waitUntil(() => usbToggleButton.textContent.includes("Disable")); await waitUntil(() => usbToggleButton.textContent.includes("Disable"));
ok(!document.querySelector(".qa-connect-usb-disabled-message"), ok(
"The message about enabling USB devices is no longer rendered"); !document.querySelector(".qa-connect-usb-disabled-message"),
"The message about enabling USB devices is no longer rendered"
);
info("Check that the addon was installed with the proper source"); info("Check that the addon was installed with the proper source");
const adbExtensionId = Services.prefs.getCharPref("devtools.remote.adb.extensionID"); const adbExtensionId = Services.prefs.getCharPref(
"devtools.remote.adb.extensionID"
);
const addon = await AddonManager.getAddonByID(adbExtensionId); const addon = await AddonManager.getAddonByID(adbExtensionId);
Assert.deepEqual(addon.installTelemetryInfo, { source: "about:debugging" }, Assert.deepEqual(
"Got the expected addon.installTelemetryInfo"); addon.installTelemetryInfo,
{ source: "about:debugging" },
"Got the expected addon.installTelemetryInfo"
);
// Right now we are resuming as soon as "USB enabled" is displayed, but ADB // Right now we are resuming as soon as "USB enabled" is displayed, but ADB
// might still be starting up. If we move to uninstall directly, the ADB startup will // might still be starting up. If we move to uninstall directly, the ADB startup will
@ -57,8 +72,10 @@ add_task(async function() {
info("Wait until the toggle button text is updated"); info("Wait until the toggle button text is updated");
await waitUntil(() => usbToggleButton.textContent.includes("Enable")); await waitUntil(() => usbToggleButton.textContent.includes("Enable"));
ok(document.querySelector(".qa-connect-usb-disabled-message"), ok(
"The message about enabling USB devices is rendered again"); document.querySelector(".qa-connect-usb-disabled-message"),
"The message about enabling USB devices is rendered again"
);
await stopAdbProcess(); await stopAdbProcess();

View file

@ -30,28 +30,40 @@ add_task(async function() {
await selectRuntime(USB_DEVICE_NAME, USB_APP_NAME, document); await selectRuntime(USB_DEVICE_NAME, USB_APP_NAME, document);
info("Check whether connection prompt toggle button exists"); info("Check whether connection prompt toggle button exists");
let connectionPromptToggleButton = let connectionPromptToggleButton = document.querySelector(
document.querySelector(".qa-connection-prompt-toggle-button"); ".qa-connection-prompt-toggle-button"
);
ok(connectionPromptToggleButton, "Toggle button existed"); ok(connectionPromptToggleButton, "Toggle button existed");
ok(connectionPromptToggleButton.textContent.includes("Disable"), ok(
"Toggle button shows 'Disable'"); connectionPromptToggleButton.textContent.includes("Disable"),
"Toggle button shows 'Disable'"
);
info("Click on the toggle button"); info("Click on the toggle button");
connectionPromptToggleButton = connectionPromptToggleButton = document.querySelector(
document.querySelector(".qa-connection-prompt-toggle-button"); ".qa-connection-prompt-toggle-button"
);
connectionPromptToggleButton.click(); connectionPromptToggleButton.click();
info("Wait until the toggle button text is updated"); info("Wait until the toggle button text is updated");
await waitUntil(() => connectionPromptToggleButton.textContent.includes("Enable")); await waitUntil(() =>
connectionPromptToggleButton.textContent.includes("Enable")
);
info("Check the preference"); info("Check the preference");
const disabledPref = runtime.getPreference("devtools.debugger.prompt-connection"); const disabledPref = runtime.getPreference(
"devtools.debugger.prompt-connection"
);
is(disabledPref, false, "The preference should be updated"); is(disabledPref, false, "The preference should be updated");
info("Click on the toggle button again"); info("Click on the toggle button again");
connectionPromptToggleButton.click(); connectionPromptToggleButton.click();
info("Wait until the toggle button text is updated"); info("Wait until the toggle button text is updated");
await waitUntil(() => connectionPromptToggleButton.textContent.includes("Disable")); await waitUntil(() =>
connectionPromptToggleButton.textContent.includes("Disable")
);
info("Check the preference"); info("Check the preference");
const enabledPref = runtime.getPreference("devtools.debugger.prompt-connection"); const enabledPref = runtime.getPreference(
"devtools.debugger.prompt-connection"
);
is(enabledPref, true, "The preference should be updated"); is(enabledPref, true, "The preference should be updated");
await removeTab(tab); await removeTab(tab);

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
/* import-globals-from helper-collapsibilities.js */ /* import-globals-from helper-collapsibilities.js */
Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-collapsibilities.js", this); Services.scriptloader.loadSubScript(
CHROME_URL_ROOT + "helper-collapsibilities.js",
this
);
/** /**
* Test that collapsibilities of DebugTargetPane on RuntimePage by mouse clicking. * Test that collapsibilities of DebugTargetPane on RuntimePage by mouse clicking.
@ -37,8 +40,9 @@ async function assertDebugTargetCollapsed(paneEl, title) {
is(targetEl.clientHeight, 0, "Height of list element is zero"); is(targetEl.clientHeight, 0, "Height of list element is zero");
// check title // check title
const titleEl = paneEl.querySelector(".qa-debug-target-pane-title"); const titleEl = paneEl.querySelector(".qa-debug-target-pane-title");
const expectedTitle = const expectedTitle = `${title} (${
`${ title } (${ targetEl.querySelectorAll(".qa-debug-target-item").length })`; targetEl.querySelectorAll(".qa-debug-target-item").length
})`;
is(titleEl.textContent, expectedTitle, "Collapsed title is correct"); is(titleEl.textContent, expectedTitle, "Collapsed title is correct");
} }
@ -51,7 +55,8 @@ async function assertDebugTargetExpanded(paneEl, title) {
ok(true, "Height of list element is greater than zero"); ok(true, "Height of list element is greater than zero");
// check title // check title
const titleEl = paneEl.querySelector(".qa-debug-target-pane-title"); const titleEl = paneEl.querySelector(".qa-debug-target-pane-title");
const expectedTitle = const expectedTitle = `${title} (${
`${ title } (${ targetEl.querySelectorAll(".qa-debug-target-item").length })`; targetEl.querySelectorAll(".qa-debug-target-item").length
})`;
is(titleEl.textContent, expectedTitle, "Expanded title is correct"); is(titleEl.textContent, expectedTitle, "Expanded title is correct");
} }

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
/* import-globals-from helper-collapsibilities.js */ /* import-globals-from helper-collapsibilities.js */
Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-collapsibilities.js", this); Services.scriptloader.loadSubScript(
CHROME_URL_ROOT + "helper-collapsibilities.js",
this
);
/** /**
* Test for preference of DebugTargetPane collapsibilities. * Test for preference of DebugTargetPane collapsibilities.
@ -28,6 +31,10 @@ add_task(async function() {
await waitUntil(() => document.querySelector(".app") === null); await waitUntil(() => document.querySelector(".app") === null);
for (const { pref } of TARGET_PANES) { for (const { pref } of TARGET_PANES) {
is(Services.prefs.getBoolPref(pref), true, `${ pref } preference should be true`); is(
Services.prefs.getBoolPref(pref),
true,
`${pref} preference should be true`
);
} }
}); });

View file

@ -6,7 +6,10 @@
/* import-globals-from helper-addons.js */ /* import-globals-from helper-addons.js */
Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-addons.js", this); Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-addons.js", this);
/* import-globals-from helper-collapsibilities.js */ /* import-globals-from helper-collapsibilities.js */
Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-collapsibilities.js", this); Services.scriptloader.loadSubScript(
CHROME_URL_ROOT + "helper-collapsibilities.js",
this
);
/** /**
* Test that an "empty" message is displayed when there are no debug targets in a debug * Test that an "empty" message is displayed when there are no debug targets in a debug
@ -23,37 +26,58 @@ add_task(async function() {
await selectThisFirefoxPage(document, window.AboutDebugging.store); await selectThisFirefoxPage(document, window.AboutDebugging.store);
info("Check that the temporary extensions pane is empty"); info("Check that the temporary extensions pane is empty");
const temporaryExtensionPane = getDebugTargetPane("Temporary Extensions", document); const temporaryExtensionPane = getDebugTargetPane(
ok(!temporaryExtensionPane.querySelector(".qa-debug-target-item"), "Temporary Extensions",
"Temporary Extensions pane contains no debug target"); document
);
ok(
!temporaryExtensionPane.querySelector(".qa-debug-target-item"),
"Temporary Extensions pane contains no debug target"
);
info("Check an empty target pane message is displayed"); info("Check an empty target pane message is displayed");
ok(temporaryExtensionPane.querySelector(".qa-debug-target-list-empty"), ok(
"An empty target list message is displayed"); temporaryExtensionPane.querySelector(".qa-debug-target-list-empty"),
"An empty target list message is displayed"
);
info("Install a temporary extension"); info("Install a temporary extension");
await installTemporaryExtension(EXTENSION_PATH, EXTENSION_NAME, document); await installTemporaryExtension(EXTENSION_PATH, EXTENSION_NAME, document);
info("Wait until a debug target item appears"); info("Wait until a debug target item appears");
await waitUntil(() => temporaryExtensionPane.querySelector(".qa-debug-target-item")); await waitUntil(() =>
temporaryExtensionPane.querySelector(".qa-debug-target-item")
);
info("Check the empty target pane message is no longer displayed"); info("Check the empty target pane message is no longer displayed");
ok(!temporaryExtensionPane.querySelector(".qa-debug-target-list-empty"), ok(
"The empty target list message is no longer displayed"); !temporaryExtensionPane.querySelector(".qa-debug-target-list-empty"),
"The empty target list message is no longer displayed"
);
const temporaryExtensionItem = const temporaryExtensionItem = temporaryExtensionPane.querySelector(
temporaryExtensionPane.querySelector(".qa-debug-target-item"); ".qa-debug-target-item"
ok(temporaryExtensionItem, "Temporary Extensions pane now shows debug target"); );
ok(
temporaryExtensionItem,
"Temporary Extensions pane now shows debug target"
);
info("Remove the temporary extension"); info("Remove the temporary extension");
temporaryExtensionItem.querySelector(".qa-temporary-extension-remove-button").click(); temporaryExtensionItem
.querySelector(".qa-temporary-extension-remove-button")
.click();
info("Wait until the debug target item disappears"); info("Wait until the debug target item disappears");
await waitUntil(() => !temporaryExtensionPane.querySelector(".qa-debug-target-item")); await waitUntil(
() => !temporaryExtensionPane.querySelector(".qa-debug-target-item")
);
info("Check the empty target pane message is displayed again"); info("Check the empty target pane message is displayed again");
ok(temporaryExtensionPane.querySelector(".qa-debug-target-list-empty"), ok(
"An empty target list message is displayed again"); temporaryExtensionPane.querySelector(".qa-debug-target-list-empty"),
"An empty target list message is displayed again"
);
await removeTab(tab); await removeTab(tab);
}); });

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
/* import-globals-from helper-collapsibilities.js */ /* import-globals-from helper-collapsibilities.js */
Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-collapsibilities.js", this); Services.scriptloader.loadSubScript(
CHROME_URL_ROOT + "helper-collapsibilities.js",
this
);
const RUNTIME_ID = "test-runtime-id"; const RUNTIME_ID = "test-runtime-id";
const RUNTIME_DEVICE_NAME = "test device name"; const RUNTIME_DEVICE_NAME = "test device name";
@ -15,13 +18,17 @@ add_task(async function() {
const mocks = new Mocks(); const mocks = new Mocks();
await checkTargetPanes({ enableLocalTabs: false }, mocks); await checkTargetPanes({ enableLocalTabs: false }, mocks);
info("Check that enableLocalTabs has no impact on the categories displayed for remote" + info(
" runtimes."); "Check that enableLocalTabs has no impact on the categories displayed for remote" +
" runtimes."
);
await checkTargetPanes({ enableLocalTabs: true }, mocks); await checkTargetPanes({ enableLocalTabs: true }, mocks);
}); });
async function checkTargetPanes({ enableLocalTabs }, mocks) { async function checkTargetPanes({ enableLocalTabs }, mocks) {
const { document, tab, window } = await openAboutDebugging({ enableLocalTabs }); const { document, tab, window } = await openAboutDebugging({
enableLocalTabs,
});
await selectThisFirefoxPage(document, window.AboutDebugging.store); await selectThisFirefoxPage(document, window.AboutDebugging.store);
mocks.createUSBRuntime(RUNTIME_ID, { mocks.createUSBRuntime(RUNTIME_ID, {

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
/* import-globals-from helper-collapsibilities.js */ /* import-globals-from helper-collapsibilities.js */
Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-collapsibilities.js", this); Services.scriptloader.loadSubScript(
CHROME_URL_ROOT + "helper-collapsibilities.js",
this
);
/** /**
* Check that DevTools are not closed when leaving This Firefox runtime page. * Check that DevTools are not closed when leaving This Firefox runtime page.

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
/* import-globals-from helper-collapsibilities.js */ /* import-globals-from helper-collapsibilities.js */
Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-collapsibilities.js", this); Services.scriptloader.loadSubScript(
CHROME_URL_ROOT + "helper-collapsibilities.js",
this
);
/** /**
* Test context menu on about:devtools-toolbox page. * Test context menu on about:devtools-toolbox page.
@ -15,13 +18,20 @@ add_task(async function() {
const { document, tab, window } = await openAboutDebugging(); const { document, tab, window } = await openAboutDebugging();
await selectThisFirefoxPage(document, window.AboutDebugging.store); await selectThisFirefoxPage(document, window.AboutDebugging.store);
const { devtoolsBrowser, devtoolsTab } = const { devtoolsBrowser, devtoolsTab } = await openAboutDevtoolsToolbox(
await openAboutDevtoolsToolbox(document, tab, window); document,
tab,
window
);
info("Check whether the menu item which opens devtools is disabled"); info("Check whether the menu item which opens devtools is disabled");
const rootDocument = devtoolsTab.ownerDocument; const rootDocument = devtoolsTab.ownerDocument;
await assertContextMenu(rootDocument, devtoolsBrowser, await assertContextMenu(
".debug-target-info", false); rootDocument,
devtoolsBrowser,
".debug-target-info",
false
);
info("Force to select about:debugging page"); info("Force to select about:debugging page");
gBrowser.selectedTab = tab; gBrowser.selectedTab = tab;
@ -32,7 +42,12 @@ add_task(async function() {
await removeTab(tab); await removeTab(tab);
}); });
async function assertContextMenu(rootDocument, browser, targetSelector, shouldBeEnabled) { async function assertContextMenu(
rootDocument,
browser,
targetSelector,
shouldBeEnabled
) {
if (shouldBeEnabled) { if (shouldBeEnabled) {
await assertContextMenuEnabled(rootDocument, browser, targetSelector); await assertContextMenuEnabled(rootDocument, browser, targetSelector);
} else { } else {
@ -40,15 +55,22 @@ async function assertContextMenu(rootDocument, browser, targetSelector, shouldBe
} }
} }
async function assertContextMenuDisabled(rootDocument, browser, targetSelector) { async function assertContextMenuDisabled(
rootDocument,
browser,
targetSelector
) {
const contextMenu = rootDocument.getElementById("contentAreaContextMenu"); const contextMenu = rootDocument.getElementById("contentAreaContextMenu");
let isPopupShown = false; let isPopupShown = false;
const listener = () => { const listener = () => {
isPopupShown = true; isPopupShown = true;
}; };
contextMenu.addEventListener("popupshown", listener); contextMenu.addEventListener("popupshown", listener);
BrowserTestUtils.synthesizeMouseAtCenter(targetSelector, BrowserTestUtils.synthesizeMouseAtCenter(
{ type: "contextmenu" }, browser); targetSelector,
{ type: "contextmenu" },
browser
);
await wait(1000); await wait(1000);
ok(!isPopupShown, `Context menu should not be shown`); ok(!isPopupShown, `Context menu should not be shown`);
contextMenu.removeEventListener("popupshown", listener); contextMenu.removeEventListener("popupshown", listener);
@ -57,14 +79,23 @@ async function assertContextMenuDisabled(rootDocument, browser, targetSelector)
async function assertContextMenuEnabled(rootDocument, browser, targetSelector) { async function assertContextMenuEnabled(rootDocument, browser, targetSelector) {
// Show content context menu. // Show content context menu.
const contextMenu = rootDocument.getElementById("contentAreaContextMenu"); const contextMenu = rootDocument.getElementById("contentAreaContextMenu");
const popupShownPromise = BrowserTestUtils.waitForEvent(contextMenu, "popupshown"); const popupShownPromise = BrowserTestUtils.waitForEvent(
BrowserTestUtils.synthesizeMouseAtCenter(targetSelector, contextMenu,
{ type: "contextmenu" }, browser); "popupshown"
);
BrowserTestUtils.synthesizeMouseAtCenter(
targetSelector,
{ type: "contextmenu" },
browser
);
await popupShownPromise; await popupShownPromise;
ok(true, `Context menu should be shown`); ok(true, `Context menu should be shown`);
// Hide content context menu. // Hide content context menu.
const popupHiddenPromise = BrowserTestUtils.waitForEvent(contextMenu, "popuphidden"); const popupHiddenPromise = BrowserTestUtils.waitForEvent(
contextMenu,
"popuphidden"
);
contextMenu.hidePopup(); contextMenu.hidePopup();
await popupHiddenPromise; await popupHiddenPromise;
} }

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
/* import-globals-from helper-collapsibilities.js */ /* import-globals-from helper-collapsibilities.js */
Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-collapsibilities.js", this); Services.scriptloader.loadSubScript(
CHROME_URL_ROOT + "helper-collapsibilities.js",
this
);
/** /**
* Test context menu of markup view on about:devtools-toolbox page. * Test context menu of markup view on about:devtools-toolbox page.
@ -15,8 +18,11 @@ add_task(async function() {
const { document, tab, window } = await openAboutDebugging(); const { document, tab, window } = await openAboutDebugging();
await selectThisFirefoxPage(document, window.AboutDebugging.store); await selectThisFirefoxPage(document, window.AboutDebugging.store);
const { devtoolsTab, devtoolsWindow } = const { devtoolsTab, devtoolsWindow } = await openAboutDevtoolsToolbox(
await openAboutDevtoolsToolbox(document, tab, window); document,
tab,
window
);
info("Select inspector tool"); info("Select inspector tool");
const toolbox = getToolbox(devtoolsWindow); const toolbox = getToolbox(devtoolsWindow);
@ -24,9 +30,11 @@ add_task(async function() {
info("Show context menu of markup view"); info("Show context menu of markup view");
const markupDocument = toolbox.getPanel("inspector").markup.doc; const markupDocument = toolbox.getPanel("inspector").markup.doc;
EventUtils.synthesizeMouseAtCenter(markupDocument.body, EventUtils.synthesizeMouseAtCenter(
{ type: "contextmenu" }, markupDocument.body,
markupDocument.ownerGlobal); { type: "contextmenu" },
markupDocument.ownerGlobal
);
info("Check whether proper context menu of markup view will be shown"); info("Check whether proper context menu of markup view will be shown");
await waitUntil(() => toolbox.topDoc.querySelector("#node-menu-edithtml")); await waitUntil(() => toolbox.topDoc.querySelector("#node-menu-edithtml"));

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
/* import-globals-from helper-collapsibilities.js */ /* import-globals-from helper-collapsibilities.js */
Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-collapsibilities.js", this); Services.scriptloader.loadSubScript(
CHROME_URL_ROOT + "helper-collapsibilities.js",
this
);
/** /**
* Test whether the focus transfers to a tab which is already inspected . * Test whether the focus transfers to a tab which is already inspected .
@ -13,39 +16,56 @@ add_task(async function() {
info("Force all debug target panes to be expanded"); info("Force all debug target panes to be expanded");
prepareCollapsibilitiesTest(); prepareCollapsibilitiesTest();
info("Select 'performance' panel as the initial tool since the tool does not listen " + info(
"any changes of the document without user action"); "Select 'performance' panel as the initial tool since the tool does not listen " +
"any changes of the document without user action"
);
await pushPref("devtools.toolbox.selectedTool", "performance"); await pushPref("devtools.toolbox.selectedTool", "performance");
const { document, tab, window } = await openAboutDebugging(); const { document, tab, window } = await openAboutDebugging();
await selectThisFirefoxPage(document, window.AboutDebugging.store); await selectThisFirefoxPage(document, window.AboutDebugging.store);
const inspectionTarget = "about:debugging"; const inspectionTarget = "about:debugging";
info(`Open ${ inspectionTarget } as inspection target`); info(`Open ${inspectionTarget} as inspection target`);
await waitUntil(() => findDebugTargetByText(inspectionTarget, document)); await waitUntil(() => findDebugTargetByText(inspectionTarget, document));
info(`Inspect ${ inspectionTarget } page in about:devtools-toolbox`); info(`Inspect ${inspectionTarget} page in about:devtools-toolbox`);
const { devtoolsTab, devtoolsWindow } = const { devtoolsTab, devtoolsWindow } = await openAboutDevtoolsToolbox(
await openAboutDevtoolsToolbox(document, tab, window, inspectionTarget); document,
tab,
window,
inspectionTarget
);
info("Check the tab state after clicking inspect button " + info(
"when another tab was selected"); "Check the tab state after clicking inspect button " +
"when another tab was selected"
);
gBrowser.selectedTab = tab; gBrowser.selectedTab = tab;
clickInspectButton(inspectionTarget, document); clickInspectButton(inspectionTarget, document);
const devtoolsURL = devtoolsWindow.location.href; const devtoolsURL = devtoolsWindow.location.href;
assertDevtoolsToolboxTabState(devtoolsURL); assertDevtoolsToolboxTabState(devtoolsURL);
info("Check the tab state after clicking inspect button " + info(
"when the toolbox tab is in another window"); "Check the tab state after clicking inspect button " +
"when the toolbox tab is in another window"
);
const newNavigator = gBrowser.replaceTabWithWindow(devtoolsTab); const newNavigator = gBrowser.replaceTabWithWindow(devtoolsTab);
await waitUntil(() => await waitUntil(
newNavigator.gBrowser && () =>
newNavigator.gBrowser.selectedTab.linkedBrowser newNavigator.gBrowser &&
.contentWindow.location.href === devtoolsURL); newNavigator.gBrowser.selectedTab.linkedBrowser.contentWindow.location
info("Create a tab in the window and select the tab " + .href === devtoolsURL
"so that the about:devtools-toolbox tab loses focus"); );
newNavigator.gBrowser.selectedTab = newNavigator.gBrowser.addTab("about:blank", { info(
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), "Create a tab in the window and select the tab " +
}); "so that the about:devtools-toolbox tab loses focus"
);
newNavigator.gBrowser.selectedTab = newNavigator.gBrowser.addTab(
"about:blank",
{
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
}
);
clickInspectButton(inspectionTarget, document); clickInspectButton(inspectionTarget, document);
assertDevtoolsToolboxTabState(devtoolsURL); assertDevtoolsToolboxTabState(devtoolsURL);
@ -71,14 +91,17 @@ function assertDevtoolsToolboxTabState(devtoolsURL) {
for (const navigator of Services.wm.getEnumerator("navigator:browser")) { for (const navigator of Services.wm.getEnumerator("navigator:browser")) {
for (const browser of navigator.gBrowser.browsers) { for (const browser of navigator.gBrowser.browsers) {
if (browser.contentWindow && browser.contentWindow.location.href === devtoolsURL) { if (
browser.contentWindow &&
browser.contentWindow.location.href === devtoolsURL
) {
const tab = navigator.gBrowser.getTabForBrowser(browser); const tab = navigator.gBrowser.getTabForBrowser(browser);
existingTabs.push(tab); existingTabs.push(tab);
} }
} }
} }
is(existingTabs.length, 1, `Only one tab is opened for ${ devtoolsURL }`); is(existingTabs.length, 1, `Only one tab is opened for ${devtoolsURL}`);
const tab = existingTabs[0]; const tab = existingTabs[0];
const navigator = tab.ownerGlobal; const navigator = tab.ownerGlobal;
is(navigator.gBrowser.selectedTab, tab, "The tab is selected"); is(navigator.gBrowser.selectedTab, tab, "The tab is selected");

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
/* import-globals-from helper-collapsibilities.js */ /* import-globals-from helper-collapsibilities.js */
Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-collapsibilities.js", this); Services.scriptloader.loadSubScript(
CHROME_URL_ROOT + "helper-collapsibilities.js",
this
);
/** /**
* Test the status of menu items when open about:devtools-toolbox. * Test the status of menu items when open about:devtools-toolbox.
@ -15,8 +18,11 @@ add_task(async function() {
const { document, tab, window } = await openAboutDebugging(); const { document, tab, window } = await openAboutDebugging();
await selectThisFirefoxPage(document, window.AboutDebugging.store); await selectThisFirefoxPage(document, window.AboutDebugging.store);
const { devtoolsTab, devtoolsWindow } = const { devtoolsTab, devtoolsWindow } = await openAboutDevtoolsToolbox(
await openAboutDevtoolsToolbox(document, tab, window); document,
tab,
window
);
info("Check whether the menu items are disabled"); info("Check whether the menu items are disabled");
const rootDocument = devtoolsTab.ownerDocument; const rootDocument = devtoolsTab.ownerDocument;
@ -48,10 +54,14 @@ async function assertMenusItems(rootDocument, shouldBeEnabled) {
const menuItem = rootDocument.getElementById("menu_devToolbox"); const menuItem = rootDocument.getElementById("menu_devToolbox");
await waitUntil(() => menuItem.hidden === !shouldBeEnabled); await waitUntil(() => menuItem.hidden === !shouldBeEnabled);
info("Check that the state of the Toggle Tools menu-item depends on the page"); info(
"Check that the state of the Toggle Tools menu-item depends on the page"
);
assertMenuItem(rootDocument, "menu_devToolbox", shouldBeEnabled); assertMenuItem(rootDocument, "menu_devToolbox", shouldBeEnabled);
info("Check that the tools menu-items are always enabled regardless of the page"); info(
"Check that the tools menu-items are always enabled regardless of the page"
);
for (const toolDefinition of gDevTools.getToolDefinitionArray()) { for (const toolDefinition of gDevTools.getToolDefinitionArray()) {
if (!toolDefinition.inMenu) { if (!toolDefinition.inMenu) {
continue; continue;
@ -63,6 +73,9 @@ async function assertMenusItems(rootDocument, shouldBeEnabled) {
function assertMenuItem(rootDocument, menuItemId, shouldBeEnabled) { function assertMenuItem(rootDocument, menuItemId, shouldBeEnabled) {
const menuItem = rootDocument.getElementById(menuItemId); const menuItem = rootDocument.getElementById(menuItemId);
is(menuItem.hidden, !shouldBeEnabled, is(
`"hidden" attribute of menu item(${ menuItemId }) should be correct`); menuItem.hidden,
!shouldBeEnabled,
`"hidden" attribute of menu item(${menuItemId}) should be correct`
);
} }

View file

@ -7,7 +7,10 @@
requestLongerTimeout(2); requestLongerTimeout(2);
/* import-globals-from helper-collapsibilities.js */ /* import-globals-from helper-collapsibilities.js */
Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-collapsibilities.js", this); Services.scriptloader.loadSubScript(
CHROME_URL_ROOT + "helper-collapsibilities.js",
this
);
/** /**
* Check that graphs used by the old performance panel are correctly displayed. * Check that graphs used by the old performance panel are correctly displayed.
@ -21,20 +24,27 @@ add_task(async function() {
const { document, tab, window } = await openAboutDebugging(); const { document, tab, window } = await openAboutDebugging();
await selectThisFirefoxPage(document, window.AboutDebugging.store); await selectThisFirefoxPage(document, window.AboutDebugging.store);
const { devtoolsTab, devtoolsWindow } = const { devtoolsTab, devtoolsWindow } = await openAboutDevtoolsToolbox(
await openAboutDevtoolsToolbox(document, tab, window); document,
tab,
window
);
info("Select performance panel"); info("Select performance panel");
const toolbox = getToolbox(devtoolsWindow); const toolbox = getToolbox(devtoolsWindow);
await toolbox.selectTool("performance"); await toolbox.selectTool("performance");
// Retrieve shared helpers for the old performance panel. // Retrieve shared helpers for the old performance panel.
const { startRecording, stopRecording } = const {
require("devtools/client/performance/test/helpers/actions"); startRecording,
stopRecording,
} = require("devtools/client/performance/test/helpers/actions");
const performancePanel = toolbox.getCurrentPanel(); const performancePanel = toolbox.getCurrentPanel();
await startRecording(performancePanel); await startRecording(performancePanel);
const { idleWait } = require("devtools/client/performance/test/helpers/wait-utils"); const {
idleWait,
} = require("devtools/client/performance/test/helpers/wait-utils");
await idleWait(100); await idleWait(100);
info("Stop recording"); info("Stop recording");

View file

@ -7,7 +7,10 @@
requestLongerTimeout(5); requestLongerTimeout(5);
/* import-globals-from helper-collapsibilities.js */ /* import-globals-from helper-collapsibilities.js */
Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-collapsibilities.js", this); Services.scriptloader.loadSubScript(
CHROME_URL_ROOT + "helper-collapsibilities.js",
this
);
const TOOLS = [ const TOOLS = [
"inspector", "inspector",
@ -36,8 +39,11 @@ add_task(async function() {
async function testReloadAboutDevToolsToolbox(toolId) { async function testReloadAboutDevToolsToolbox(toolId) {
const { document, tab, window } = await openAboutDebugging(); const { document, tab, window } = await openAboutDebugging();
await selectThisFirefoxPage(document, window.AboutDebugging.store); await selectThisFirefoxPage(document, window.AboutDebugging.store);
const { devtoolsBrowser, devtoolsTab, devtoolsWindow } = const {
await openAboutDevtoolsToolbox(document, tab, window); devtoolsBrowser,
devtoolsTab,
devtoolsWindow,
} = await openAboutDevtoolsToolbox(document, tab, window);
info(`Select tool: ${toolId}`); info(`Select tool: ${toolId}`);
const toolbox = getToolbox(devtoolsWindow); const toolbox = getToolbox(devtoolsWindow);
@ -49,8 +55,10 @@ async function testReloadAboutDevToolsToolbox(toolId) {
ok(true, "Toolbox is re-created again"); ok(true, "Toolbox is re-created again");
info("Check whether about:devtools-toolbox page displays correctly"); info("Check whether about:devtools-toolbox page displays correctly");
ok(devtoolsBrowser.contentDocument.querySelector(".debug-target-info"), ok(
"about:devtools-toolbox page displays correctly"); devtoolsBrowser.contentDocument.querySelector(".debug-target-info"),
"about:devtools-toolbox page displays correctly"
);
await closeAboutDevtoolsToolbox(document, devtoolsTab, window); await closeAboutDevtoolsToolbox(document, devtoolsTab, window);
await removeTab(tab); await removeTab(tab);

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
/* import-globals-from helper-collapsibilities.js */ /* import-globals-from helper-collapsibilities.js */
Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-collapsibilities.js", this); Services.scriptloader.loadSubScript(
CHROME_URL_ROOT + "helper-collapsibilities.js",
this
);
/** /**
* Test shortcut keys on about:devtools-toolbox page. * Test shortcut keys on about:devtools-toolbox page.
@ -15,8 +18,11 @@ add_task(async function() {
const { document, tab, window } = await openAboutDebugging(); const { document, tab, window } = await openAboutDebugging();
await selectThisFirefoxPage(document, window.AboutDebugging.store); await selectThisFirefoxPage(document, window.AboutDebugging.store);
const { devtoolsBrowser, devtoolsTab, devtoolsWindow } = const {
await openAboutDevtoolsToolbox(document, tab, window); devtoolsBrowser,
devtoolsTab,
devtoolsWindow,
} = await openAboutDevtoolsToolbox(document, tab, window);
info("Check whether the shortcut keys which opens devtools is disabled"); info("Check whether the shortcut keys which opens devtools is disabled");
await assertShortcutKeys(devtoolsBrowser, false); await assertShortcutKeys(devtoolsBrowser, false);
@ -25,13 +31,19 @@ add_task(async function() {
const toolbox = getToolbox(devtoolsWindow); const toolbox = getToolbox(devtoolsWindow);
await toolbox.selectTool("inspector"); await toolbox.selectTool("inspector");
info("Use the Webconsole keyboard shortcut and wait for the panel to be selected"); info(
"Use the Webconsole keyboard shortcut and wait for the panel to be selected"
);
const onToolReady = toolbox.once("webconsole-ready"); const onToolReady = toolbox.once("webconsole-ready");
EventUtils.synthesizeKey("K", { EventUtils.synthesizeKey(
accelKey: true, "K",
shiftKey: !navigator.userAgent.match(/Mac/), {
altKey: navigator.userAgent.match(/Mac/), accelKey: true,
}, devtoolsWindow); shiftKey: !navigator.userAgent.match(/Mac/),
altKey: navigator.userAgent.match(/Mac/),
},
devtoolsWindow
);
await onToolReady; await onToolReady;
info("Force to select about:debugging page"); info("Force to select about:debugging page");
@ -45,15 +57,20 @@ add_task(async function() {
async function assertShortcutKeys(browser, shouldBeEnabled) { async function assertShortcutKeys(browser, shouldBeEnabled) {
await assertShortcutKey(browser.contentWindow, "VK_F12", {}, shouldBeEnabled); await assertShortcutKey(browser.contentWindow, "VK_F12", {}, shouldBeEnabled);
await assertShortcutKey(browser.contentWindow, "I", { await assertShortcutKey(
accelKey: true, browser.contentWindow,
shiftKey: !navigator.userAgent.match(/Mac/), "I",
altKey: navigator.userAgent.match(/Mac/), {
}, shouldBeEnabled); accelKey: true,
shiftKey: !navigator.userAgent.match(/Mac/),
altKey: navigator.userAgent.match(/Mac/),
},
shouldBeEnabled
);
} }
async function assertShortcutKey(win, key, modifiers, shouldBeEnabled) { async function assertShortcutKey(win, key, modifiers, shouldBeEnabled) {
info(`Assert shortcut key [${ key }]`); info(`Assert shortcut key [${key}]`);
if (shouldBeEnabled) { if (shouldBeEnabled) {
await assertShortcutKeyEnabled(win, key, modifiers); await assertShortcutKeyEnabled(win, key, modifiers);
@ -71,7 +88,7 @@ async function assertShortcutKeyDisabled(win, key, modifiers) {
EventUtils.synthesizeKey(key, modifiers, win); EventUtils.synthesizeKey(key, modifiers, win);
await wait(1000); await wait(1000);
ok(!isReadyCalled, `Devtools should not be opened by ${ key }`); ok(!isReadyCalled, `Devtools should not be opened by ${key}`);
gDevTools.off("toolbox-ready", toolboxListener); gDevTools.off("toolbox-ready", toolboxListener);
} }
@ -81,11 +98,11 @@ async function assertShortcutKeyEnabled(win, key, modifiers) {
const onToolboxReady = gDevTools.once("toolbox-ready"); const onToolboxReady = gDevTools.once("toolbox-ready");
EventUtils.synthesizeKey(key, modifiers, win); EventUtils.synthesizeKey(key, modifiers, win);
await onToolboxReady; await onToolboxReady;
ok(true, `Devtools should be opened by ${ key }`); ok(true, `Devtools should be opened by ${key}`);
// Close devtools // Close devtools
const onToolboxDestroyed = gDevTools.once("toolbox-destroyed"); const onToolboxDestroyed = gDevTools.once("toolbox-destroyed");
EventUtils.synthesizeKey(key, modifiers, win); EventUtils.synthesizeKey(key, modifiers, win);
await onToolboxDestroyed; await onToolboxDestroyed;
ok(true, `Devtopls should be closed by ${ key }`); ok(true, `Devtopls should be closed by ${key}`);
} }

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
/* import-globals-from helper-collapsibilities.js */ /* import-globals-from helper-collapsibilities.js */
Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-collapsibilities.js", this); Services.scriptloader.loadSubScript(
CHROME_URL_ROOT + "helper-collapsibilities.js",
this
);
/** /**
* Test that the split console key shortcut works on about:devtools-toolbox. * Test that the split console key shortcut works on about:devtools-toolbox.
@ -15,8 +18,11 @@ add_task(async function() {
const { document, tab, window } = await openAboutDebugging(); const { document, tab, window } = await openAboutDebugging();
await selectThisFirefoxPage(document, window.AboutDebugging.store); await selectThisFirefoxPage(document, window.AboutDebugging.store);
const { devtoolsTab, devtoolsWindow } = const { devtoolsTab, devtoolsWindow } = await openAboutDevtoolsToolbox(
await openAboutDevtoolsToolbox(document, tab, window); document,
tab,
window
);
// Select any tool that is not the Webconsole, since we will assert the split-console. // Select any tool that is not the Webconsole, since we will assert the split-console.
info("Select inspector tool"); info("Select inspector tool");

View file

@ -12,16 +12,25 @@ add_task(async function() {
// go to This Firefox and inspect the new tab // go to This Firefox and inspect the new tab
info("Inspecting a new tab in This Firefox"); info("Inspecting a new tab in This Firefox");
await selectThisFirefoxPage(document, window.AboutDebugging.store); await selectThisFirefoxPage(document, window.AboutDebugging.store);
const { devtoolsDocument, devtoolsTab, devtoolsWindow } = const {
await openAboutDevtoolsToolbox(document, tab, window, "about:home"); devtoolsDocument,
const targetInfoHeader = devtoolsDocument.querySelector(".qa-debug-target-info"); devtoolsTab,
ok(targetInfoHeader.textContent.includes("about:home"), devtoolsWindow,
"about:devtools-toolbox is open for the target"); } = await openAboutDevtoolsToolbox(document, tab, window, "about:home");
const targetInfoHeader = devtoolsDocument.querySelector(
".qa-debug-target-info"
);
ok(
targetInfoHeader.textContent.includes("about:home"),
"about:devtools-toolbox is open for the target"
);
// close the inspected tab and check that error page is shown // close the inspected tab and check that error page is shown
info("removing the inspected tab"); info("removing the inspected tab");
await removeTab(targetTab); await removeTab(targetTab);
await waitUntil(() => devtoolsWindow.document.querySelector(".qa-error-page")); await waitUntil(() =>
devtoolsWindow.document.querySelector(".qa-error-page")
);
info("closing the toolbox"); info("closing the toolbox");
await removeTab(devtoolsTab); await removeTab(devtoolsTab);

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
/* import-globals-from helper-collapsibilities.js */ /* import-globals-from helper-collapsibilities.js */
Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-collapsibilities.js", this); Services.scriptloader.loadSubScript(
CHROME_URL_ROOT + "helper-collapsibilities.js",
this
);
/** /**
* Test tooltip of markup view on about:devtools-toolbox page. * Test tooltip of markup view on about:devtools-toolbox page.
@ -18,8 +21,11 @@ add_task(async function() {
const { document, tab, window } = await openAboutDebugging(); const { document, tab, window } = await openAboutDebugging();
await selectThisFirefoxPage(document, window.AboutDebugging.store); await selectThisFirefoxPage(document, window.AboutDebugging.store);
const { devtoolsDocument, devtoolsTab, devtoolsWindow } = const {
await openAboutDevtoolsToolbox(document, tab, window); devtoolsDocument,
devtoolsTab,
devtoolsWindow,
} = await openAboutDevtoolsToolbox(document, tab, window);
info("Select inspector tool"); info("Select inspector tool");
const toolbox = getToolbox(devtoolsWindow); const toolbox = getToolbox(devtoolsWindow);
@ -27,37 +33,67 @@ add_task(async function() {
const inspector = toolbox.getPanel("inspector"); const inspector = toolbox.getPanel("inspector");
const markupDocument = inspector.markup.doc; const markupDocument = inspector.markup.doc;
const eventBadge = markupDocument.querySelector(".inspector-badge.interactive"); const eventBadge = markupDocument.querySelector(
".inspector-badge.interactive"
);
info("Check tooltip visibility after clicking on an element in the markup view"); info(
"Check tooltip visibility after clicking on an element in the markup view"
);
await checkTooltipVisibility(inspector, eventBadge, markupDocument.body); await checkTooltipVisibility(inspector, eventBadge, markupDocument.body);
info("Check tooltip visibility after clicking on an element in the DevTools document"); info(
"Check tooltip visibility after clicking on an element in the DevTools document"
);
await checkTooltipVisibility( await checkTooltipVisibility(
inspector, eventBadge, devtoolsDocument.querySelector(".debug-target-info")); inspector,
eventBadge,
devtoolsDocument.querySelector(".debug-target-info")
);
info("Check tooltip visibility after clicking on an element in the root document"); info(
"Check tooltip visibility after clicking on an element in the root document"
);
const rootDocument = devtoolsWindow.windowRoot.ownerGlobal.document; const rootDocument = devtoolsWindow.windowRoot.ownerGlobal.document;
await checkTooltipVisibility( await checkTooltipVisibility(
inspector, eventBadge, rootDocument.querySelector("#titlebar")); inspector,
eventBadge,
rootDocument.querySelector("#titlebar")
);
await closeAboutDevtoolsToolbox(document, devtoolsTab, window); await closeAboutDevtoolsToolbox(document, devtoolsTab, window);
await removeTab(tab); await removeTab(tab);
}); });
async function checkTooltipVisibility(inspector, elementForShowing, elementForHiding) { async function checkTooltipVisibility(
inspector,
elementForShowing,
elementForHiding
) {
info("Show event tooltip"); info("Show event tooltip");
elementForShowing.click(); elementForShowing.click();
const tooltip = inspector.markup.eventDetailsTooltip; const tooltip = inspector.markup.eventDetailsTooltip;
await tooltip.once("shown"); await tooltip.once("shown");
is(tooltip.container.classList.contains("tooltip-visible"), true, is(
"The tooltip should be shown"); tooltip.container.classList.contains("tooltip-visible"),
true,
"The tooltip should be shown"
);
info("Hide event tooltip"); info("Hide event tooltip");
EventUtils.synthesizeMouse(elementForHiding, 1, 1, {}, elementForHiding.ownerGlobal); EventUtils.synthesizeMouse(
elementForHiding,
1,
1,
{},
elementForHiding.ownerGlobal
);
await tooltip.once("hidden"); await tooltip.once("hidden");
is(tooltip.container.classList.contains("tooltip-visible"), false, is(
"Tooltip should be hidden"); tooltip.container.classList.contains("tooltip-visible"),
false,
"Tooltip should be hidden"
);
if (inspector._updateProgress) { if (inspector._updateProgress) {
info("Need to wait for the inspector to update"); info("Need to wait for the inspector to update");

View file

@ -10,7 +10,8 @@ const ADB_RUNTIME_NAME = "Firefox Preview";
const SERVER_VERSION = "v7.3.31"; const SERVER_VERSION = "v7.3.31";
const ADB_VERSION = "v1.3.37"; const ADB_VERSION = "v1.3.37";
const FENIX_RELEASE_ICON_SRC = "chrome://devtools/skin/images/aboutdebugging-fenix.svg"; const FENIX_RELEASE_ICON_SRC =
"chrome://devtools/skin/images/aboutdebugging-fenix.svg";
const FENIX_NIGHTLY_ICON_SRC = const FENIX_NIGHTLY_ICON_SRC =
"chrome://devtools/skin/images/aboutdebugging-fenix-nightly.svg"; "chrome://devtools/skin/images/aboutdebugging-fenix-nightly.svg";
@ -42,15 +43,23 @@ add_task(async function() {
const runtimeInfoText = runtimeInfo.textContent; const runtimeInfoText = runtimeInfo.textContent;
ok(runtimeInfoText.includes(ADB_RUNTIME_NAME), "Name is the ADB name"); ok(runtimeInfoText.includes(ADB_RUNTIME_NAME), "Name is the ADB name");
ok(!runtimeInfoText.includes(SERVER_RUNTIME_NAME), ok(
"Name does not include the server name"); !runtimeInfoText.includes(SERVER_RUNTIME_NAME),
"Name does not include the server name"
);
ok(runtimeInfoText.includes(ADB_VERSION), "Version contains the ADB version"); ok(runtimeInfoText.includes(ADB_VERSION), "Version contains the ADB version");
ok(!runtimeInfoText.includes(SERVER_VERSION), ok(
"Version does not contain the server version"); !runtimeInfoText.includes(SERVER_VERSION),
"Version does not contain the server version"
);
const runtimeIcon = document.querySelector(".qa-runtime-icon"); const runtimeIcon = document.querySelector(".qa-runtime-icon");
is(runtimeIcon.src, FENIX_RELEASE_ICON_SRC, "The runtime icon is the Fenix icon"); is(
runtimeIcon.src,
FENIX_RELEASE_ICON_SRC,
"The runtime icon is the Fenix icon"
);
info("Remove USB runtime"); info("Remove USB runtime");
mocks.removeUSBRuntime(RUNTIME_ID); mocks.removeUSBRuntime(RUNTIME_ID);
@ -98,21 +107,33 @@ add_task(async function() {
await connectToRuntime(DEVICE_NAME, document); await connectToRuntime(DEVICE_NAME, document);
await selectRuntime(DEVICE_NAME, ADB_RUNTIME_NAME, document); await selectRuntime(DEVICE_NAME, ADB_RUNTIME_NAME, document);
info("Wait for requests to finish the USB runtime is backed by a real local client"); info(
"Wait for requests to finish the USB runtime is backed by a real local client"
);
await onRequestSuccess; await onRequestSuccess;
info("Wait for the about:debugging target to be available"); info("Wait for the about:debugging target to be available");
await waitUntil(() => findDebugTargetByText("about:debugging", document)); await waitUntil(() => findDebugTargetByText("about:debugging", document));
const { devtoolsDocument, devtoolsTab } = const { devtoolsDocument, devtoolsTab } = await openAboutDevtoolsToolbox(
await openAboutDevtoolsToolbox(document, tab, window); document,
tab,
window
);
const runtimeInfo = devtoolsDocument.querySelector(".qa-runtime-info"); const runtimeInfo = devtoolsDocument.querySelector(".qa-runtime-info");
const runtimeInfoText = runtimeInfo.textContent; const runtimeInfoText = runtimeInfo.textContent;
ok(runtimeInfoText.includes(ADB_RUNTIME_NAME), "Name is the ADB runtime name"); ok(
runtimeInfoText.includes(ADB_RUNTIME_NAME),
"Name is the ADB runtime name"
);
ok(runtimeInfoText.includes(ADB_VERSION), "Version is the ADB version"); ok(runtimeInfoText.includes(ADB_VERSION), "Version is the ADB version");
const runtimeIcon = devtoolsDocument.querySelector(".qa-runtime-icon"); const runtimeIcon = devtoolsDocument.querySelector(".qa-runtime-icon");
is(runtimeIcon.src, FENIX_NIGHTLY_ICON_SRC, "The runtime icon is the Fenix icon"); is(
runtimeIcon.src,
FENIX_NIGHTLY_ICON_SRC,
"The runtime icon is the Fenix icon"
);
info("Wait for all pending requests to settle on the DebuggerClient"); info("Wait for all pending requests to settle on the DebuggerClient");
await clientWrapper.client.waitForRequestsToSettle(); await clientWrapper.client.waitForRequestsToSettle();
@ -132,8 +153,9 @@ async function createLocalClientWrapper() {
info("Create a local DebuggerClient"); info("Create a local DebuggerClient");
const { DebuggerServer } = require("devtools/server/main"); const { DebuggerServer } = require("devtools/server/main");
const { DebuggerClient } = require("devtools/shared/client/debugger-client"); const { DebuggerClient } = require("devtools/shared/client/debugger-client");
const { ClientWrapper } = const {
require("devtools/client/aboutdebugging-new/src/modules/client-wrapper"); ClientWrapper,
} = require("devtools/client/aboutdebugging-new/src/modules/client-wrapper");
DebuggerServer.init(); DebuggerServer.init();
DebuggerServer.registerAllActors(); DebuggerServer.registerAllActors();

View file

@ -6,12 +6,24 @@
// Test that system and hidden addons are only displayed when the showSystemAddons // Test that system and hidden addons are only displayed when the showSystemAddons
// preferences is true. // preferences is true.
const SYSTEM_ADDON = const SYSTEM_ADDON = createAddonData({
createAddonData({ id: "system", name: "System Addon", isSystem: true, hidden: true }); id: "system",
const HIDDEN_ADDON = name: "System Addon",
createAddonData({ id: "hidden", name: "Hidden Addon", isSystem: false, hidden: true }); isSystem: true,
const NORMAL_ADDON = hidden: true,
createAddonData({ id: "normal", name: "Normal Addon", isSystem: false, hidden: false }); });
const HIDDEN_ADDON = createAddonData({
id: "hidden",
name: "Hidden Addon",
isSystem: false,
hidden: true,
});
const NORMAL_ADDON = createAddonData({
id: "normal",
name: "Normal Addon",
isSystem: false,
hidden: false,
});
add_task(async function testShowSystemAddonsTrue() { add_task(async function testShowSystemAddonsTrue() {
info("Test with showHiddenAddons set to true"); info("Test with showHiddenAddons set to true");
@ -23,7 +35,11 @@ add_task(async function testShowSystemAddonsTrue() {
async function testAddonsDisplay(showHidden) { async function testAddonsDisplay(showHidden) {
const thisFirefoxClient = setupThisFirefoxMock(); const thisFirefoxClient = setupThisFirefoxMock();
thisFirefoxClient.listAddons = () => ([SYSTEM_ADDON, HIDDEN_ADDON, NORMAL_ADDON]); thisFirefoxClient.listAddons = () => [
SYSTEM_ADDON,
HIDDEN_ADDON,
NORMAL_ADDON,
];
info("Set showHiddenAddons to " + showHidden); info("Set showHiddenAddons to " + showHidden);
await pushPref("devtools.aboutdebugging.showHiddenAddons", showHidden); await pushPref("devtools.aboutdebugging.showHiddenAddons", showHidden);
@ -34,10 +50,16 @@ async function testAddonsDisplay(showHidden) {
const hasSystemAddon = !!findDebugTargetByText("System Addon", document); const hasSystemAddon = !!findDebugTargetByText("System Addon", document);
const hasHiddenAddon = !!findDebugTargetByText("Hidden Addon", document); const hasHiddenAddon = !!findDebugTargetByText("Hidden Addon", document);
const hasInstalledAddon = !!findDebugTargetByText("Normal Addon", document); const hasInstalledAddon = !!findDebugTargetByText("Normal Addon", document);
is(hasSystemAddon, showHidden, is(
"System addon display is correct when showHiddenAddons is " + showHidden); hasSystemAddon,
is(hasHiddenAddon, showHidden, showHidden,
"Hidden addon display is correct when showHiddenAddons is " + showHidden); "System addon display is correct when showHiddenAddons is " + showHidden
);
is(
hasHiddenAddon,
showHidden,
"Hidden addon display is correct when showHiddenAddons is " + showHidden
);
ok(hasInstalledAddon, "Installed addon is always displayed"); ok(hasInstalledAddon, "Installed addon is always displayed");
await removeTab(tab); await removeTab(tab);
@ -49,7 +71,9 @@ function setupThisFirefoxMock() {
const runtimeClientFactoryMock = createRuntimeClientFactoryMock(); const runtimeClientFactoryMock = createRuntimeClientFactoryMock();
const thisFirefoxClient = createThisFirefoxClientMock(); const thisFirefoxClient = createThisFirefoxClientMock();
runtimeClientFactoryMock.createClientForRuntime = runtime => { runtimeClientFactoryMock.createClientForRuntime = runtime => {
const { RUNTIMES } = require("devtools/client/aboutdebugging-new/src/constants"); const {
RUNTIMES,
} = require("devtools/client/aboutdebugging-new/src/constants");
if (runtime.id === RUNTIMES.THIS_FIREFOX) { if (runtime.id === RUNTIMES.THIS_FIREFOX) {
return thisFirefoxClient; return thisFirefoxClient;
} }

View file

@ -28,7 +28,9 @@ add_task(async function() {
}); });
async function testCloseMessageWithIcon(warningMessage, doc) { async function testCloseMessageWithIcon(warningMessage, doc) {
const closeIcon = warningMessage.querySelector(".qa-message-button-close-icon"); const closeIcon = warningMessage.querySelector(
".qa-message-button-close-icon"
);
ok(!!closeIcon, "The warning message has a close icon"); ok(!!closeIcon, "The warning message has a close icon");
info("Closing the message and waiting for it to disappear"); info("Closing the message and waiting for it to disappear");
@ -39,7 +41,9 @@ async function testCloseMessageWithIcon(warningMessage, doc) {
} }
async function testCloseMessageWithButton(warningMessage, doc) { async function testCloseMessageWithButton(warningMessage, doc) {
const closeButton = warningMessage.querySelector(".qa-message-button-close-button"); const closeButton = warningMessage.querySelector(
".qa-message-button-close-button"
);
ok(!!closeButton, "The warning message has a close button"); ok(!!closeButton, "The warning message has a close button");
info("Click on the button and wait for the message to disappear"); info("Click on the button and wait for the message to disappear");
@ -50,21 +54,27 @@ async function testCloseMessageWithButton(warningMessage, doc) {
} }
async function installExtensionWithWarning(doc) { async function installExtensionWithWarning(doc) {
await installTemporaryExtensionFromXPI({ await installTemporaryExtensionFromXPI(
id: EXTENSION_ID, {
name: EXTENSION_NAME, id: EXTENSION_ID,
extraProperties: { name: EXTENSION_NAME,
// This property is not expected in the manifest and should trigger a warning! extraProperties: {
"wrongProperty": {}, // This property is not expected in the manifest and should trigger a warning!
wrongProperty: {},
},
}, },
}, doc); doc
);
info("Wait until a debug target item appears"); info("Wait until a debug target item appears");
await waitUntil(() => findDebugTargetByText(EXTENSION_NAME, doc)); await waitUntil(() => findDebugTargetByText(EXTENSION_NAME, doc));
const target = findDebugTargetByText(EXTENSION_NAME, doc); const target = findDebugTargetByText(EXTENSION_NAME, doc);
const warningMessage = target.querySelector(".qa-message"); const warningMessage = target.querySelector(".qa-message");
ok(!!warningMessage, "A warning message is displayed for the installed addon"); ok(
!!warningMessage,
"A warning message is displayed for the installed addon"
);
return warningMessage; return warningMessage;
} }

View file

@ -4,7 +4,10 @@
"use strict"; "use strict";
/* import-globals-from helper-collapsibilities.js */ /* import-globals-from helper-collapsibilities.js */
Services.scriptloader.loadSubScript(CHROME_URL_ROOT + "helper-collapsibilities.js", this); Services.scriptloader.loadSubScript(
CHROME_URL_ROOT + "helper-collapsibilities.js",
this
);
/** /**
* Check that navigating from This Firefox to Connect and back to This Firefox works and * Check that navigating from This Firefox to Connect and back to This Firefox works and
@ -27,11 +30,18 @@ add_task(async function() {
ok(connectSidebarItem, "Found the Connect sidebar item"); ok(connectSidebarItem, "Found the Connect sidebar item");
const thisFirefoxString = getThisFirefoxString(window); const thisFirefoxString = getThisFirefoxString(window);
const thisFirefoxSidebarItem = findSidebarItemByText(thisFirefoxString, document); const thisFirefoxSidebarItem = findSidebarItemByText(
const thisFirefoxLink = thisFirefoxSidebarItem.querySelector(".qa-sidebar-link"); thisFirefoxString,
document
);
const thisFirefoxLink = thisFirefoxSidebarItem.querySelector(
".qa-sidebar-link"
);
ok(thisFirefoxSidebarItem, "Found the ThisFirefox sidebar item"); ok(thisFirefoxSidebarItem, "Found the ThisFirefox sidebar item");
ok(isSidebarItemSelected(thisFirefoxSidebarItem), ok(
"ThisFirefox sidebar item is selected by default"); isSidebarItemSelected(thisFirefoxSidebarItem),
"ThisFirefox sidebar item is selected by default"
);
info("Open a new background tab TAB1"); info("Open a new background tab TAB1");
const backgroundTab1 = await addTab(TAB_URL_1, { background: true }); const backgroundTab1 = await addTab(TAB_URL_1, { background: true });
@ -48,7 +58,10 @@ add_task(async function() {
// we need to wait here because the sidebar isn't updated after mounting the page // we need to wait here because the sidebar isn't updated after mounting the page
info("Wait until Connect sidebar item is selected"); info("Wait until Connect sidebar item is selected");
await waitUntil(() => isSidebarItemSelected(connectSidebarItem)); await waitUntil(() => isSidebarItemSelected(connectSidebarItem));
ok(!document.querySelector(".qa-runtime-page"), "Runtime page no longer rendered"); ok(
!document.querySelector(".qa-runtime-page"),
"Runtime page no longer rendered"
);
info("Open a new tab which should be listed when we go back to This Firefox"); info("Open a new tab which should be listed when we go back to This Firefox");
const backgroundTab2 = await addTab(TAB_URL_2, { background: true }); const backgroundTab2 = await addTab(TAB_URL_2, { background: true });
@ -62,9 +75,14 @@ add_task(async function() {
info("Wait until ThisFirefox page is displayed"); info("Wait until ThisFirefox page is displayed");
await waitUntil(() => document.querySelector(".qa-runtime-page")); await waitUntil(() => document.querySelector(".qa-runtime-page"));
ok(isSidebarItemSelected(thisFirefoxSidebarItem), ok(
"ThisFirefox sidebar item is selected again"); isSidebarItemSelected(thisFirefoxSidebarItem),
ok(!document.querySelector(".qa-connect-page"), "Connect page no longer rendered"); "ThisFirefox sidebar item is selected again"
);
ok(
!document.querySelector(".qa-connect-page"),
"Connect page no longer rendered"
);
info("TAB2 should already be displayed in the debug targets"); info("TAB2 should already be displayed in the debug targets");
await waitUntil(() => findDebugTargetByText("TAB2", document)); await waitUntil(() => findDebugTargetByText("TAB2", document));
@ -72,13 +90,17 @@ add_task(async function() {
info("Remove first background tab"); info("Remove first background tab");
await removeTab(backgroundTab1); await removeTab(backgroundTab1);
info("Check TAB1 disappears, meaning ThisFirefox client is correctly connected"); info(
"Check TAB1 disappears, meaning ThisFirefox client is correctly connected"
);
await waitUntil(() => !findDebugTargetByText("TAB1", document)); await waitUntil(() => !findDebugTargetByText("TAB1", document));
info("Remove second background tab"); info("Remove second background tab");
await removeTab(backgroundTab2); await removeTab(backgroundTab2);
info("Check TAB2 disappears, meaning ThisFirefox client is correctly connected"); info(
"Check TAB2 disappears, meaning ThisFirefox client is correctly connected"
);
await waitUntil(() => !findDebugTargetByText("TAB2", document)); await waitUntil(() => !findDebugTargetByText("TAB2", document));
await waitForRequestsToSettle(AboutDebugging.store); await waitForRequestsToSettle(AboutDebugging.store);

View file

@ -41,8 +41,10 @@ add_task(async function() {
}); });
}); });
async function testRemoteClientPersistConnection(mocks, async function testRemoteClientPersistConnection(
{ client, id, runtimeName, sidebarName, type }) { mocks,
{ client, id, runtimeName, sidebarName, type }
) {
info("Open about:debugging and connect to the test runtime"); info("Open about:debugging and connect to the test runtime");
let { document, tab, window } = await openAboutDebugging(); let { document, tab, window } = await openAboutDebugging();
await selectThisFirefoxPage(document, window.AboutDebugging.store); await selectThisFirefoxPage(document, window.AboutDebugging.store);
@ -70,13 +72,18 @@ async function testRemoteClientPersistConnection(mocks,
info("Remove the runtime from the list of remote runtimes"); info("Remove the runtime from the list of remote runtimes");
mocks.removeRuntime(id); mocks.removeRuntime(id);
info("Emit 'closed' on the client and wait for the sidebar item to disappear"); info(
"Emit 'closed' on the client and wait for the sidebar item to disappear"
);
client._eventEmitter.emit("closed"); client._eventEmitter.emit("closed");
if (type === "usb") { if (type === "usb") {
await waitUntilUsbDeviceIsUnplugged(sidebarName, document); await waitUntilUsbDeviceIsUnplugged(sidebarName, document);
} else { } else {
await waitUntil(() => !findSidebarItemByText(sidebarName, document) && await waitUntil(
!findSidebarItemByText(runtimeName, document)); () =>
!findSidebarItemByText(sidebarName, document) &&
!findSidebarItemByText(runtimeName, document)
);
} }
info("Remove the tab"); info("Remove the tab");

Some files were not shown because too many files have changed in this diff Show more