Bug 1356244 - add integration test for DevToolsShim;r=ochameau
authorJulian Descottes <jdescottes@mozilla.com>
Thu, 18 May 2017 09:15:47 +0200
changeset 409856 861f125ec68fc0c29690bd85593d8d9481fb02ab
parent 409855 e18063b2ed57265bd48e55cf0841515dc1f2c14d
child 409857 d0aa9b4a0fef41eefcabed4fee0cda4b406bf14f
push id1490
push usermtabara@mozilla.com
push dateMon, 31 Jul 2017 14:08:16 +0000
treeherdermozilla-release@70e32e6bf15e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersochameau
bugs1356244
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1356244 - add integration test for DevToolsShim;r=ochameau MozReview-Commit-ID: 8GKOLQtaSRl
devtools/client/framework/test/browser.ini
devtools/client/framework/test/browser_devtools_api.js
devtools/client/framework/test/browser_devtools_shim.js
devtools/client/framework/test/head.js
--- a/devtools/client/framework/test/browser.ini
+++ b/devtools/client/framework/test/browser.ini
@@ -34,16 +34,17 @@ support-files =
   sjs_code_reload.sjs
   sjs_code_bundle_reload_map.sjs
   test_browser_toolbox_debugger.js
 
 [browser_browser_toolbox.js]
 [browser_browser_toolbox_debugger.js]
 [browser_devtools_api.js]
 [browser_devtools_api_destroy.js]
+[browser_devtools_shim.js]
 [browser_dynamic_tool_enabling.js]
 [browser_ignore_toolbox_network_requests.js]
 [browser_keybindings_01.js]
 [browser_keybindings_02.js]
 [browser_keybindings_03.js]
 [browser_menu_api.js]
 [browser_new_activation_workflow.js]
 [browser_source_map-01.js]
--- a/devtools/client/framework/test/browser_devtools_api.js
+++ b/devtools/client/framework/test/browser_devtools_api.js
@@ -12,32 +12,30 @@ thisTestLeaksUncaughtRejectionsAndShould
 // When running in a standalone directory, we get this error
 thisTestLeaksUncaughtRejectionsAndShouldBeFixed("TypeError: this.doc is undefined");
 
 // Tests devtools API
 
 const toolId1 = "test-tool-1";
 const toolId2 = "test-tool-2";
 
-var EventEmitter = require("devtools/shared/event-emitter");
-
 function test() {
   addTab("about:blank").then(runTests1);
 }
 
 // Test scenario 1: the tool definition build method returns a promise.
 function runTests1(aTab) {
   let toolDefinition = {
     id: toolId1,
     isTargetSupported: () => true,
     visibilityswitch: "devtools.test-tool.enabled",
     url: "about:blank",
     label: "someLabel",
     build: function (iframeWindow, toolbox) {
-      let panel = new DevToolPanel(iframeWindow, toolbox);
+      let panel = createTestPanel(iframeWindow, toolbox);
       return panel.open();
     },
   };
 
   ok(gDevTools, "gDevTools exists");
   ok(!gDevTools.getToolDefinitionMap().has(toolId1),
     "The tool is not registered");
 
@@ -88,17 +86,17 @@ function runTests1(aTab) {
 function runTests2() {
   let toolDefinition = {
     id: toolId2,
     isTargetSupported: () => true,
     visibilityswitch: "devtools.test-tool.enabled",
     url: "about:blank",
     label: "someLabel",
     build: function (iframeWindow, toolbox) {
-      return new DevToolPanel(iframeWindow, toolbox);
+      return createTestPanel(iframeWindow, toolbox);
     },
   };
 
   ok(!gDevTools.getToolDefinitionMap().has(toolId2),
     "The tool is not registered");
 
   gDevTools.registerTool(toolDefinition);
   ok(gDevTools.getToolDefinitionMap().has(toolId2),
@@ -206,61 +204,8 @@ function destroyToolbox(toolbox) {
     finishUp();
   });
 }
 
 function finishUp() {
   gBrowser.removeCurrentTab();
   finish();
 }
-
-/**
-* When a Toolbox is started it creates a DevToolPanel for each of the tools
-* by calling toolDefinition.build(). The returned object should
-* at least implement these functions. They will be used by the ToolBox.
-*
-* There may be no benefit in doing this as an abstract type, but if nothing
-* else gives us a place to write documentation.
-*/
-function DevToolPanel(iframeWindow, toolbox) {
-  EventEmitter.decorate(this);
-
-  this._toolbox = toolbox;
-
-  /* let doc = iframeWindow.document
-  let label = doc.createElement("label");
-  let textNode = doc.createTextNode("Some Tool");
-
-  label.appendChild(textNode);
-  doc.body.appendChild(label);*/
-}
-
-DevToolPanel.prototype = {
-  open: function () {
-    let deferred = defer();
-
-    executeSoon(() => {
-      this._isReady = true;
-      this.emit("ready");
-      deferred.resolve(this);
-    });
-
-    return deferred.promise;
-  },
-
-  get target() {
-    return this._toolbox.target;
-  },
-
-  get toolbox() {
-    return this._toolbox;
-  },
-
-  get isReady() {
-    return this._isReady;
-  },
-
-  _isReady: false,
-
-  destroy: function DTI_destroy() {
-    return defer(null);
-  },
-};
new file mode 100644
--- /dev/null
+++ b/devtools/client/framework/test/browser_devtools_shim.js
@@ -0,0 +1,97 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+// Tests DevToolsShim API works as expected when DevTools are available.
+
+const TOOL_ID = "test-tool";
+
+const { DevToolsShim } =
+    Components.utils.import("chrome://devtools-shim/content/DevToolsShim.jsm", {});
+
+add_task(function* () {
+  yield addTab("about:blank");
+
+  yield testThemeRegistrationWithShim();
+  yield testToolRegistrationWithShim();
+
+  gBrowser.removeCurrentTab();
+});
+
+// Test that theme registration works with the DevToolsShim.
+function* testThemeRegistrationWithShim() {
+  let themeId = yield new Promise(resolve => {
+    DevToolsShim.on("theme-registered", function onThemeRegistered(e, id) {
+      resolve(id);
+    });
+
+    DevToolsShim.registerTheme({
+      id: "test-theme",
+      label: "Test theme",
+      stylesheets: [CHROME_URL_ROOT + "doc_theme.css"],
+      classList: ["theme-test"],
+    });
+  });
+
+  is(themeId, "test-theme", "theme-registered event handler sent theme id");
+
+  ok(gDevTools.getThemeDefinitionMap().has(themeId), "theme added to map");
+  DevToolsShim.unregisterTheme("test-theme");
+  ok(!gDevTools.getThemeDefinitionMap().has(themeId), "theme removed");
+}
+
+// Test that tool registration works with the DevToolsShim.
+function* testToolRegistrationWithShim() {
+  let toolDefinition = {
+    id: TOOL_ID,
+    isTargetSupported: () => true,
+    visibilityswitch: "devtools.test-tool.enabled",
+    url: "about:blank",
+    label: "someLabel",
+    build: function (iframeWindow, toolbox) {
+      let panel = createTestPanel(iframeWindow, toolbox);
+      return panel.open();
+    },
+  };
+
+  // Check that tool registration works when using the DevToolsShim.
+  ok(!gDevTools.getToolDefinitionMap().has(TOOL_ID), "The tool is not registered");
+  DevToolsShim.registerTool(toolDefinition);
+  ok(gDevTools.getToolDefinitionMap().has(TOOL_ID), "The tool is registered");
+
+  let events = {};
+
+  // Check that events can be listened to on the shim in the same way as on gDevTools
+  DevToolsShim.on(TOOL_ID + "-init", function onTool1Init(event, toolbox, iframe) {
+    DevToolsShim.off(TOOL_ID + "-init", onTool1Init);
+    ok(toolbox, "toolbox argument available");
+    ok(iframe, "iframe argument available");
+    events.init = true;
+  });
+
+  DevToolsShim.on(TOOL_ID + "-ready", function onToolReady(event, toolbox, iframe) {
+    DevToolsShim.off(TOOL_ID + "-ready", onToolReady);
+    ok(toolbox, "toolbox argument available");
+    ok(iframe, "iframe argument available");
+    events.ready = true;
+  });
+
+  let target = TargetFactory.forTab(gBrowser.selectedTab);
+  let toolbox = yield gDevTools.showToolbox(target, TOOL_ID);
+
+  // init & ready events should have been fired when opening the toolbox.
+  ok(events.init, "init event fired");
+  ok(events.ready, "ready event fired");
+
+  ok(gDevTools.getToolDefinitionMap().has(TOOL_ID), "The tool is still registered");
+  DevToolsShim.unregisterTool(TOOL_ID);
+  ok(!gDevTools.getToolDefinitionMap().has(TOOL_ID), "The tool is no longer registered");
+
+  // Wait for toolbox select event after unregistering the currently selected tool.
+  yield toolbox.once("select");
+
+  yield toolbox.destroy();
+}
--- a/devtools/client/framework/test/head.js
+++ b/devtools/client/framework/test/head.js
@@ -3,16 +3,18 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /* import-globals-from shared-head.js */
 
 // shared-head.js handles imports, constants, and utility functions
 Services.scriptloader.loadSubScript("chrome://mochitests/content/browser/devtools/client/framework/test/shared-head.js", this);
 
+const EventEmitter = require("devtools/shared/event-emitter");
+
 function toggleAllTools(state) {
   for (let [, tool] of gDevTools._tools) {
     if (!tool.visibilityswitch) {
       continue;
     }
     if (state) {
       Services.prefs.setBoolPref(tool.visibilityswitch, true);
     } else {
@@ -183,8 +185,62 @@ function waitForSourceLoad(toolbox, url)
         resolve();
         target.off("source-updated", sourceHandler);
       }
     }
 
     target.on("source-updated", sourceHandler);
   });
 }
+
+/**
+* When a Toolbox is started it creates a DevToolPanel for each of the tools
+* by calling toolDefinition.build(). The returned object should
+* at least implement these functions. They will be used by the ToolBox.
+*
+* There may be no benefit in doing this as an abstract type, but if nothing
+* else gives us a place to write documentation.
+*/
+function DevToolPanel(iframeWindow, toolbox) {
+  EventEmitter.decorate(this);
+
+  this._toolbox = toolbox;
+}
+
+DevToolPanel.prototype = {
+  open: function () {
+    let deferred = defer();
+
+    executeSoon(() => {
+      this._isReady = true;
+      this.emit("ready");
+      deferred.resolve(this);
+    });
+
+    return deferred.promise;
+  },
+
+  get target() {
+    return this._toolbox.target;
+  },
+
+  get toolbox() {
+    return this._toolbox;
+  },
+
+  get isReady() {
+    return this._isReady;
+  },
+
+  _isReady: false,
+
+  destroy: function () {
+    return defer(null);
+  },
+};
+
+/**
+ * Create a simple devtools test panel that implements the minimum API needed to be
+ * registered and opened in the toolbox.
+ */
+function createTestPanel(iframeWindow, toolbox) {
+  return new DevToolPanel(iframeWindow, toolbox);
+}