@open-wa/driver-puppeteer 5.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,113 @@
1
+ import { ConnectOptions, DisposableHandle, DriverCapabilities, IBrowser, IDriver, IDriverContext, IElementHandle, IFrame, IPage, LaunchOptions, NavigationWaitUntil, PageEventHandler, WaitForFunctionOptions } from "@open-wa/driver-interface";
2
+ import { Browser, CDPSession, ElementHandle, Page } from "puppeteer";
3
+
4
+ //#region src/PuppeteerDriver.d.ts
5
+ declare class PuppeteerDriver implements IDriver {
6
+ readonly name: "puppeteer";
7
+ version?: string;
8
+ readonly capabilities: DriverCapabilities;
9
+ private puppeteer;
10
+ private ctx?;
11
+ constructor();
12
+ init(ctx?: IDriverContext): Promise<void>;
13
+ launch(options?: LaunchOptions): Promise<IBrowser>;
14
+ connect(options: ConnectOptions): Promise<IBrowser>;
15
+ unwrap(): any;
16
+ has<C extends string>(cap: C): boolean;
17
+ require<C extends string>(cap: C): void;
18
+ }
19
+ //#endregion
20
+ //#region src/PuppeteerBrowser.d.ts
21
+ declare class PuppeteerBrowser implements IBrowser {
22
+ private browser;
23
+ private capabilities;
24
+ readonly name: "puppeteer";
25
+ constructor(browser: Browser, capabilities: DriverCapabilities);
26
+ newPage(options?: {
27
+ clearFirstPage?: boolean;
28
+ }): Promise<IPage>;
29
+ pages(): Promise<IPage[]>;
30
+ close(): Promise<void>;
31
+ isConnected(): boolean;
32
+ versionString(): Promise<string>;
33
+ unwrap(): Browser;
34
+ }
35
+ //#endregion
36
+ //#region src/PuppeteerPage.d.ts
37
+ declare class PuppeteerPage implements IPage {
38
+ private page;
39
+ private capabilities;
40
+ readonly name: "puppeteer";
41
+ private readonly listenerWrappers;
42
+ constructor(page: Page, capabilities: DriverCapabilities);
43
+ goto(url: string, options?: {
44
+ waitUntil?: NavigationWaitUntil;
45
+ timeoutMs?: number;
46
+ }): Promise<void>;
47
+ url(): string;
48
+ reload(): Promise<void>;
49
+ mainFrame(): IFrame;
50
+ evaluateOnNewDocument<Arg, Ret>(fn: (arg: Arg) => Ret | Promise<Ret>, arg: Arg): Promise<void>;
51
+ evaluate<Arg, Ret>(fn: (arg: Arg) => Ret | Promise<Ret>, arg: Arg): Promise<Ret>;
52
+ evaluateScript<Ret = unknown>(script: string): Promise<Ret>;
53
+ addInitScript(script: string): Promise<DisposableHandle>;
54
+ setViewport(viewport: {
55
+ width: number;
56
+ height: number;
57
+ }): Promise<void>;
58
+ setUserAgent(ua: string): Promise<void>;
59
+ setRequestInterception(enabled: boolean): Promise<void>;
60
+ waitForSelector(selector: string, options?: {
61
+ timeoutMs?: number;
62
+ }): Promise<IElementHandle | null>;
63
+ waitForFunction<Arg>(script: string, options?: WaitForFunctionOptions): Promise<void>;
64
+ waitForFunction<Arg>(fn: (arg: Arg) => boolean, arg: Arg, options?: WaitForFunctionOptions): Promise<void>;
65
+ $(selector: string): Promise<IElementHandle | null>;
66
+ $$(selector: string): Promise<IElementHandle[]>;
67
+ click(selector: string): Promise<void>;
68
+ type(selector: string, text: string, options?: {
69
+ delayMs?: number;
70
+ }): Promise<void>;
71
+ screenshot(options?: {
72
+ type?: 'png' | 'jpeg';
73
+ fullPage?: boolean;
74
+ }): Promise<Uint8Array>;
75
+ exposeFunction(name: string, fn: (...args: any[]) => any): Promise<void>;
76
+ on<K extends string>(event: K, handler: ((...args: any[]) => void | Promise<void>) | PageEventHandler<any>): DisposableHandle;
77
+ off<K extends string>(event: K, handler: ((...args: any[]) => void | Promise<void>) | PageEventHandler<any>): void;
78
+ close(): Promise<void>;
79
+ isClosed(): boolean;
80
+ has<C extends string>(cap: C): boolean;
81
+ require<C extends string>(cap: C): void;
82
+ cdp(): Promise<CDPSession>;
83
+ setBypassServiceWorker(bypass: boolean): Promise<void>;
84
+ pdf(options?: {
85
+ path?: string;
86
+ format?: string;
87
+ }): Promise<Uint8Array>;
88
+ startTracing(options?: {
89
+ path?: string;
90
+ screenshots?: boolean;
91
+ }): Promise<void>;
92
+ stopTracing(): Promise<Uint8Array>;
93
+ unwrap(): Page;
94
+ private getWrapperSet;
95
+ private removeWrappedListener;
96
+ private getInitScriptIdentifier;
97
+ private wrapEventPayload;
98
+ }
99
+ //#endregion
100
+ //#region src/PuppeteerElementHandle.d.ts
101
+ declare class PuppeteerElementHandle implements IElementHandle {
102
+ private element;
103
+ constructor(element: ElementHandle);
104
+ click(): Promise<void>;
105
+ type(text: string): Promise<void>;
106
+ getAttribute(name: string): Promise<string | null>;
107
+ textContent(): Promise<string | null>;
108
+ dispose(): Promise<void>;
109
+ unwrap(): ElementHandle;
110
+ }
111
+ //#endregion
112
+ export { PuppeteerBrowser, PuppeteerDriver, PuppeteerElementHandle, PuppeteerPage };
113
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/PuppeteerDriver.ts","../src/PuppeteerBrowser.ts","../src/PuppeteerPage.ts","../src/PuppeteerElementHandle.ts"],"mappings":";;;;cAGa,eAAA,YAA2B,OAAA;EAAA,SAC3B,IAAA;EACT,OAAA;EAAA,SACS,YAAA,EAAc,kBAAA;EAAA,QAEf,SAAA;EAAA,QACA,GAAA;;EAgBF,IAAA,CAAK,GAAA,GAAM,cAAA,GAAiB,OAAA;EAgB5B,MAAA,CAAO,OAAA,GAAU,aAAA,GAAgB,OAAA,CAAQ,QAAA;EAoBzC,OAAA,CAAQ,OAAA,EAAS,cAAA,GAAiB,OAAA,CAAQ,QAAA;EAWhD,MAAA,CAAA;EAIA,GAAA,kBAAA,CAAsB,GAAA,EAAK,CAAA;EAI3B,OAAA,kBAAA,CAA0B,GAAA,EAAK,CAAA;AAAA;;;cC5EtB,gBAAA,YAA4B,QAAA;EAAA,QAIzB,OAAA;EAAA,QACA,YAAA;EAAA,SAJH,IAAA;cAGG,OAAA,EAAS,OAAA,EACT,YAAA,EAAc,kBAAA;EAGpB,OAAA,CAAQ,OAAA;IACV,cAAA;EAAA,IACA,OAAA,CAAQ,KAAA;EAWN,KAAA,CAAA,GAAS,OAAA,CAAQ,KAAA;EAKjB,KAAA,CAAA,GAAS,OAAA;EAIf,WAAA,CAAA;EAIM,aAAA,CAAA,GAAiB,OAAA;EAIvB,MAAA,CAAA,GAAU,OAAA;AAAA;;;cCwHD,aAAA,YAAyB,KAAA;EAAA,QAKtB,IAAA;EAAA,QACA,YAAA;EAAA,SALH,IAAA;EAAA,iBACQ,gBAAA;cAGL,IAAA,EAAM,IAAA,EACN,YAAA,EAAc,kBAAA;EAGpB,IAAA,CAAK,GAAA,UAAa,OAAA;IAAY,SAAA,GAAY,mBAAA;IAAqB,SAAA;EAAA,IAAuB,OAAA;EAO5F,GAAA,CAAA;EAIM,MAAA,CAAA,GAAU,OAAA;EAIhB,SAAA,CAAA,GAAa,MAAA;EAIP,qBAAA,UAAA,CACF,EAAA,GAAK,GAAA,EAAK,GAAA,KAAQ,GAAA,GAAM,OAAA,CAAQ,GAAA,GAChC,GAAA,EAAK,GAAA,GACN,OAAA;EAIG,QAAA,UAAA,CAAmB,EAAA,GAAK,GAAA,EAAK,GAAA,KAAQ,GAAA,GAAM,OAAA,CAAQ,GAAA,GAAM,GAAA,EAAK,GAAA,GAAM,OAAA,CAAQ,GAAA;EAS5E,cAAA,eAAA,CAA8B,MAAA,WAAiB,OAAA,CAAQ,GAAA;EAQvD,aAAA,CAAc,MAAA,WAAiB,OAAA,CAAQ,gBAAA;EAiBvC,WAAA,CAAY,QAAA;IAAY,KAAA;IAAe,MAAA;EAAA,IAAmB,OAAA;EAI1D,YAAA,CAAa,EAAA,WAAa,OAAA;EAI1B,sBAAA,CAAuB,OAAA,YAAmB,OAAA;EAK1C,eAAA,CAAgB,QAAA,UAAkB,OAAA;IAAY,SAAA;EAAA,IAAuB,OAAA,CAAQ,cAAA;EAY7E,eAAA,KAAA,CAAqB,MAAA,UAAgB,OAAA,GAAU,sBAAA,GAAyB,OAAA;EACxE,eAAA,KAAA,CAAqB,EAAA,GAAK,GAAA,EAAK,GAAA,cAAiB,GAAA,EAAK,GAAA,EAAK,OAAA,GAAU,sBAAA,GAAyB,OAAA;EAoC7F,CAAA,CAAE,QAAA,WAAmB,OAAA,CAAQ,cAAA;EAK7B,EAAA,CAAG,QAAA,WAAmB,OAAA,CAAQ,cAAA;EAK9B,KAAA,CAAM,QAAA,WAAmB,OAAA;EAIzB,IAAA,CAAK,QAAA,UAAkB,IAAA,UAAc,OAAA;IAAY,OAAA;EAAA,IAAqB,OAAA;EAItE,UAAA,CAAW,OAAA;IAAY,IAAA;IAAuB,QAAA;EAAA,IAAuB,OAAA,CAAQ,UAAA;EAK7E,cAAA,CAAe,IAAA,UAAc,EAAA,MAAQ,IAAA,kBAAsB,OAAA;EAIjE,EAAA,kBAAA,CAAqB,KAAA,EAAO,CAAA,EAAG,OAAA,OAAc,IAAA,mBAAuB,OAAA,UAAiB,gBAAA,QAAwB,gBAAA;EAiB7G,GAAA,kBAAA,CAAsB,KAAA,EAAO,CAAA,EAAG,OAAA,OAAc,IAAA,mBAAuB,OAAA,UAAiB,gBAAA;EAchF,KAAA,CAAA,GAAS,OAAA;EAIf,QAAA,CAAA;EAIA,GAAA,kBAAA,CAAsB,GAAA,EAAK,CAAA;EAI3B,OAAA,kBAAA,CAA0B,GAAA,EAAK,CAAA;EAUzB,GAAA,CAAA,GAAO,OAAA,CAAQ,UAAA;EAKf,sBAAA,CAAuB,MAAA,YAAkB,OAAA;EAKzC,GAAA,CAAI,OAAA;IAAY,IAAA;IAAe,MAAA;EAAA,IAAoB,OAAA,CAAQ,UAAA;EAM3D,YAAA,CAAa,OAAA;IAAY,IAAA;IAAe,WAAA;EAAA,IAA0B,OAAA;EAKlE,WAAA,CAAA,GAAe,OAAA,CAAQ,UAAA;EAM7B,MAAA,CAAA,GAAU,IAAA;EAAA,QAIF,aAAA;EAAA,QAgBA,qBAAA;EAAA,QAkBA,uBAAA;EAAA,QAcA,gBAAA;AAAA;;;cCjcC,sBAAA,YAAkC,cAAA;EAAA,QACvB,OAAA;cAAA,OAAA,EAAS,aAAA;EAEvB,KAAA,CAAA,GAAS,OAAA;EAIT,IAAA,CAAK,IAAA,WAAe,OAAA;EAIpB,YAAA,CAAa,IAAA,WAAe,OAAA;EAK5B,WAAA,CAAA,GAAe,OAAA;EAKf,OAAA,CAAA,GAAW,OAAA;EAIjB,MAAA,CAAA,GAAU,aAAA;AAAA"}
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@open-wa/driver-puppeteer",
3
+ "version": "5.0.0-alpha.0",
4
+ "description": "Puppeteer driver implementation for open-wa",
5
+ "main": "./dist/index.cjs",
6
+ "types": "./dist/index.d.cts",
7
+ "exports": {
8
+ ".": {
9
+ "require": "./dist/index.cjs",
10
+ "import": "./dist/index.cjs",
11
+ "types": "./dist/index.d.cts"
12
+ }
13
+ },
14
+ "dependencies": {
15
+ "puppeteer": "^24.40.0",
16
+ "puppeteer-extra": "^3.3.6",
17
+ "@open-wa/driver-interface": "5.0.0-alpha.0"
18
+ },
19
+ "devDependencies": {
20
+ "@types/node": "^25.9.1",
21
+ "typescript": "^6.0.3",
22
+ "vitest": "4.1.2"
23
+ },
24
+ "publishConfig": {
25
+ "access": "public"
26
+ },
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "https://github.com/open-wa/wa-automate-nodejs.git"
30
+ },
31
+ "scripts": {
32
+ "build": "tsdown src/index.ts --format cjs",
33
+ "dev": "tsdown src/index.ts --format cjs --watch",
34
+ "lint": "oxlint src",
35
+ "test": "vitest run"
36
+ }
37
+ }
@@ -0,0 +1,46 @@
1
+ import { IBrowser, IPage, DriverCapabilities } from '@open-wa/driver-interface';
2
+ import type { Browser } from 'puppeteer';
3
+ import { PuppeteerPage } from './PuppeteerPage';
4
+
5
+ export class PuppeteerBrowser implements IBrowser {
6
+ readonly name = 'puppeteer' as const;
7
+
8
+ constructor(
9
+ private browser: Browser,
10
+ private capabilities: DriverCapabilities
11
+ ) { }
12
+
13
+ async newPage(options?: {
14
+ clearFirstPage?: boolean
15
+ }): Promise<IPage> {
16
+ const page = await this.browser.newPage();
17
+ if (options?.clearFirstPage) {
18
+ const pages = await this.browser.pages();
19
+ if (pages.length > 0) {
20
+ await pages[0].close();
21
+ }
22
+ }
23
+ return new PuppeteerPage(page, this.capabilities);
24
+ }
25
+
26
+ async pages(): Promise<IPage[]> {
27
+ const pages = await this.browser.pages();
28
+ return pages.map(p => new PuppeteerPage(p, this.capabilities));
29
+ }
30
+
31
+ async close(): Promise<void> {
32
+ await this.browser.close();
33
+ }
34
+
35
+ isConnected(): boolean {
36
+ return this.browser.isConnected();
37
+ }
38
+
39
+ async versionString(): Promise<string> {
40
+ return await this.browser.version();
41
+ }
42
+
43
+ unwrap(): Browser {
44
+ return this.browser;
45
+ }
46
+ }
@@ -0,0 +1,91 @@
1
+ import { IDriver, IBrowser, LaunchOptions, ConnectOptions, IDriverContext, DriverCapabilities } from '@open-wa/driver-interface';
2
+ import { PuppeteerBrowser } from './PuppeteerBrowser';
3
+
4
+ export class PuppeteerDriver implements IDriver {
5
+ readonly name = 'puppeteer' as const;
6
+ version?: string;
7
+ readonly capabilities: DriverCapabilities;
8
+
9
+ private puppeteer: any;
10
+ private ctx?: IDriverContext;
11
+
12
+ constructor() {
13
+ this.capabilities = {
14
+ cdp: { supported: true },
15
+ requestInterception: { supported: true },
16
+ serviceWorkerBypass: { supported: true },
17
+ stealth: { supported: true, notes: 'Via puppeteer-extra plugins' },
18
+ pdf: { supported: true },
19
+ tracing: { supported: true, notes: 'Basic tracing support' },
20
+ persistentContext: { supported: true },
21
+ browserExtensions: { supported: true },
22
+ exposeBinding: { supported: true },
23
+ };
24
+ }
25
+
26
+ async init(ctx?: IDriverContext): Promise<void> {
27
+ this.ctx = ctx;
28
+
29
+ const pExtra = await import('puppeteer-extra');
30
+ this.puppeteer = pExtra.default ?? pExtra;
31
+
32
+ try {
33
+ const { createRequire } = await import('node:module');
34
+ const _require = createRequire(__filename);
35
+ const pkg = _require('puppeteer/package.json');
36
+ this.version = pkg.version;
37
+ } catch {}
38
+
39
+ this.ctx?.logger?.info('PuppeteerDriver initialized', { version: this.version });
40
+ }
41
+
42
+ async launch(options?: LaunchOptions): Promise<IBrowser> {
43
+ if (!this.puppeteer) await this.init();
44
+
45
+ const browser = await this.puppeteer.launch({
46
+ headless: options?.headless ?? true,
47
+ executablePath: options?.executablePath,
48
+ args: options?.args || [],
49
+ defaultViewport: options?.defaultViewport,
50
+ userDataDir: options?.userDataDir,
51
+ timeout: options?.timeoutMs,
52
+ });
53
+
54
+ try {
55
+ const browserVersion = await browser.version();
56
+ this.ctx?.logger?.info('Browser executable version', { version: browserVersion });
57
+ } catch {}
58
+
59
+ return new PuppeteerBrowser(browser, this.capabilities);
60
+ }
61
+
62
+ async connect(options: ConnectOptions): Promise<IBrowser> {
63
+ if (!this.puppeteer) await this.init();
64
+
65
+ const browser = await this.puppeteer.connect({
66
+ browserWSEndpoint: options.wsEndpoint,
67
+ timeout: options?.timeoutMs,
68
+ });
69
+
70
+ return new PuppeteerBrowser(browser, this.capabilities);
71
+ }
72
+
73
+ unwrap(): any {
74
+ return this.puppeteer;
75
+ }
76
+
77
+ has<C extends string>(cap: C): boolean {
78
+ return (this.capabilities as any)[cap]?.supported === true;
79
+ }
80
+
81
+ require<C extends string>(cap: C): void {
82
+ if (!this.has(cap)) {
83
+ const capability = (this.capabilities as any)[cap];
84
+ throw new Error(
85
+ `Driver '${this.name}' does not support capability '${cap}'${
86
+ capability?.reason ? `: ${capability.reason}` : ''
87
+ }`
88
+ );
89
+ }
90
+ }
91
+ }
@@ -0,0 +1,32 @@
1
+ import { IElementHandle } from '@open-wa/driver-interface';
2
+ import type { ElementHandle } from 'puppeteer';
3
+
4
+ export class PuppeteerElementHandle implements IElementHandle {
5
+ constructor(private element: ElementHandle) {}
6
+
7
+ async click(): Promise<void> {
8
+ await this.element.click();
9
+ }
10
+
11
+ async type(text: string): Promise<void> {
12
+ await this.element.type(text);
13
+ }
14
+
15
+ async getAttribute(name: string): Promise<string | null> {
16
+ const value = await this.element.evaluate((el, attr) => el.getAttribute(attr), name);
17
+ return value;
18
+ }
19
+
20
+ async textContent(): Promise<string | null> {
21
+ const text = await this.element.evaluate(el => el.textContent);
22
+ return text;
23
+ }
24
+
25
+ async dispose(): Promise<void> {
26
+ await this.element.dispose();
27
+ }
28
+
29
+ unwrap(): ElementHandle {
30
+ return this.element;
31
+ }
32
+ }