diff --git a/devtools/client/webconsole/middleware/history-persistence.js b/devtools/client/webconsole/middleware/history-persistence.js index b3070c9c4d36..b6506726f2ae 100644 --- a/devtools/client/webconsole/middleware/history-persistence.js +++ b/devtools/client/webconsole/middleware/history-persistence.js @@ -18,7 +18,7 @@ loader.lazyRequireGetter(this, "asyncStorage", "devtools/shared/async-storage"); * History persistence middleware is responsible for loading * and maintaining history of executed expressions in JSTerm. */ -function historyPersistenceMiddleware(store) { +function historyPersistenceMiddleware(webConsoleUI, store) { let historyLoaded = false; asyncStorage.getItem("webConsoleHistory").then( value => { @@ -44,7 +44,14 @@ function historyPersistenceMiddleware(store) { // Save the current history entries when modified, but wait till // entries from the previous session are loaded. - if (historyLoaded && triggerStoreActions.includes(action.type)) { + const { isPrivate } = + webConsoleUI.hud?.commands?.targetCommand?.targetFront?.targetForm || {}; + + if ( + !isPrivate && + historyLoaded && + triggerStoreActions.includes(action.type) + ) { const state = store.getState(); asyncStorage .setItem("webConsoleHistory", state.history.entries) diff --git a/devtools/client/webconsole/store.js b/devtools/client/webconsole/store.js index 3481889fb313..71df0bf3e30d 100644 --- a/devtools/client/webconsole/store.js +++ b/devtools/client/webconsole/store.js @@ -94,7 +94,7 @@ function configureStore(webConsoleUI, options = {}) { prefsService, ...options.thunkArgs, }), - historyPersistence, + historyPersistence.bind(null, webConsoleUI), eventTelemetry.bind(null, options.telemetry, sessionId) ); diff --git a/devtools/client/webconsole/test/browser/browser_console_webconsole_private_browsing.js b/devtools/client/webconsole/test/browser/browser_console_webconsole_private_browsing.js index 11a4393eca0a..20da497c4df0 100644 --- a/devtools/client/webconsole/test/browser/browser_console_webconsole_private_browsing.js +++ b/devtools/client/webconsole/test/browser/browser_console_webconsole_private_browsing.js @@ -26,16 +26,16 @@ const PRIVATE_TEST_URI = `data:text/html;charset=utf8,Test consol add_task(async function() { await pushPref("devtools.browserconsole.contentMessages", true); - await addTab(NON_PRIVATE_TEST_URI); + const publicTab = await addTab(NON_PRIVATE_TEST_URI); await pushPref("devtools.browsertoolbox.fission", false); - await testBrowserConsole(); + await testBrowserConsole(publicTab); await pushPref("devtools.browsertoolbox.fission", true); - await testBrowserConsole(); + await testBrowserConsole(publicTab); }); -async function testBrowserConsole() { +async function testBrowserConsole(publicTab) { const privateWindow = await BrowserTestUtils.openNewBrowserWindow({ private: true, }); @@ -64,6 +64,26 @@ async function testBrowserConsole() { await onErrorMessage; ok(true, "Messages are displayed as expected"); + info("Check that commands executed in private windows aren't put in history"); + const privateCommand = `"command in private window"`; + await executeAndWaitForMessage(hud, privateCommand, "", ".result"); + + const publicHud = await openConsole(publicTab); + const historyMessage = await executeAndWaitForMessage( + publicHud, + ":history", + "", + ".simpleTable" + ); + + ok( + Array.from( + historyMessage.node.querySelectorAll("tr td:last-of-type") + ).every(td => td.textContent !== privateCommand), + "command from private window wasn't added to the history" + ); + await closeConsole(publicTab); + info("test cached messages"); await closeConsole(privateTab); info("web console closed"); diff --git a/devtools/server/actors/targets/window-global.js b/devtools/server/actors/targets/window-global.js index 470c395f4a76..a08468814c30 100644 --- a/devtools/server/actors/targets/window-global.js +++ b/devtools/server/actors/targets/window-global.js @@ -36,6 +36,9 @@ const Targets = require("devtools/server/actors/targets/index"); const { TargetActorRegistry } = ChromeUtils.import( "resource://devtools/server/actors/targets/target-actor-registry.jsm" ); +const { PrivateBrowsingUtils } = ChromeUtils.import( + "resource://gre/modules/PrivateBrowsingUtils.jsm" +); const EXTENSION_CONTENT_JSM = "resource://gre/modules/ExtensionContent.jsm"; @@ -281,6 +284,8 @@ const windowGlobalTargetPrototype = { // Save references to the original document we attached to this._originalWindow = this.window; + this.isPrivate = PrivateBrowsingUtils.isContentWindowPrivate(this.window); + this.followWindowGlobalLifeCycle = followWindowGlobalLifeCycle; this.isTopLevelTarget = !!isTopLevelTarget; this.ignoreSubFrames = ignoreSubFrames; @@ -604,6 +609,7 @@ const windowGlobalTargetPrototype = { isTopLevelTarget: this.isTopLevelTarget, ignoreSubFrames: this.ignoreSubFrames, isPopup, + isPrivate: this.isPrivate, traits: { // @backward-compat { version 64 } Exposes a new trait to help identify // BrowsingContextActor's inherited actors from the client side.