Chrome Extension connect Chrome Debugger and take full screenshot

I want to take a full size screenshot in the active tab using a chrome plugin.

I know there is a function called chrome.tabs.captureVisibleTab (), but this does not help to get a full page screenshot.

I know we can get a full page screenshot from chrome (devtools > ctrl+shift+p > Capture full size screenshot). I want to take a screenshot using this feature or a different feature.

With the code I have given below, I can take full page screenshots on a linux machine for my purpose. But when I run the plugin on a windows machine, I get an image like this: enter image description here

this is my code. It may be more helpful to start reading from the bottom:

chrome.tabs.onUpdated.addListener(attachToDebugger);

function clearDeviceMetricsOverride(tabId, base_64_data) {
  chrome.debugger.sendCommand(
    {
      tabId: tabId,
    },
    "Emulation.clearDeviceMetricsOverride",
    function () {
      postData(base_64_data, tabId);
    }
  );
}


function captureScreenshot(tabId) {
  console.log(`{page}: captureScreenshot: status=aboutTo, tabId=${tabId}`);

  chrome.debugger.sendCommand(
    { tabId: tabId },
    "Page.captureScreenshot",
    {
      format: "jpeg",
      quality: 60,
      fromSurface: false,
    },
    (response) => {
      if (chrome.runtime.lastError) {
        console.log(`{back}: captureScreenshot: status=failed, tabId=${tabId}`);
      } else {
        var dataType = typeof response.data;
        console.log(
          `{back}: captureScreenshot: status=success, tabId=${tabId}, dataType=${dataType}`
        );
        let base_64_data = "data:image/jpg;base64," + response.data;
        setTimeout(() => {
          clearDeviceMetricsOverride(tabId, base_64_data);
        }, 500);
      }
    }
  );

  console.log(`{page}: captureScreenshot: status=commandSent, tabId=${tabId}`);
}

//---------------------------------------------------------------------------
function setDeviceMetricsOverride(tabId, height, width) {
  chrome.debugger.sendCommand(
    {
      tabId: tabId,
    },
    "Emulation.setDeviceMetricsOverride",
    { height: height, width: width, deviceScaleFactor: 1, mobile: false },
    function () {
      setTimeout(() => {
        captureScreenshot(tabId);
      }, 500);
    }
  );
}

//---------------------------------------------------------------------------

function getLayoutMetrics(tabId) {
  chrome.debugger.sendCommand(
    {
      tabId: tabId,
    },
    "Page.getLayoutMetrics",
    {},
    function (object) {
      console.log("---- get layout w: " + object.contentSize.width);
      console.log("---- get layout h: " + object.contentSize.height);
      const { height, width } = object.contentSize;
      setDeviceMetricsOverride(tabId, height, width);
    }
  );
}

//---------------------------------------------------------------------------

function setColorlessBackground(tabId) {
  console.log(`{back}: setColorlessBackground: status=aboutTo, tabId=${tabId}`);

  chrome.debugger.sendCommand(
    { tabId: tabId },
    "Emulation.setDefaultBackgroundColorOverride",
    { color: { r: 0, g: 0, b: 0, a: 0 } },
    function () {
      console.log(
        `{back}: setColorlessBackground: status=enabled, tabId=${tabId}`
      );
      getLayoutMetrics(tabId);
    }
  );

  console.log(
    `{back}: setColorlessBackground: status=commandSent, tabId=${tabId}`
  );
}

//---------------------------------------------------------------------------

function enableDTPage(tabId) {
  console.log(`{back}: enableDTPage: status=aboutTo, tabId=${tabId}`);

  chrome.debugger.sendCommand({ tabId: tabId }, "Page.enable", {}, function () {
    console.log(`{back}: enableDTPage: status=enabled, tabId=${tabId}`);
    setColorlessBackground(tabId);
  });

  console.log(`{back}: enableDTPage: status=commandSent, tabId=${tabId}`);
}

//---------------------------------------------------------------------------

function attachToDebugger(tabId, changeInfo, tab) {
  try {
    if (tab.status == "complete") {
      chrome.debugger.attach({ tabId: tabId }, "1.0", () => {
        if (chrome.runtime.lastError) {
          console.log(
            `{back}: debugger attach failed: error=${chrome.runtime.lastError.message}`
          );
        } else {
          console.log(`{back}: debugger attach success: tabId=${tabId}`);
          enableDTPage(tabId);
        }
      });
    }
  } catch {}
}

Answer

With the code I have given below, I can take full page screenshots on a linux machine for my purpose.

Not sure how Linux differentiates the surface and the view (if your code works), but for Windows you have to change this:

"Page.captureScreenshot",
    {
      format: "jpeg",
      quality: 60,
      fromSurface: false,

To this:

"Page.captureScreenshot",
    {
      format: "jpeg",
      quality: 60,
      fromSurface: true,

Your code will produce full page screenshot with this fix. I’m not sure you changed the fromSurface property value from the example you took this code from, since in the docs they say that this property will force the API to make a screenshot within the view, if set to false, which makes sense for result to become cropped.