'Cannot query clipboard when running puppeteer in headless mode

The code below works when puppeteer runs with { headless: false } but fails when it's true. The error is DataError: No valid data on clipboard..

Why is this happening? Is there a way around it?

import * as puppeteer from "puppeteer";

const browser = puppeteer.launch({ headless: true });
const page = browser.then((browser) => browser.newPage());
const blank = page.then((page) => page.goto("https://example.com"));
const context = browser.then((browser) => browser.defaultBrowserContext());

context.then((context) =>
  context.overridePermissions("https://example.com", ["clipboard-read"])
);
async function getClipboardData() {
  await blank;
  const p = await page;
  await p.bringToFront();
  await p.click("body");

  return p.evaluate(function () {
    return new Promise((res, rej) => {
      navigator.clipboard
        .read()
        .then(async (clipboards) => {
          res(null);
        })
        .catch((error) => rej(error.toString()));
    });
  });
}

getClipboardData()
  .then(() => console.log("It works!"))
  .catch((e) => console.log(e)); // Outputs DataError

The same situation happens when trying to trigger a CTRL+V from headless:

import * as puppeteer from "puppeteer";

const browser = puppeteer.launch({ headless: true });
const page = browser.then((browser) => browser.newPage());
const blank = page.then((page) => page.goto("https://example.com"));
const context = browser.then((browser) => browser.defaultBrowserContext());

async function getClipboardData() {
  await blank;
  const p = await page;
  await p.bringToFront();
  await p.click("body");

  let result = p.evaluate(function () {
    return new Promise((res, rej) => {
      document.querySelector("body").addEventListener("paste", (event) => {
        res(event.clipboardData.types);
      });
    });
  });

  await p.keyboard.down("Control");
  await p.keyboard.press("V");
  await p.keyboard.up("Control");

  return result;
}

getClipboardData()
  .then((x) => console.log(x)) // Outputs []
  .catch((e) => console.log(e));


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source