Commit 50376d46 authored by Henrik Skupin's avatar Henrik Skupin
Browse files

Bug 1669917 - [marionette] Port "WebDriver:TakeScreenshot" to JSWindowActor....

Bug 1669917 - [marionette] Port "WebDriver:TakeScreenshot" to JSWindowActor. r=marionette-reviewers,maja_zf

Differential Revision: https://phabricator.services.mozilla.com/D92895
parent f1977d10
Loading
Loading
Loading
Loading
+51 −0
Original line number Diff line number Diff line
@@ -126,6 +126,9 @@ class MarionetteFrameChild extends JSWindowActorChild {
        case "MarionetteFrameParent:getPageSource":
          result = await this.getPageSource();
          break;
        case "MarionetteFrameParent:getScreenshotRect":
          result = await this.getScreenshotRect(data);
          break;
        case "MarionetteFrameParent:isElementDisplayed":
          result = await this.isElementDisplayed(data);
          break;
@@ -337,6 +340,54 @@ class MarionetteFrameChild extends JSWindowActorChild {
    return this.document.documentElement.outerHTML;
  }

  /**
   * Returns the rect of the element to screenshot.
   *
   * Because the screen capture takes place in the parent process the dimensions
   * for the screenshot have to be determined in the appropriate child process.
   *
   * Also it takes care of scrolling an element into view if requested.
   *
   * @param {Object} options
   * @param {Element} options.elem
   *     Optional element to take a screenshot of.
   * @param {boolean=} options.full
   *     True to take a screenshot of the entire document element.
   *     Defaults to true.
   * @param {boolean=} options.scroll
   *     When <var>elem</var> is given, scroll it into view.
   *     Defaults to true.
   *
   * @return {DOMRect}
   *     The area to take a snapshot from.
   */
  async getScreenshotRect(options = {}) {
    const { elem, full = true, scroll = true } = options;
    const win = elem ? this.contentWindow : this.browsingContext.top.window;

    let rect;

    if (elem) {
      if (scroll) {
        element.scrollIntoView(elem);
      }
      rect = this.getElementRect({ elem });
    } else if (full) {
      const docEl = win.document.documentElement;
      rect = new DOMRect(0, 0, docEl.scrollWidth, docEl.scrollHeight);
    } else {
      // viewport
      rect = new DOMRect(
        win.pageXOffset,
        win.pageYOffset,
        win.innerWidth,
        win.innerHeight
      );
    }

    return rect;
  }

  /**
   * Determine the element displayedness of the given web element.
   */
+38 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ const { XPCOMUtils } = ChromeUtils.import(
);

XPCOMUtils.defineLazyModuleGetters(this, {
  capture: "chrome://marionette/content/capture.js",
  element: "chrome://marionette/content/element.js",
  error: "chrome://marionette/content/error.js",
  evaluate: "chrome://marionette/content/evaluate.js",
@@ -237,4 +238,41 @@ class MarionetteFrameParent extends JSWindowActorParent {
      browsingContext: BrowsingContext.get(browsingContextId),
    };
  }

  async takeScreenshot(elem, format, full, scroll) {
    const rect = await this.sendQuery(
      "MarionetteFrameParent:getScreenshotRect",
      {
        elem,
        full,
        scroll,
      }
    );

    // If no element has been specified use the top-level browsing context.
    // Otherwise use the browsing context from the currently selected frame.
    const browsingContext = elem
      ? this.browsingContext
      : this.browsingContext.top;

    let canvas = await capture.canvas(
      browsingContext.topChromeWindow,
      browsingContext,
      rect.x,
      rect.y,
      rect.width,
      rect.height
    );

    switch (format) {
      case capture.Format.Hash:
        return capture.toHash(canvas);

      case capture.Format.Base64:
        return capture.toBase64(canvas);

      default:
        throw new TypeError(`Invalid capture format: ${format}`);
    }
  }
}
+4 −0
Original line number Diff line number Diff line
@@ -3084,6 +3084,10 @@ GeckoDriver.prototype.takeScreenshot = async function(cmd) {
  // Only consider full screenshot if no element has been specified
  full = webEl ? false : full;

  if (MarionettePrefs.useActors) {
    return this.getActor().takeScreenshot(webEl, format, full, scroll);
  }

  const win = this.getCurrentWindow();

  let rect;