Bug 1450186 - Clear cached messages when user clear messages; r=Honza. draft
authorNicolas Chevobbe <nchevobbe@mozilla.com>
Thu, 05 Apr 2018 18:54:06 +0200
changeset 780280 15958cd4cb1912254131b4a2b3fb7c3c055e8777
parent 779723 a8061a09cd7064a8783ca9e67979d77fb52e001e
push id105970
push userbmo:nchevobbe@mozilla.com
push dateWed, 11 Apr 2018 08:21:53 +0000
reviewersHonza
bugs1450186
milestone61.0a1
Bug 1450186 - Clear cached messages when user clear messages; r=Honza. This patch adds a new middleware which takes care of clearing the messages caches when the user clear the messages through the UI or via console.clear. Tests are added for both webconsole and browser console to make sure we don't regress. MozReview-Commit-ID: IaBQycsBAS9
devtools/client/webconsole/store.js
devtools/client/webconsole/test/mochitest/browser.ini
devtools/client/webconsole/test/mochitest/browser_console_clear_cache.js
devtools/client/webconsole/test/mochitest/browser_webconsole_clear_cache.js
--- a/devtools/client/webconsole/store.js
+++ b/devtools/client/webconsole/store.js
@@ -70,17 +70,18 @@ function configureStore(hud, options = {
 
   return createStore(
     createRootReducer(),
     initialState,
     compose(
       applyMiddleware(thunk.bind(null, {prefsService})),
       enableActorReleaser(hud),
       enableBatching(),
-      enableNetProvider(hud)
+      enableNetProvider(hud),
+      enableMessagesCacheClearing(hud),
     )
   );
 }
 
 function thunk(options = {}, { dispatch, getState }) {
   return next => action => {
     return (typeof action === "function")
       ? action(dispatch, getState, options)
@@ -247,16 +248,39 @@ function enableNetProvider(hud) {
       }
 
       return newState;
     }
 
     return next(netProviderEnhancer, initialState, enhancer);
   };
 }
+
+/**
+ * This enhancer is responsible for clearing the messages caches using the
+ * webconsoleClient when the user clear the messages (either by direct UI action, or via
+ * `console.clear()`).
+ */
+function enableMessagesCacheClearing(hud) {
+  return next => (reducer, initialState, enhancer) => {
+    function messagesCacheClearingEnhancer(state, action) {
+      state = reducer(state, action);
+
+      let webConsoleClient = hud && hud.proxy ? hud.proxy.webConsoleClient : null;
+      if (webConsoleClient && action.type === MESSAGES_CLEAR) {
+        webConsoleClient.clearNetworkRequests();
+        webConsoleClient.clearMessagesCache();
+      }
+      return state;
+    }
+
+    return next(messagesCacheClearingEnhancer, initialState, enhancer);
+  };
+}
+
 /**
  * Helper function for releasing backend actors.
  */
 function releaseActors(removedActors, proxy) {
   if (!proxy) {
     return;
   }
 
--- a/devtools/client/webconsole/test/mochitest/browser.ini
+++ b/devtools/client/webconsole/test/mochitest/browser.ini
@@ -161,16 +161,17 @@ support-files =
   testscript.js
   !/devtools/client/netmonitor/test/sjs_cors-test-server.sjs
   !/image/test/mochitest/blue.png
   !/devtools/client/shared/test/shared-head.js
   !/devtools/client/shared/test/test-actor.js
   !/devtools/client/shared/test/test-actor-registry.js
 
 [browser_console.js]
+[browser_console_clear_cache.js]
 [browser_console_clear_method.js]
 skip-if = true # Bug 1437843
 [browser_console_consolejsm_output.js]
 [browser_console_context_menu_entries.js]
 skip-if = (os == "linux" && (debug || ccov)) # Bug 1440059
 [browser_console_dead_objects.js]
 [browser_console_devtools_loader_exception.js]
 [browser_console_error_source_click.js]
@@ -233,16 +234,17 @@ subsuite = clipboard
 [browser_webconsole_allow_mixedcontent_securityerrors.js]
 tags = mcb
 [browser_webconsole_batching.js]
 [browser_webconsole_block_mixedcontent_securityerrors.js]
 tags = mcb
 [browser_webconsole_cached_messages.js]
 [browser_webconsole_cd_iframe.js]
 [browser_webconsole_certificate_messages.js]
+[browser_webconsole_clear_cache.js]
 [browser_webconsole_click_function_to_source.js]
 [browser_webconsole_clickable_urls.js]
 [browser_webconsole_close_unfocused_window.js]
 [browser_webconsole_closing_after_completion.js]
 [browser_webconsole_close_sidebar.js]
 [browser_webconsole_closure_inspection.js]
 skip-if = true # Bug 1405250
 [browser_webconsole_console_api_iframe.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/webconsole/test/mochitest/browser_console_clear_cache.js
@@ -0,0 +1,39 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Check that clearing the browser console output also clears the console cache.
+
+"use strict";
+
+const TEST_URI = "data:text/html;charset=utf8,Test browser console clear cache";
+
+add_task(async function() {
+  await addTab(TEST_URI);
+  let hud = await HUDService.toggleBrowserConsole();
+  const CACHED_MESSAGE = "CACHED_MESSAGE";
+  await logTextToConsole(hud, CACHED_MESSAGE);
+
+  info("Click the clear output button");
+  const onBrowserConsoleOutputCleared = waitFor(
+    () => !findMessage(hud, CACHED_MESSAGE)
+  );
+  hud.ui.window.document.querySelector(".devtools-clear-icon").click();
+  await onBrowserConsoleOutputCleared;
+
+  info("Close and re-open the browser console");
+  await HUDService.toggleBrowserConsole();
+  hud = await HUDService.toggleBrowserConsole();
+
+  info("Log a smoke message in order to know that the console is ready");
+  await logTextToConsole(hud, "Smoke message");
+  is(findMessage(hud, CACHED_MESSAGE), null, "The cached message is not visible anymore");
+});
+
+function logTextToConsole(hud, text) {
+  const onMessage = waitForMessage(hud, text);
+  ContentTask.spawn(gBrowser.selectedBrowser, text, function(str) {
+    content.wrappedJSObject.console.log(str);
+  });
+  return onMessage;
+}
new file mode 100644
--- /dev/null
+++ b/devtools/client/webconsole/test/mochitest/browser_webconsole_clear_cache.js
@@ -0,0 +1,64 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Check that clearing the output also clears the console cache.
+
+"use strict";
+
+const TEST_URI = "data:text/html;charset=utf8,Test clear cache";
+
+add_task(async function() {
+  const tab = await addTab(TEST_URI);
+  let hud = await openConsole(tab);
+
+  const CACHED_MESSAGE = "CACHED_MESSAGE";
+  await logTextToConsole(hud, CACHED_MESSAGE);
+
+  info("Close and re-open the console");
+  await closeToolbox();
+  hud = await openConsole(tab);
+
+  await waitFor(() => findMessage(hud, CACHED_MESSAGE));
+
+  info("Click the clear output button");
+  let onOutputCleared = waitFor(() => !findMessage(hud, CACHED_MESSAGE));
+  hud.ui.window.document.querySelector(".devtools-clear-icon").click();
+  await onOutputCleared;
+
+  info("Close and re-open the console");
+  await closeToolbox();
+  hud = await openConsole(tab);
+
+  info("Log a smoke message in order to know that the console is ready");
+  await logTextToConsole(hud, "Smoke message");
+  is(findMessage(hud, CACHED_MESSAGE), null, "The cached message is not visible anymore");
+
+  // Test that we also clear the cache when calling console.clear().
+  const NEW_CACHED_MESSAGE = "NEW_CACHED_MESSAGE";
+  await logTextToConsole(hud, NEW_CACHED_MESSAGE);
+
+  info("Send a console.clear() from the content page");
+  const onConsoleCleared = waitForMessage(hud, "Console was cleared");
+  ContentTask.spawn(gBrowser.selectedBrowser, {}, () => {
+    content.wrappedJSObject.console.clear();
+  });
+  await onConsoleCleared;
+
+  info("Close and re-open the console");
+  await closeToolbox();
+  hud = await openConsole(tab);
+
+  info("Log a smoke message in order to know that the console is ready");
+  await logTextToConsole(hud, "Second smoke message");
+  is(findMessage(hud, NEW_CACHED_MESSAGE), null,
+    "The new cached message is not visible anymore");
+});
+
+function logTextToConsole(hud, text) {
+  const onMessage = waitForMessage(hud, text);
+  ContentTask.spawn(gBrowser.selectedBrowser, text, function(str) {
+    content.wrappedJSObject.console.log(str);
+  });
+  return onMessage;
+}