Bug 1403677 - Initial implementation of integration. r?jaws draft
authorRobin Miller <mill2540@msu.edu>
Sat, 14 Oct 2017 17:00:37 -0400
changeset 680513 118767aa97cbb9024acf181570e3e65ccd70cb75
parent 680512 83325c5ee1f82038f7f7deff83a4529096b8608d
child 735872 9084554873875d222bcd49a440dc5f2ba762fb01
push id84522
push userbmo:mill2540@msu.edu
push dateSat, 14 Oct 2017 21:09:12 +0000
reviewersjaws
bugs1403677
milestone58.0a1
Bug 1403677 - Initial implementation of integration. r?jaws Can now crop screenshots properly, for basic cases. Still needs work to add support for more complex cases such as DevTools or new windows. MozReview-Commit-ID: CqmIJFufONw
browser/tools/mozscreenshots/mozscreenshots/extension/Screenshot.jsm
browser/tools/mozscreenshots/mozscreenshots/extension/TestRunner.jsm
browser/tools/mozscreenshots/mozscreenshots/extension/configurations/DevTools.jsm
--- a/browser/tools/mozscreenshots/mozscreenshots/extension/Screenshot.jsm
+++ b/browser/tools/mozscreenshots/mozscreenshots/extension/Screenshot.jsm
@@ -59,21 +59,21 @@ this.Screenshot = {
     }
   },
 
   _buildImagePath(baseName) {
     return OS.Path.join(this._path, this._imagePrefix + baseName + this._imageExtension);
   },
 
   // Capture the whole screen using an external application.
-  captureExternal(filename) {
+  async captureExternal(filename) {
     let imagePath = this._buildImagePath(filename);
-    return this._screenshotFunction(imagePath).then(() => {
-      log.debug("saved screenshot: " + filename);
-    });
+    await this._screenshotFunction(imagePath);
+    log.debug("saved screenshot: " + filename);
+    return imagePath;
   },
 
   // helpers
 
   _screenshotWindows(filename) {
     return new Promise((resolve, reject) => {
       let exe = Services.dirsvc.get("GreBinD", Ci.nsIFile);
       exe.append("screenshot.exe");
@@ -98,21 +98,21 @@ this.Screenshot = {
         file.initWithPath("/usr/sbin/screencapture");
 
         let process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
         process.init(file);
 
         // Run the process.
         let args = ["-x", "-t", "png"];
         // Darwin version number for OS X 10.6 is 10.x
-        if (windowID && Services.sysinfo.getProperty("version").indexOf("10.") !== 0) {
-          // Capture only that window on 10.7+
-          args.push("-l");
-          args.push(windowID);
-        }
+        // if (windowID && Services.sysinfo.getProperty("version").indexOf("10.") !== 0) {
+        //   // Capture only that window on 10.7+
+        //   args.push("-l");
+        //   args.push(windowID);
+        // }
         args.push(filename);
         process.runAsync(args, args.length, this._processObserver(resolve, reject));
       });
     };
 
     function readWindowID() {
       let decoder = new TextDecoder();
       let promise = OS.File.read("/tmp/mozscreenshots-windowid");
--- a/browser/tools/mozscreenshots/mozscreenshots/extension/TestRunner.jsm
+++ b/browser/tools/mozscreenshots/mozscreenshots/extension/TestRunner.jsm
@@ -169,17 +169,17 @@ this.TestRunner = {
   _findBoundingBox(selectors, windowType) {
     // No selectors provided
     if (!selectors.length) {
       log.info("_findBoundingBox: selectors argument is empty");
       return null;
     }
     // Set window type, default "navigator:browser"
     windowType = windowType || "navigator:browser";
-    let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
+    let browserWindow = Services.wm.getMostRecentWindow(windowType);
     let element = browserWindow.document.querySelector(selectors[0]);
     // Selector not found
     if (!element) {
       log.info("_findBoundingBox: selector not found");
       return null;
     }
     let box = browserWindow.document.getBoxObjectFor(element);
     let finalRect = new Rect(box.screenX, box.screenY, box.width, box.height);
@@ -189,17 +189,23 @@ this.TestRunner = {
       if (!newElement) {
         log.info("_findBoundingBox: selector not found");
         return null;
       }
       let newBox = browserWindow.document.getBoxObjectFor(newElement);
       let newRect = new Rect(newBox.screenX, newBox.screenY, newBox.width, newBox.height);
       finalRect = finalRect.union(newRect);
     }
-    return finalRect.inflateFixed(10);
+    finalRect = finalRect.inflateFixed(10);
+    // Clip dimensions to window only
+    finalRect.left = Math.max(finalRect.left, browserWindow.screenX);
+    finalRect.top = Math.max(finalRect.top, browserWindow.screenY);
+    finalRect.right = Math.min(finalRect.right, browserWindow.screenX + browserWindow.outerWidth);
+    finalRect.bottom = Math.min(finalRect.bottom, browserWindow.screenY + browserWindow.outerHeight);
+    return finalRect;
   },
 
   async _performCombo(combo) {
     let paddedComboIndex = padLeft(this.currentComboIndex + 1, String(this.combos.length).length);
     log.info("Combination " + paddedComboIndex + "/" + this.combos.length + ": " +
              this._comboName(combo).substring(1));
 
     function changeConfig(config) {
@@ -250,31 +256,42 @@ this.TestRunner = {
       log.warn("\tskipped configuration: " + ex);
       // Don't set lastCombo here so that we properly know which configurations
       // need to be applied since the last screenshot
 
       // Return so we don't take a screenshot.
       return;
     }
 
-    await this._onConfigurationReady(combo);
+    // TODO: account for multiple windowTypes
+    // Collect selectors from combo configs for cropping region
+    let windowType = undefined;
+    let finalSelectors = [];
+    for (let obj of combo) {
+      if (windowType) {
+        windowType = obj.windowType;
+      }
+      for (let select of obj.selectors) {
+        finalSelectors.push(select);
+      }
+    }
+
+    let rect = this._findBoundingBox(finalSelectors, windowType);
+    await this._onConfigurationReady(combo, rect);
   },
 
-  _onConfigurationReady(combo) {
-    let delayedScreenshot = () => {
-      let filename = padLeft(this.currentComboIndex + 1,
-                             String(this.combos.length).length) + this._comboName(combo);
-      return Screenshot.captureExternal(filename)
-        .then(() => {
-          this.completedCombos++;
-        });
-    };
+  async _onConfigurationReady(combo, rect) {
+    let filename = padLeft(this.currentComboIndex + 1,
+                           String(this.combos.length).length) + this._comboName(combo);
+    const imagePath = await Screenshot.captureExternal(filename);
 
+    let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
+    await this._cropImage(browserWindow, OS.Path.toFileURI(imagePath), rect, imagePath);
+    this.completedCombos++;
     log.debug("_onConfigurationReady");
-    return delayedScreenshot();
   },
 
   _comboName(combo) {
     return combo.reduce(function(a, b) {
       return a + "_" + b.name;
     }, "");
   },
 
--- a/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/DevTools.jsm
+++ b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/DevTools.jsm
@@ -18,46 +18,46 @@ let TargetFactory = devtools.TargetFacto
 function getTargetForSelectedTab() {
   let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
   let target = TargetFactory.forTab(browserWindow.gBrowser.selectedTab);
   return target;
 }
 
 this.DevTools = {
   init(libDir) {
-    let panels = ["options", "webconsole", "jsdebugger", "styleeditor",
-                  "performance", "netmonitor"];
-
-    panels.forEach(panel => {
-      this.configurations[panel] = {};
-      this.configurations[panel].selectors = ["#toolbox-container"];
-      this.configurations[panel].applyConfig = async function() {
-        await gDevTools.showToolbox(getTargetForSelectedTab(), panel, "bottom");
-        await new Promise(resolve => setTimeout(resolve, 500));
-      };
-    });
+    // let panels = ["options", "webconsole", "jsdebugger", "styleeditor",
+    //               "performance", "netmonitor"];
+    //
+    // panels.forEach(panel => {
+    //   this.configurations[panel] = {};
+    //   this.configurations[panel].selectors = ["#toolbox-container"];
+    //   this.configurations[panel].applyConfig = async function() {
+    //     await gDevTools.showToolbox(getTargetForSelectedTab(), panel, "bottom");
+    //     await new Promise(resolve => setTimeout(resolve, 500));
+    //   };
+    // });
   },
 
   configurations: {
     bottomToolbox: {
       selectors: ["#toolbox-container"],
       async applyConfig() {
         await gDevTools.showToolbox(getTargetForSelectedTab(), "inspector", "bottom");
         await new Promise(resolve => setTimeout(resolve, 1000));
       },
     },
-    sideToolbox: {
-      selectors: ["#toolbox-container"],
-      async applyConfig() {
-        await gDevTools.showToolbox(getTargetForSelectedTab(), "inspector", "side");
-        await new Promise(resolve => setTimeout(resolve, 500));
-      },
-    },
-    undockedToolbox: {
-      selectors: ["#toolbox-container"],
-      windowType: "devtools:toolbox",
-      async applyConfig() {
-        await gDevTools.showToolbox(getTargetForSelectedTab(), "inspector", "window");
-        await new Promise(resolve => setTimeout(resolve, 500));
-      },
-    }
+    // sideToolbox: {
+    //   selectors: ["#toolbox-container"],
+    //   async applyConfig() {
+    //     await gDevTools.showToolbox(getTargetForSelectedTab(), "inspector", "side");
+    //     await new Promise(resolve => setTimeout(resolve, 500));
+    //   },
+    // },
+    // undockedToolbox: {
+    //   selectors: ["#toolbox-container"],
+    //   windowType: "devtools:toolbox",
+    //   async applyConfig() {
+    //     await gDevTools.showToolbox(getTargetForSelectedTab(), "inspector", "window");
+    //     await new Promise(resolve => setTimeout(resolve, 500));
+    //   },
+    // }
   },
 };