Giter VIP home page Giter VIP logo

deno-puppeteer's Introduction

deno-puppeteer

A fork of Puppeteer running on Deno.

Puppeteer is a library which provides a high-level API to control Chrome, Chromium, or Firefox Nightly over the DevTools Protocol. Puppeteer runs headless by default, but can be configured to run full (non-headless) Chrome or Chromium.

Most things that you can do manually in the browser can be done using Puppeteer! Here are a few examples to get you started:

  • Generate screenshots and PDFs of pages.
  • Crawl a SPA (Single-Page Application) and generate pre-rendered content (i.e. "SSR" (Server-Side Rendering)).
  • Automate form submission, UI testing, keyboard input, etc.
  • Create an up-to-date, automated testing environment. Run your tests directly in the latest version of Chrome using the latest JavaScript and browser features.
  • Capture a timeline trace of your site to help diagnose performance issues.
  • Test Chrome Extensions.

Getting Started

Installation

To use Puppeteer, import it like so:

import puppeteer from "https://deno.land/x/[email protected]/mod.ts";

Puppeteer can use any recent version of Chromium or Firefox Nightly, but this version of Puppeteer is only validated against a specific version. To cache these versions in the Puppeteer cache, run the commands below.

PUPPETEER_PRODUCT=chrome deno run -A --unstable https://deno.land/x/[email protected]/install.ts
PUPPETEER_PRODUCT=firefox deno run -A --unstable https://deno.land/x/[email protected]/install.ts

You can find all of the supported environment variables to customize installation in the Puppeteer docs.

Usage

Puppeteer will be familiar to people using other browser testing frameworks. You create an instance of Browser, open pages, and then manipulate them with Puppeteer's API.

Example - navigating to https://example.com and saving a screenshot as example.png:

Save file as example.js

import puppeteer from "https://deno.land/x/[email protected]/mod.ts";

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto("https://example.com");
await page.screenshot({ path: "example.png" });

await browser.close();

Execute script on the command line

deno run -A --unstable example.js

Puppeteer sets an initial page size to 800×600px, which defines the screenshot size. The page size can be customized with Page.setViewport().

Example - create a PDF.

Save file as hn.js

import puppeteer from "https://deno.land/x/[email protected]/mod.ts";

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto("https://news.ycombinator.com", {
  waitUntil: "networkidle2",
});
await page.pdf({ path: "hn.pdf", format: "A4" });

await browser.close();

Execute script on the command line

deno run -A --unstable hn.js

See Page.pdf() for more information about creating pdfs.

Example - evaluate script in the context of the page

Save file as get-dimensions.js

import puppeteer from "https://deno.land/x/[email protected]/mod.ts";

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto("https://example.com");

// Get the "viewport" of the page, as reported by the page.
const dimensions = await page.evaluate(() => {
  return {
    width: document.documentElement.clientWidth,
    height: document.documentElement.clientHeight,
    deviceScaleFactor: window.devicePixelRatio,
  };
});

console.log("Dimensions:", dimensions);

await browser.close();

Execute script on the command line

deno run -A --unstable get-dimensions.js

FAQ

How does deno-puppeteer compare to the Node version?

deno-puppeteer effectively runs a regular version of Puppeteer, except for some minor changes to make it compatible with Deno.

The most noticable difference is likely that instead of some methods taking / returning Node Buffer, they take / return Uint8Array. One method also returns a web native ReadableStream instead of the Node Readable.

Other than this, the documentation on https://pptr.dev generally applies.

How to run in Docker?

An example Dockerfile can be found in this repository. It will install all necessary dependencies, and shows how to run the ./examples/docker.js.

It is just meant as a jumping off point - customize it as you wish.

deno-puppeteer's People

Contributors

c0per avatar fer22f avatar lucacasonato avatar lukechannings avatar marktiedemann avatar masnagam avatar maxim-mazurok avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

deno-puppeteer's Issues

Add more tests

Testing is very slim right now. At minimum a test for the following should be added:

  • FF installation and usage
  • Connect only, with browserless.io
  • Taking screenshot with path option

PDF Issue on Chromium 91.0.4469.0 on Linux

The latest version of this project points to Chromium 91.0.4469.0 and the instance I am using on linux fails with the following error when I try to call page.pdf({<opts>}):

error: Uncaught (in promise) Error: Protocol error (Page.printToPDF): PrintToPDF is not implemented
      this._callbacks.set(id, { resolve, reject, error: new Error(), method });
                                                        ^
    at https://deno.land/x/[email protected]/vendor/puppeteer-core/puppeteer/common/Connection.js:226:57
    at new Promise (<anonymous>)
    at CDPSession.send (https://deno.land/x/[email protected]/vendor/puppeteer-core/puppeteer/common/Connection.js:225:12)
    at Page.pdf (https://deno.land/x/[email protected]/vendor/puppeteer-core/puppeteer/common/Page.js:1406:39)

Here is my test code:

import puppeteer from "https://deno.land/x/[email protected]/mod.ts";

// Bad Version: Version 91.0.4469.0 (Developer Build) (64-bit)
const browser = await puppeteer.launch({headless: false});

// OK Version: Version 99.0.4844.74 (Official Build) (64-bit)
// const browser = await puppeteer.launch({executablePath: '/usr/bin/google-chrome', headless: false});
const page = await browser.newPage();
await page.goto("https://example.com");
await page.pdf({ path: "example.pdf" });

await browser.close();

example doesn't do anything on Linux/Manjaro

import puppeteer from "https://deno.land/x/[email protected]/mod.ts";

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto("https://example.com");
await page.screenshot({ path: "example.png" });

await browser.close();

nothing happens. I don't see any browser open or screenshot.png created.

I tried adding { headless false } and I get this error:

Check file:///home/ettinger/src/accounts/bot/test.ts
error: Uncaught TimeoutError: Timed out after 30000 ms while trying to connect to the browser! Only Chrome at revision r991974 is guaranteed to work.
    throw new TimeoutError(
          ^
    at https://deno.land/x/[email protected]/src/deno/BrowserRunner.ts:162:11
    at Object.action (deno:ext/web/02_timers.js:145:13)
    at handleTimerMacrotask (deno:ext/web/02_timers.js:62:12)
➜  bot 
$ 

I ran this command and it finished:


$ PUPPETEER_PRODUCT=chrome deno run -A --unstable https://deno.land/x/[email protected]/install.ts
Already downloaded at /home/ettinger/.cache/deno/deno_puppeteer/chromium/linux-991974/chrome-linux/chrome

Resolve errors for import paths `fs` and `path`

With Deno v1.25.0, run:

deno info https://deno.land/x/[email protected]/mod.ts

And you can see in the output that there are resolve errors for the import paths fs and path

Relative import path "fs" not prefixed with / or ./ or ../ and not in import map from "https://deno.land/x/[email protected]/vendor/puppeteer-core/puppeteer/common/IsolatedWorld.js" (resolve error)

Source:

Relative import path "path" not prefixed with / or ./ or ../ and not in import map from "https://deno.land/x/[email protected]/vendor/puppeteer-core/puppeteer/common/ElementHandle.js" (resolve error)

Source:

How to use it with browserless.io?

Can I override the local browser check? I'm using the following:

const getBrowser = async function () {
    puppeteer.connect({ browserWSEndpoint: 'wss://chrome.browserless.io?token=[REDACTED] })
    puppeteer.launch();

And I'm still getting the browser not found error.

error: Uncaught Error: Could not find browser revision 1022525. Run "PUPPETEER_PRODUCT=chrome deno run -A --unstable https://deno.land/x/[email protected]/install.ts" to download a supported browser binary.

The entire point of using browserless is to not require a local browser installation 😊

TypeError: reader is not async iterable at getReadableStreamAsUint8Array

Deno info:

🐉 >deno info
DENO_DIR location: /Users/mateuszflisikowski/Library/Caches/deno
Remote modules cache: /Users/mateuszflisikowski/Library/Caches/deno/deps
npm modules cache: /Users/mateuszflisikowski/Library/Caches/deno/npm
Emitted modules cache: /Users/mateuszflisikowski/Library/Caches/deno/gen
Language server registries cache: /Users/mateuszflisikowski/Library/Caches/deno/registries
Origin storage: /Users/mateuszflisikowski/Library/Caches/deno/location_data

TypeError: reader is not async iterable

TypeError: reader is not async iterable
    at getReadableStreamAsUint8Array (https://deno.land/x/[email protected]/vendor/puppeteer-core/puppeteer/common/util.js:329:29)
    at Page.pdf (https://deno.land/x/[email protected]/vendor/puppeteer-core/puppeteer/common/Page.js:2606:24)
    at async Server.<anonymous> (file:///home/deno/functions/download-cv/index.ts:21:17)
    at async Server.#respond (https://deno.land/[email protected]/http/server.ts:298:18)

Supabase function code, that try to run.

import puppeteer from 'https://deno.land/x/[email protected]/mod.ts';
import { serve } from 'https://deno.land/[email protected]/http/server.ts';

serve(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  await page.goto('https://mflisikowski.dev/cv', {
    waitUntil: 'networkidle2',
  });

  const pdf = await page.pdf({ format: 'A4' });

  await browser.close();

  return new Response(pdf, {
    headers: {
      'Content-Disposition': `attachment; filename="cv.pdf"`,
      'Content-Type': 'application/pdf',
    },
  });
});

Error: Property 'utime' does not exist on type 'typeof Deno'

I got this on Deno 1.13.2 and also on latest 1.14.1

OS: MacOS Mojave 10.14.6

$ deno run --allow-read --allow-net --unstable --config tsconfig.json src/cli.ts
# ...
error: TS2339 [ERROR]: Property 'utime' does not exist on type 'typeof Deno'. 'Deno.utime' is an unstable API. Did you forget to run with the '--unstable' flag?
    await Deno.utime(dest, statInfo.atime, statInfo.mtime);
               ~~~~~
    at https://deno.land/[email protected]/fs/copy.ts:96:16

TS2339 [ERROR]: Property 'utimeSync' does not exist on type 'typeof Deno'. 'Deno.utimeSync' is an unstable API. Did you forget to run with the '--unstable' flag?
    Deno.utimeSync(dest, statInfo.atime, statInfo.mtime);
         ~~~~~~~~~
    at https://deno.land/[email protected]/fs/copy.ts:111:10

TS2339 [ERROR]: Property 'utime' does not exist on type 'typeof Deno'. 'Deno.utime' is an unstable API. Did you forget to run with the '--unstable' flag?
    await Deno.utime(dest, statInfo.atime, statInfo.mtime);
               ~~~~~
    at https://deno.land/[email protected]/fs/copy.ts:135:16

TS2339 [ERROR]: Property 'utimeSync' does not exist on type 'typeof Deno'. 'Deno.utimeSync' is an unstable API. Did you forget to run with the '--unstable' flag?
    Deno.utimeSync(dest, statInfo.atime, statInfo.mtime);
         ~~~~~~~~~
    at https://deno.land/[email protected]/fs/copy.ts:160:10

TS2339 [ERROR]: Property 'utime' does not exist on type 'typeof Deno'. 'Deno.utime' is an unstable API. Did you forget to run with the '--unstable' flag?
    await Deno.utime(dest, srcStatInfo.atime, srcStatInfo.mtime);
               ~~~~~
    at https://deno.land/[email protected]/fs/copy.ts:183:16

TS2339 [ERROR]: Property 'utimeSync' does not exist on type 'typeof Deno'. 'Deno.utimeSync' is an unstable API. Did you forget to run with the '--unstable' flag?
    Deno.utimeSync(dest, srcStatInfo.atime, srcStatInfo.mtime);
         ~~~~~~~~~
    at https://deno.land/[email protected]/fs/copy.ts:214:10

$ deno --version
deno 1.13.2 (release, x86_64-apple-darwin)
v8 9.3.345.11
typescript 4.3.5
$ deno upgrade
# ...
$ deno --version
deno 1.14.1 (release, x86_64-apple-darwin)
v8 9.4.146.15
typescript 4.4.2

Consider --disable-gpu flag on Windows / Disable .cc logs

Hi @lucacasonato, thanks for this awesome project! <3

I might have found a tiny issue:

import puppeteer from "https://deno.land/x/[email protected]/mod.ts";

let browser = await puppeteer.launch();
let page = await browser.newPage();
await page.goto("https://deno.land");
console.log(await page.title());
await browser.close();
C:\dev\test>deno run --unstable -A puppeteer .ts
Deno - A secure runtime for JavaScript and TypeScript
[1230/190020.763:ERROR:command_buffer_proxy_impl.cc(122)] ContextResult::kTransientFailure: Failed to send GpuChannelMsg_CreateCommandBuffer.
[1230/190020.764:ERROR:command_buffer_proxy_impl.cc(122)] ContextResult::kTransientFailure: Failed to send GpuChannelMsg_CreateCommandBuffer.

After adding the launch args: ["--disable-gpu"], no errors were logged.

See puppeteer/puppeteer#1610.

macOS: Chromium crashes on launch

deno 1.7.0 (release, x86_64-apple-darwin)
v8 8.9.255.3
typescript 4.1.3

I ran:

PUPPETEER_PRODUCT=chrome deno run -A --unstable https://deno.land/x/[email protected]/install.ts

Which completed successfully.

I then tested the example:

import puppeteer from "https://deno.land/x/[email protected]/mod.ts";

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto("https://example.com");
await page.screenshot({ path: "example.png" });

await browser.close();

But it throws an error:

λ deno run -A --unstable ./example.js
error: Uncaught (in promise) Error: Protocol error (Target.setDiscoverTargets): Target closed.
      this._callbacks.set(id, { resolve, reject, error: new Error(), method });
                                                        ^
    at https://deno.land/x/[email protected]/vendor/puppeteer-core/puppeteer/common/Connection.js:69:57
    at new Promise (<anonymous>)
    at Connection.send (https://deno.land/x/[email protected]/vendor/puppeteer-core/puppeteer/common/Connection.js:68:12)
    at Function.create (https://deno.land/x/[email protected]/vendor/puppeteer-core/puppeteer/common/Browser.js:127:22)
    at ChromeLauncher.launch (Launcher.ts:113:37)
    at async file:///Users/luke/Desktop/example.js:3:17

`page.pdf()` does not resolve

  • Deno version: 1.20.5 (release, x86_64-pc-windows-msvc)
  • Platform / OS version: Windows 10.0.25126

When I run the hackernews.ts example –

import puppeteer from 'https://deno.land/x/[email protected]/mod.ts';

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto("https://news.ycombinator.com", { waitUntil: "networkidle2" });

console.log('before');
await page.pdf({ path: "hn.pdf", format: "a4" });
console.log('after');

await browser.close();

a file at ./hn.pdf is created, but it appears to be empty, and await page.pdf({ path: './example.pdf' }); never resolves. There are no error message, and the default timeout after 30 seconds also does not occur.

The same code setup does work on my system in NodeJS with Puppeteer v14.1.1 and Chromium 991974, but #4136 in the Puppeteer issues describes something similar, that seems to have been fixed by version 1.13.0.

deno-puppeteer or deno-puppeteer-core ?

Great job !!!
I think there is some more good news about installation and browser requirements.

The README says 'Puppeteer can use any recent version of Chromium or Firefox Nightly, but this version of Puppeteer is only validated against a specific version'[chromium 88.0.4298.0].
In my opinion saying "this version of Puppeteer" is misleading because what we have here is the deno version of puppeteer-core not of puppeteer.
Puppeteer source has two major subtrees, common and node, and while both are needed for the puppeteer product only the first one is used by the library puppeteer-core. As pointed out in puppeteer vs puppeteer-core. installing the puppeteer product means downloading the browser, but for puppeteer-core only an explicit executablePath option has to be set in puppeteer.connect or puppeteer.launch .
I have been able to import deno-puppeteer with no browser dowloading in the following conditions:

  • linux fedora 33, google-chrome-stable 87.0.4280.88 and chromium-browser 87.0.4280.88
  • windows 10, chrome 84.0.4147.135

On both systems, however, pointing the executablePath to firefox starts the browser but eventually exits with an error.

Support args option in chrome options

My options look as follows:

const browser = await launch({
  executablePath: "/usr/bin/chromium-browser",
  args: [
    // Required for Docker version of Puppeteer
    "--no-sandbox",
    "--disable-setuid-sandbox",
    "--headless",
    "--disable-gpu",
    // This will write shared memory files into /tmp instead of /dev/shm,
    // because Docker’s default for /dev/shm is 64MB
    "--disable-dev-shm-usage",
  ],
});

Bit of a mess to be able to run in Docker with alpine. There may be a better option that I'd be open to haha. Regardless, it seems puppeteer is happy with these options and runs well. However, the types don't support this giving me a false positive type error. I'm guessing it's ChromeOptions that needs to be a bit more flexible? Not sure. What do you think?

Thanks for this great module!

deno 1.14.0 import puppeteer does proc.kill(9)

reproduce with deno upgrade (or explicitly deno upgrade --version 1.14.0 then create file.js with:

import puppeteer from 'https://deno.land/x/puppeteer/mod.ts';

then deno run -A --unstable file.js

resulting error

error: TS2345 [ERROR]: Argument of type 'number' is not assignable to parameter of type 'string'.
        this.proc.kill(9);
                       ^
    at https://deno.land/x/[email protected]/vendor/puppeteer-core/puppeteer/deno/BrowserRunner.ts:125:24

environment: macos 11.6 M1 2020; deno release in all instances mentioned here are for aarch64-apple-darwin
temporary solution: deno upgrade --version 1.13.2

pdf binary contents

I'm trying to grab binary pdf contents.
Writing to file works fine.
In node pdf() returns Promise<Buffer>.
In deno promise always resolves to Uint8Array(2) [ 0, 0 ]
Can't get how to make work.
Any piece of advice?

Types and execution context (evaluation functions): suggested patterns

When writing evaluation functions to be executed in a puppeteer page (e.g. page.evaluate(fn)), it is desirable to have access to the native TS window and DOM types within those functions.

The two environments (Deno and browser) share quite a bit of API overlap, but also have some exclusive parts (e.g. globalThis.Deno in Deno vs window.document in browser, etc.). One simple approach is to include all type libs in a Deno config, like this:

deno.json:

{
  "compilerOptions": {
    "lib": [
      "deno.window",
      "dom",
      "dom.iterable"
    ]
  }
}

However — because runtime errors will occur when using browser-exclusive APIs in Deno (or Deno-exclusive APIs in browser evaluation functions) — the above approach prevents the compiler from catching these environment-mismatch errors and emitting related diagnostics.

To me, at least, it is desirable to maintain type safety in these independent execution contexts (Deno vs browser). Are there any established patterns for this?

`Page` event `pageerror` error isn't an `Error` instance

The Page event pageerror callback provides an error that isn't an Error instance. The puppeteer docs and TypeScript type definitions seem to indicate it should be, so perhaps something is being lost in translation from Node.js to Deno?

They are objects with a message property, but none of the properties are enumerable and code like this will result in nothing except blank lines being logged:

const page = await browser.newPage();
page.once("pageerror", (error) => {
  console.error(error);
});

Download ARM Chromium builds on M1 Mac

On a M1 Mac the install script currently downloads a Intel (x86_64) build of chromium while there are arm builds available nowadays.

It would be nice if the install script downloaded the ARM version when using an M1 Mac.

Trouble installing chrome - this.proc.kill("SIGKILL")

I get this

$ PUPPETEER_PRODUCT=chrome deno run -A --unstable https://deno.land/x/[email protected]/install.ts
Check https://deno.land/x/[email protected]/install.ts
error: TS2345 [ERROR]: Argument of type 'string' is not assignable to parameter of type 'number'.
        this.proc.kill("SIGKILL");

Not sure on how to fix it since I would also imagine that it needs a number to keep a specific process.

https://github.com/lucacasonato/deno-puppeteer/blob/main/src/deno/BrowserRunner.ts#:~:text=not%20be%20found.-,if%20(this.proc%20%26%26%20this.proc.pid%20%26%26%20!this._closed)%20%7B,%7D,-//%20Cleanup%20this%20listener

Missing `pipe` option in `puppeteer.launch([options])`

When the following code is ran, a WebSocket connection to the browser is established.

const browser = await puppeteer.launch({pipe: true});

But according to puppeteer.launch, a pipe should be used instead:

pipe <boolean> Connects to the browser over a pipe instead of a WebSocket. Defaults to false.

Seems the code doesn't care about the pipe option:

const {
ignoreDefaultArgs = false,
args = [],
executablePath = null,
env = Deno.env.toObject(),
ignoreHTTPSErrors = false,
defaultViewport = { width: 800, height: 600 },
slowMo = 0,
timeout = 30000,
dumpio = false,
} = options;

Cannot Install Firefox: error: stdout was not piped

Running the firefox install script in the docs, the download completes then I get

error: Uncaught (in promise) TypeError: stdout was not piped
    const stdout = new TextDecoder().decode(await proc.output());

System Info:
M1 MacOs 11.1
deno 1.10.3 (release, aarch64-apple-darwin)
v8 9.1.269.27
typescript 4.2.2

page.hover seemingly not working

To reproduce:
https://github.com/kemicofa/deno-puppeteer-hover-example

I'm trying to cause a color change on hover over one of the buttons on my website

From:
Screenshot 2022-01-16 at 15 32 40

To:
Screenshot 2022-01-16 at 15 33 19

However, through deno-puppeteer the color stays the same using the following code:

const browser = await puppeteer.launch();
const page = await browser.newPage();

const url = 'https://sweet-snake-49.deno.dev';
await page.goto(url);
await page.setViewport({
    width: 1600,
    height: 1200
});
await page.hover('#left');
await page.screenshot({ path: Deno.cwd() + '/example.png' }); 

await browser.close();

Adding `{headless:false}` to readme examples when using Chrome makes them hang for 30 seconds and then throw a `TimeoutError` (browser doesn't launch)

I've tried this on my own machine (PopOS 20.04), and on a completely fresh installation of Ubuntu 20.04. I'm using the example.js script from the readme. It works fine without the {headless:false}, and Node.js has no troubles with the {headless:false}. Also, it's only a problem for Chrome - Firefox works fine.

Perhaps headful mode is not supported and the readme just needs to be updated to communicate this?

My exact steps on the fresh Ubuntu install were:

  1. Install Deno with curl -fsSL https://deno.land/x/install/install.sh | sh
  2. Install Chrome with PUPPETEER_PRODUCT=chrome deno run -A --unstable https://deno.land/x/[email protected]/install.ts
  3. Copy example.js code from readme
  4. Run PUPPETEER_PRODUCT=chrome deno run -A --unstable example.js to confirm that it works without {headless:false} (it does)
  5. Add {headless:false} and try again

And at step 5 it gives the TimeoutError:

error: Uncaught TimeoutError: Timed out after 30000 ms while trying to connect to the browser! Only Chrome at revision r1022525 is guaranteed to work.
    throw new TimeoutError(
          ^
    at https://deno.land/x/[email protected]/src/deno/BrowserRunner.ts:163:11
    at Object.action (deno:ext/web/02_timers.js:148:13)
    at handleTimerMacrotask (deno:ext/web/02_timers.js:65:12)

I've confirmed that it did download r1022525 - at least according to the logs produced by the install.ts script.

$eval and $$eval TypeScript return types incorrectly wrap all values in ElementHandle

The return value of $eval and $$eval should only be wrapped in an ElementHandle when they are of type Element.
However, the TypeScript return types of these functions indicate that all return values are wrapped in ElementHandles, regardless of their types.

The problems seems to come from this line:
https://github.com/lucacasonato/deno-puppeteer/blob/14.1.1/vendor/puppeteer-core/puppeteer/common/EvalTypes.d.ts#L66

In the upstream puppeteer repo this line correctly checks if the type extends Element before wrapping it in an ElementHandle (https://github.com/puppeteer/puppeteer/blob/v14.1.1/src/common/EvalTypes.ts#L75), but in this deno port, the type Element is replaced with the type any, causing the aforementioned bug.

`error: Uncaught (in promise) BadResource: Bad resource ID`

Just tried to run the example code from README:

PUPPETEER_PRODUCT=chrome deno run -A --unstable https://deno.land/x/[email protected]/install.ts

example.js / example.ts:

import puppeteer from "https://deno.land/x/[email protected]/mod.ts";

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto("https://example.com");
await page.screenshot({ path: "example.png" });

await browser.close();

And then:

deno run -A --unstable example.ts

Which throws an error:

error: Uncaught (in promise) BadResource: Bad resource ID
    const result = await reader.read(inspectArr);
                   ^
    at async read (deno:runtime/js/12_io.js:105:19)
    at async readDelim (https://deno.land/[email protected]/io/bufio.ts:652:20)
    at async readStringDelim (https://deno.land/[email protected]/io/bufio.ts:702:20)
    at async readLines (https://deno.land/[email protected]/io/bufio.ts:711:18)
    at async waitForWSEndpoint (https://deno.land/x/[email protected]/src/deno/BrowserRunner.ts:167:20)
    at async BrowserRunner.setupConnection (https://deno.land/x/[email protected]/src/deno/BrowserRunner.ts:145:31)
    at async ChromeLauncher.launch (https://deno.land/x/[email protected]/src/deno/Launcher.ts:114:26)
    at async file:///home/ubuntu/Projects/deno-puppeteer/example.ts:3:17

Deno.version:

{ deno: "1.24.3", v8: "10.4.132.20", typescript: "4.7.4" }

NetworkError: failed to connect to WebSocket: Invalid status code

System: Intel macOS 12.6.5

Chrome downloaded via:

PUPPETEER_PRODUCT=chrome deno run -A --unstable https://deno.land/x/[email protected]/install.ts

Simple script:

import puppeteer from 'https:/deno.land/x/[email protected]/mod.ts';
const browser = await puppeteer.launch({
  defaultViewport: { width: 1200, height: 675 },
});

Full error dump:

ErrorEvent {
  bubbles: false,
  cancelable: false,
  composed: false,
  currentTarget: null,
  defaultPrevented: false,
  eventPhase: 0,
  srcElement: null,
  target: WebSocket {
  url: "ws://127.0.0.1:58347/devtools/browser/b767004f-f789-426e-a294-256b9b49c1ed",
  readyState: 3,
  extensions: "",
  protocol: "",
  binaryType: "blob",
  bufferedAmount: 0
},
  returnValue: true,
  timeStamp: 1683480676254,
  type: "error",
  message: "NetworkError: failed to connect to WebSocket: Invalid status code",
  filename: "",
  lineno: 0,
  colno: 0,
  error: DOMException: failed to connect to WebSocket: Invalid status code
}

PermissionDenied:

error: Uncaught (in promise) PermissionDenied: Permission denied (os error 13)
    this.proc = Deno.run({
                     ^
    at Object.opSync (deno:core/01_core.js:172:12)
    at opRun (deno:runtime/js/40_process.js:28:17)
    at Object.run (deno:runtime/js/40_process.js:111:17)
    at BrowserRunner.start (https://deno.land/x/[email protected]/src/deno/BrowserRunner.ts:63:22)
    at ChromeLauncher.launch (https://deno.land/x/[email protected]/src/deno/Launcher.ts:108:12)

Installing FF fails with v9

C:\> set PUPPETEER_PRODUCT=firefox

C:\> deno run -A --unstable https://deno.land/x/[email protected]/install.ts
Download https://deno.land/x/[email protected]/install.ts
Check https://deno.land/x/[email protected]/install.ts

100.00% 21.1s 83721209/83721209

error: Uncaught (in promise) NotFound: The system cannot find the path specified. (os error 3)
      await Deno.writeFile(ff, content);
      ^
    at unwrapOpResult (deno:core/core.js:99:13)
    at async open (deno:runtime/js/40_files.js:46:17)
    at async Object.writeFile (deno:runtime/js/40_write_file.js:58:18)
    at async JSZip.unzip (https://deno.land/x/[email protected]/vendor/puppeteer-core/vendor/zip/mod.ts:203:7)
    at async extractZip (https://deno.land/x/[email protected]/src/deno/BrowserFetcher.ts:473:3)
    at async BrowserFetcher.download (https://deno.land/x/[email protected]/src/deno/BrowserFetcher.ts:283:7)
    at async https://deno.land/x/[email protected]/install.ts:34:27

C:\> deno -V
deno 1.9.2

Installing Chrome worked just fine.

Question: why is browser.close() crasching when using browserless.io

Using https://github.com/guifromrio/puppeteer_on_deploy/blob/main/main.tsx crasches the app when closing.

error: Uncaught ErrorEvent {
  bubbles: false,
  cancelable: false,
  composed: false,
  currentTarget: null,
  defaultPrevented: false,
  eventPhase: 0,
  srcElement: null,
  target: WebSocket {
  url: "wss://chrome.browserless.io/?token=BROWSERLESS_TOKEN",
  readyState: 3,
  extensions: "",
  protocol: "",
  binaryType: "blob",
  bufferedAmount: 0
},
  returnValue: true,
  timeStamp: 1681473331975,
  type: "error",
  message: "WebSocket protocol error: Connection reset without closing handshake",
  filename: "",
  lineno: 0,
  colno: 0,
  error: undefined
}

Any idea on why, maybe it's a browserless.io thing?

Error: Could not find browser revision XXX. Run "PUPPETEER_PRODUCT=chrome deno run -A --unstable https://deno.land/x/puppeteer@VERSION/install.ts" to download a supported browser binary.

Hi, I'm stuck looking for a browser version on my Apple M1 Pro, when I added the puppeteer package, I can't run Supabase function successfully anymore.

Deno info:

🐉 >deno info
DENO_DIR location: /Users/mateuszflisikowski/Library/Caches/deno
Remote modules cache: /Users/mateuszflisikowski/Library/Caches/deno/deps
npm modules cache: /Users/mateuszflisikowski/Library/Caches/deno/npm
Emitted modules cache: /Users/mateuszflisikowski/Library/Caches/deno/gen
Language server registries cache: /Users/mateuszflisikowski/Library/Caches/deno/registries
Origin storage: /Users/mateuszflisikowski/Library/Caches/deno/location_data

Error after call http://localhost:54321/functions/v1/:

Error: Could not find browser revision 1022525. Run "PUPPETEER_PRODUCT=chrome deno run -A --unstable https://deno.land/x/[email protected]/install.ts" to download a supported browser binary.

... 

🐉 >PUPPETEER_PRODUCT=chrome deno run -A --unstable https://deno.land/x/[email protected]/install.ts
Already downloaded at /Users/mateuszflisikowski/Library/Caches/deno/deno_puppeteer/chromium/mac-1022525/chrome-mac/Chromium.app/Contents/MacOS/Chromium

...

mateuszflisikowski ::: ~/Library/Caches/deno/deno_puppeteer/chromium 
🌐 >ls -l
total 0
drwxr-xr-x  3 mateuszflisikowski  staff  96 26 gru 21:02 mac-1022525

Supabase function code, that try to run.

import puppeteer from 'https://deno.land/x/[email protected]/mod.ts';
import { serve } from 'https://deno.land/[email protected]/http/server.ts';

serve(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  await page.goto('https://mflisikowski.dev/cv', {
    waitUntil: 'networkidle2',
  });

  const pdf = await page.pdf({ format: 'A4' });

  await browser.close();

  return new Response(pdf, {
    headers: {
      'Content-Disposition': `attachment; filename="cv.pdf"`,
      'Content-Type': 'application/pdf',
    },
  });
});

Buffer is not defined

Error: Uncaught ReferenceError: Buffer is not defined
? Buffer.from(postData).toString("base64")

Reason:

//this happens when listening to the "request" event
browser = await puppeteer.launch({headless:false});
    const page = await browser.newPage();
    page.setDefaultNavigationTimeout(0);
    page.setRequestInterception(true);
    page.on("request", (interceptedRequest) => {
      interceptedRequest.continue({
        method: "POST",
        postData: new URLSearchParams(body).toString(),
        headers: {
          ...interceptedRequest.headers(),
          "Content-Type": "application/x-www-form-urlencoded",
        },
      });
    });
    await page.goto(url);

Error when saving output of `page.pdf` into variable

The following code which outputs page.pdf into variable

#!/usr/bin/env -S deno -q run -A --unstable
import puppeteer from "https://deno.land/x/puppeteer/mod.ts";

const browser = await puppeteer.launch()
const page = await browser.newPage();

const html = "<html></html>";
await page.goto("data:text/html," + html, {
  waitUntil: 'networkidle2'
});

const pdf = await page.pdf({
  format: 'A4',
})

await browser.close()

fails in Deno Puppeteer versions 16.2.0 and 14.1.1, but works in the version 9.0.2. The error is as follows

error: Uncaught TypeError: reader is not async iterable
  for await (const chunk of reader) {
                            ^
    at getReadableStreamAsUint8Array (https://deno.land/x/[email protected]/vendor/puppeteer-core/puppeteer/common/util.js:329:29)
    at Page.pdf (https://deno.land/x/[email protected]/vendor/puppeteer-core/puppeteer/common/Page.js:2606:24)
    at async file:///home/dir/test.ts:12:13

This error is also absent in newer versions of Puppeteer, f.e. 19.x.x.

Running in Docker

Hi @lucacasonato !

I am trying to create a docker image where I use Deno with Oak and Puppeteer, but I am having some issues with Puppeteer. So far, this is my docker image, but I cannot seem to make it work. I have two main issues at the moment:

1: The install script does not seem to recognize that an existing installation exists
2: Puppeteer is not able to run the downloaded chromium

Here is my Dockerfile (assume that all the variables are set). Let me know if I can provide you with any other information!

FROM hayd/alpine-deno:1.7.2

EXPOSE ${MICROSERVICE_PORT}

WORKDIR /app

# As provided by https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#running-on-alpine
RUN apk add --no-cache \
      nss \
      freetype \
      freetype-dev \
      harfbuzz \
      ca-certificates \
      ttf-freefont 


ENV PUPPETEER_EXECUTABLE_PATH=/deno-dir/deno_puppeteer/chromium/linux-818858/chrome-linux/chrome

ADD . .

RUN PUPPETEER_PRODUCT=chrome deno run -A --unstable https://deno.land/x/puppeteer@${PUPPETEER_VERSION}/install.ts

RUN deno install -qAf --unstable https://deno.land/x/denon/denon.ts

RUN deno cache --unstable src/deps.ts

RUN deno cache --unstable src/mod.ts

USER deno

ENTRYPOINT [ "denon"]

CMD ["run","--unstable","-A","src/mod.ts" ]

This is the error that I am receiving when I try to use Puppeteer:

Error: Failed to launch the browser process!
TROUBLESHOOTING: https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md

    at waitForWSEndpoint (BrowserRunner.ts:174:9)
    at async BrowserRunner.setupConnection (BrowserRunner.ts:143:31)
    at async ChromeLauncher.launch (Launcher.ts:108:26)
    at async createPDF (pdf-handler.ts:4:19)
    at async routes.ts:14:19
    at async dispatch (middleware.ts:41:7)
    at async dispatch (middleware.ts:41:7)
    at async dispatch (middleware.ts:41:7)
    at async Application.#handleRequest (application.ts:252:9)

Bad resource ID when closing browser

Running both the scripts in the examples given in the readme I get the following error:

error: Uncaught (in promise) BadResource: Bad resource ID
at processResponse (deno:core/core.js:212:11)
at jsonOpSync (deno:core/core.js:236:12)
at Object.close (deno:core/core.js:252:5)
at WebSocket.#eventLoop (deno:op_crates/websocket/01_websocket.js:368:18)

For this example the following code was used but the error is given every time I run the await browser.close() command.

import puppeteer from "https://deno.land/x/[email protected]/mod.ts";

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto("https://example.com");
await page.screenshot({ path: "example.png" });

await browser.close();

The screenshot does get saved so the problem really seems to be once puppeteer is finished.

Error: JSHandle#uploadFile can only be used in Node-like environments on deno-puppeteer-16.2.0

Hello, thank you for your effort in this project.

I could use puppeteer on v14.1.1, I recently update the library to v16.2.0 and found that the upload is not working. When click on the browse button, an error happen:

error: Uncaught (in promise) Error: JSHandle#uploadFile can only be used in Node-like environments.
        throw new Error(
              ^
    at ElementHandle.uploadFile (https://deno.land/x/[email protected]/vendor/puppeteer-core/puppeteer/common/ElementHandle.js:668:15)
    at async FileChooser.accept (https://deno.land/x/[email protected]/vendor/puppeteer-core/puppeteer/common/FileChooser.js:122:5)

Deno:

$ deno --version                                                                                               
deno 1.25.2 (release, x86_64-apple-darwin)
v8 10.6.194.5
typescript 4.7.4

deno compile error

I have a script, the only dependency is deno-puppeteer. When I compile using deno compile -A --unstable example.js it generates an .exe with no error. But when I run the generated example.exe I get the following error:

error: ReferenceError: joinGlobs is not defined
    at file://$deno$/bundle.js:13267:20

I found one other GitHub issue referencing such an error here: denoland/deno#9257 (comment)

Tnx for a great lib!

Issue installing on windows

Not very familiar with JS let alone Deno, but was having issues when I followed the instructions with the "PUPPETEER_PRODUCT=firefox deno run -A --unstable https://deno.land/x/[email protected]/install.ts" line (I also tried the chrome as well). Added puppeteer to my path, created new env variables, deleted and reinstalled, nothing got it to work. Eventually I installed chrome and ran "run -A --unstable https://deno.land/x/[email protected]/install.ts" instead and was able to get it to work. Unsure if anything I did fixed it or if the documentation just isn't as clear for windows, but imo its worth thinking about at least a little.

`Deno.core.runMicrotasks()` is not supported in this environment

First of all, thank you very much for your work on Deno, its ecosystem, in the TC39 as a deligate (Response.json wooo!), with Fresh, and in general in open source. It's extremely appreciated and you're doing a great job!

This evening, after upgrading from deno v1.29.4 to deno v1.30.0 I began to see the following error when I ran code which imports this module:

error: Uncaught Error: Deno.core.runMicrotasks() is not supported in this environment
      throw new Error(
            ^
    at Object.runMicrotasks (https://deno.land/[email protected]/node/_core.ts:22:13)
    at processTicksAndRejections (https://deno.land/[email protected]/node/_next_tick.ts:62:10)
    at https://deno.land/[email protected]/node/process.ts:375:7
    at innerInvokeEventListeners (deno:ext/web/02_event.js:776:9)
    at invokeEventListeners (deno:ext/web/02_event.js:816:7)
    at dispatch (deno:ext/web/02_event.js:685:11)
    at dispatchEvent (deno:ext/web/02_event.js:1066:14)
    at [deno:cli/worker.rs:90:39]:1:1

Here is all that is needed to reproduce this error:

// ./mod.ts

import puppeteer from "https://deno.land/x/[email protected]/mod.ts";

if (import.meta.main) {
  console.log(puppeteer);
}

deno run --allow-env ./mod.ts

For context, here is information about my environment:

Deno Version: 1.30.0
deno --version
deno 1.30.0 (release, x86_64-unknown-linux-gnu)
v8 10.9.194.5
typescript 4.9.4

OS: Pop!_OS 22.04 LTS x86_64 (Linux)

Also, I looked into this error a little (at the referenced line at the top of the stack trace https://deno.land/[email protected]/node/_core.ts:22:13 as well as the analogous code in the latest version of stdlib https://deno.land/[email protected]/node/_core.ts?source#L26), which prompted me to go into the repl and just see what I get when I check the availability of that internal Deno-core set of APIs, and found the following:

> Deno?.[Deno.internal]?.core.runMicrotasks.toString()
"() => ops.op_run_microtasks()"
> Deno?.core?.runMicrotasks
undefined

so, apparently between deno v1.29.4 and deno v1.30.0, something was moved out of Deno.core and into Deno[Deno.internal].core (if I'm reading this right). I did not check if this was just the fruition of a deprecation, but I wouldn't be surprised to learn that it was given that we just crossed a new minor.

It's possible that all that's needed to address this is to bump the versions of the stdlib being used by deno-puppeteer but I wanted to surface this error in case there's something deeper going on.


I looked around for alternate puppeteer modules for Deno, and found that this one, https://deno.land/x/[email protected], is able to run a simple script just fine for me:

e.g.

// ./second-mod.ts

import { puppeteer } from "https://deno.land/x/[email protected]/mod.ts";

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto("https://example.com");
await page.screenshot({ path: "example.png" });

await browser.close();

deno run -A ./second-mod.ts

but there are no others which worked when I tried for various reasons (most seem to be due to things being out of date).

Also weird, is that the GitHub repo associated with https://deno.land/x/[email protected] is 404'ing , and in fact, so is that entire user account...weird 😬

getting PermissionDenied: 'Deno.makeTempDir' is not allowed in this context

Locally it works fine, running with allow-write on deno run.

when I run on deno, on the logs I get;

PermissionDenied: 'Deno.makeTempDir' is not allowed in this context. at Object.makeTempDir (deno:deploy/js/02_fs.js:193:9) at ChromeLauncher.launch (https://deno.land/x/[email protected]/src/deno/Launcher.ts:31:49) at PuppeteerDeno.launch (https://deno.land/x/[email protected]/src/deno/Puppeteer.ts:115:31) at crawl (file:///src/index.js:136:35)

not sure it's a newbie question but how can I run allow-write on deno?

Installing puppeteer with firefox option

When I tried to install puppeteer by typing "PUPPETEER_PRODUCT=firefox deno run -A --unstable https://deno.land/x/[email protected]/install.ts" in the terminal, I got this error:

PUPPETEER_PRODUCT=firefox : The term 'PUPPETEER_PRODUCT=firefox' is not recognized as the name of a cmdlet, function, script file, or
operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1

  • PUPPETEER_PRODUCT=firefox deno run -A --unstable https://deno.land/x/ ...
  •   + CategoryInfo          : ObjectNotFound: (PUPPETEER_PRODUCT=firefox:String) [], CommandNotFoundException
      + FullyQualifiedErrorId : CommandNotFoundException
    

Where to write this command to install firefox?
Thanks in advance...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.