Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BREAKING: Migrate to deno-puppeteer #123

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,5 @@ jobs:
run: chrome --version
- name: Run tests
run: |
deno task test
CAROL_DEBUG=1 deno task test

38 changes: 25 additions & 13 deletions carol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ interface ExtendedSelf extends Self {
receivedFromParent(message: Messages.Any): void;
}

// deno-lint-ignore no-explicit-any
type PageFunctionArgs = any[];

interface PageFunction {
// deno-lint-ignore no-explicit-any
(...args: PageFunctionArgs): any;
}

interface Carol {
loadParams(): Promise<unknown>;
}
Expand Down Expand Up @@ -222,8 +230,11 @@ class Application extends EventEmitter implements types.Application {
);
}

// deno-lint-ignore no-explicit-any, ban-types
evaluate(pageFunction: Function | string, ...args: unknown[]): Promise<any> {
evaluate(
pageFunction: PageFunction | string,
...args: PageFunctionArgs
// deno-lint-ignore no-explicit-any
): Promise<any> {
return this.mainWindow().evaluate(pageFunction, ...args);
}

Expand Down Expand Up @@ -322,7 +333,7 @@ class Window extends EventEmitter implements types.Window {

private loadParams_!: unknown[];
private domContentLoadedCallback_?: () => void;
private windowId_: unknown;
private windowId_!: number;
private interceptionInitialized_ = false;
private hostHandle_: HandleProxy;
private receivedFromChild_!: (message: Messages.Any) => void;
Expand Down Expand Up @@ -352,7 +363,7 @@ class Window extends EventEmitter implements types.Window {
*/
async init_(): Promise<void> {
this.logger_.debug("[app] Configuring window");
const targetId = this.page_.target()._targetInfo.targetId;
const targetId = this.page_.target()._targetId;
assert(this.options_.bgcolor);
const bgcolor = Color.parse(this.options_.bgcolor);
assert(bgcolor, "Invalid bgcolor");
Expand Down Expand Up @@ -394,9 +405,8 @@ class Window extends EventEmitter implements types.Window {
}

async evaluate(
// deno-lint-ignore ban-types
pageFunction: string | Function,
...args: unknown[]
pageFunction: string | PageFunction,
...args: PageFunctionArgs
// deno-lint-ignore no-explicit-any
): Promise<any> {
try {
Expand Down Expand Up @@ -444,7 +454,7 @@ class Window extends EventEmitter implements types.Window {
// Await here to process exceptions.
await this.page_.goto(
new URL(this.loadURI_, "https://domain/").toString(),
{ timeout: 0, waitFor: "domcontentloaded" },
{ timeout: 0, waitUntil: "domcontentloaded" },
);
// Available in Chrome M73+.
this.session_.send("Page.resetNavigationHistory").catch((_e) => {});
Expand All @@ -453,7 +463,7 @@ class Window extends EventEmitter implements types.Window {
return result;
}

initBounds_(result: { windowId: unknown }) {
initBounds_(result: { windowId: number }) {
this.windowId_ = result.windowId;
return this.setBounds(
{
Expand Down Expand Up @@ -664,23 +674,23 @@ class Window extends EventEmitter implements types.Window {
}

async fullscreen(): Promise<void> {
const bounds = { windowState: "fullscreen" };
const bounds = { windowState: "fullscreen" } as const;
await this.app_.session_.send(
"Browser.setWindowBounds",
{ windowId: this.windowId_, bounds },
);
}

async minimize(): Promise<void> {
const bounds = { windowState: "minimized" };
const bounds = { windowState: "minimized" } as const;
await this.app_.session_.send(
"Browser.setWindowBounds",
{ windowId: this.windowId_, bounds },
);
}

async maximize(): Promise<void> {
const bounds = { windowState: "maximized" };
const bounds = { windowState: "maximized" } as const;
await this.app_.session_.send(
"Browser.setWindowBounds",
{ windowId: this.windowId_, bounds },
Expand Down Expand Up @@ -833,9 +843,11 @@ class HostWindow {
"Runtime.evaluate",
{ expression },
);
const { objectId } = result;
assert(objectId != null, "objectId must be set");
return this.window_.session_.send(
"DOM.getFileInfo",
{ objectId: result.objectId },
{ objectId },
);
}
}
Expand Down
20 changes: 12 additions & 8 deletions deps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,15 @@ export {
fail,
} from "https://deno.land/[email protected]/testing/asserts.ts";

export { default as puppeteer } from "https://unpkg.com/[email protected]/lib/esm/puppeteer/web.js";
export { EventEmitter } from "https://unpkg.com/[email protected]/lib/esm/puppeteer/common/EventEmitter.js";
export { BrowserWebSocketTransport } from "https://unpkg.com/[email protected]/lib/esm/puppeteer/common/BrowserWebSocketTransport.js";

export type { Browser } from "https://unpkg.com/[email protected]/lib/esm/puppeteer/common/Browser.js";
export type { Target } from "https://unpkg.com/[email protected]/lib/esm/puppeteer/common/Target.js";
export type { CDPSession } from "https://unpkg.com/[email protected]/lib/esm/puppeteer/common/Connection.js";
export type { Page } from "https://unpkg.com/[email protected]/lib/esm/puppeteer/common/Page.js";
export {
default as puppeteer,
} from "https://deno.land/x/[email protected]/mod.ts";
export type {
Browser,
CDPSession,
Page,
Protocol,
Target,
} from "https://deno.land/x/[email protected]/mod.ts";
export { EventEmitter } from "https://deno.land/x/[email protected]/vendor/puppeteer-core/puppeteer/common/EventEmitter.js";
export { BrowserWebSocketTransport } from "https://deno.land/x/[email protected]/vendor/puppeteer-core/puppeteer/common/BrowserWebSocketTransport.js";
29 changes: 15 additions & 14 deletions http_request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,13 @@
*/

import { concat, encode, encodeToBase64 } from "./deps.ts";
import type { CDPSession } from "./deps.ts";
import type { CDPSession, Protocol } from "./deps.ts";
import type * as types from "./types.ts";
import { assert } from "./util.ts";

type ContinueInterceptedRequestRequest = Partial<
Protocol.Network.ContinueInterceptedRequestRequest
>;

const statusTexts = {
"100": "Continue",
Expand Down Expand Up @@ -87,7 +92,8 @@ const statusTexts = {
export interface HttpRequestParams {
request: Request;
resourceType: string;
interceptionId: number;
interceptionId:
Protocol.Network.ContinueInterceptedRequestRequest["interceptionId"];
}

interface Request {
Expand All @@ -96,15 +102,6 @@ interface Request {
headers: Record<string, string>;
}

interface ResolveParams {
url?: string;
method?: string;
headers?: Record<string, string>;
interceptionId?: number;
rawResponse?: string;
errorReason?: string;
}

export class HttpRequest implements types.HttpRequest {
done_ = false;

Expand Down Expand Up @@ -150,7 +147,7 @@ export class HttpRequest implements types.HttpRequest {

deferToBrowser(overrides?: types.Overrides) {
this.logger_.debug("[server] deferToBrowser", this.url());
const params = {} as ResolveParams;
const params = {} as ContinueInterceptedRequestRequest;
if (overrides && overrides.url) params.url = overrides.url;
if (overrides && overrides.method) params.method = overrides.method;
if (overrides && overrides.headers) params.headers = overrides.headers;
Expand Down Expand Up @@ -207,11 +204,15 @@ export class HttpRequest implements types.HttpRequest {
this.resolve_({});
}

resolve_(params: ResolveParams): Promise<unknown> {
resolve_(params: ContinueInterceptedRequestRequest): Promise<unknown> {
this.logger_.debug("[server] resolve", this.url());
if (this.done_) throw new Error("Already resolved given request");
params.interceptionId = this.params_.interceptionId;
this.done_ = true;
return this.session_.send("Network.continueInterceptedRequest", params);
assert(params.interceptionId != null);
return this.session_.send(
"Network.continueInterceptedRequest",
params as Protocol.Network.ContinueInterceptedRequestRequest,
);
}
}
42 changes: 25 additions & 17 deletions puppeteer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@ import type { Browser, Target } from "./deps.ts";
import type { AppOptions } from "./types.ts";
import { getLocalDataDir } from "./util.ts";

interface LaunchResult {
browser: Browser;
chromeProcess: Deno.Process;
}

class ExtendedBrowserWebSocketTransport extends BrowserWebSocketTransport {
#ws: WebSocket;

Expand All @@ -40,13 +35,18 @@ class ExtendedBrowserWebSocketTransport extends BrowserWebSocketTransport {
this.#ws = ws;
}

close(): void {
async close(): Promise<void> {
if (this.#ws.readyState === this.#ws.OPEN) {
super.close();
await super.close();
}
}
}

interface LaunchResult {
browser: Browser;
chromeProcess: Deno.Process;
}

export async function launch(
executablePath: string,
headless: boolean,
Expand All @@ -58,16 +58,24 @@ export async function launch(
stderr: "piped",
});
const wsEndpoint = await waitForWSEndpoint(chromeProcess.stderr);
const transport = await ExtendedBrowserWebSocketTransport.create(wsEndpoint);
const browser = await puppeteer.connect({
ignoreHTTPSErrors: true,
transport,
});
await browser.waitForTarget((t: Target) => t.type() === "page");
return {
browser,
chromeProcess,
};
try {
const transport = await ExtendedBrowserWebSocketTransport.create(
wsEndpoint,
);
const browser = await puppeteer.connect({
ignoreHTTPSErrors: true,
transport,
});
await browser.waitForTarget((t: Target) => t.type() === "page");
return {
browser,
chromeProcess,
};
} catch (error) {
console.error(error);
chromeProcess.close();
throw error;
}
}

function prepareChromeArgs(
Expand Down
8 changes: 4 additions & 4 deletions types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,10 @@ export interface Window {
}

export interface Bounds {
left: number;
top: number;
width: number;
height: number;
left?: number;
top?: number;
width?: number;
height?: number;
}

export interface HttpHandler {
Expand Down
6 changes: 6 additions & 0 deletions util.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { dirname, fromFileUrl, join } from "./deps.ts";

export function assert(expr: unknown, msg = ""): asserts expr {
if (!expr) {
throw new Error("assertion failed: " + msg);
}
}

export function getLocalDataDir(): string {
const __dirname = import.meta.url.startsWith("file://")
? dirname(fromFileUrl(import.meta.url))
Expand Down