browserclaw 0.8.0 → 0.8.2
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.
- package/dist/index.cjs +173 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +124 -2
- package/dist/index.d.ts +124 -2
- package/dist/index.js +173 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BrowserContext, Page, CDPSession } from 'playwright-core';
|
|
1
|
+
import { BrowserContext, Page, Locator, CDPSession } from 'playwright-core';
|
|
2
2
|
import { lookup } from 'node:dns';
|
|
3
3
|
import { lookup as lookup$1 } from 'node:dns/promises';
|
|
4
4
|
|
|
@@ -517,6 +517,21 @@ interface DialogOptions {
|
|
|
517
517
|
/** Timeout for waiting for the dialog. Default: `30000` */
|
|
518
518
|
timeoutMs?: number;
|
|
519
519
|
}
|
|
520
|
+
/** Information about a dialog event passed to `onDialog` handlers. */
|
|
521
|
+
interface DialogEvent {
|
|
522
|
+
/** Dialog type: `'alert'`, `'confirm'`, `'prompt'`, or `'beforeunload'` */
|
|
523
|
+
type: string;
|
|
524
|
+
/** The message displayed in the dialog */
|
|
525
|
+
message: string;
|
|
526
|
+
/** The default prompt value (for prompt dialogs) */
|
|
527
|
+
defaultValue: string;
|
|
528
|
+
/** Accept the dialog (optionally with prompt text) */
|
|
529
|
+
accept: (promptText?: string) => Promise<void>;
|
|
530
|
+
/** Dismiss the dialog */
|
|
531
|
+
dismiss: () => Promise<void>;
|
|
532
|
+
}
|
|
533
|
+
/** Callback for persistent dialog handling. */
|
|
534
|
+
type DialogHandler = (event: DialogEvent) => void | Promise<void>;
|
|
520
535
|
/** Result of intercepting a response body. */
|
|
521
536
|
interface ResponseBodyResult {
|
|
522
537
|
/** The response URL */
|
|
@@ -666,6 +681,21 @@ declare class CrawlPage {
|
|
|
666
681
|
* ```
|
|
667
682
|
*/
|
|
668
683
|
click(ref: string, opts?: ClickOptions): Promise<void>;
|
|
684
|
+
/**
|
|
685
|
+
* Click an element by CSS selector (no snapshot/ref needed).
|
|
686
|
+
*
|
|
687
|
+
* Finds and clicks atomically — no stale ref problem.
|
|
688
|
+
*
|
|
689
|
+
* @param selector - CSS selector (e.g. `'#submit-btn'`, `'.modal button'`)
|
|
690
|
+
* @param opts - Click options (double-click, button, modifiers)
|
|
691
|
+
*
|
|
692
|
+
* @example
|
|
693
|
+
* ```ts
|
|
694
|
+
* await page.clickBySelector('#submit-btn');
|
|
695
|
+
* await page.clickBySelector('.modal .close', { button: 'right' });
|
|
696
|
+
* ```
|
|
697
|
+
*/
|
|
698
|
+
clickBySelector(selector: string, opts?: ClickOptions): Promise<void>;
|
|
669
699
|
/**
|
|
670
700
|
* Click at specific page coordinates.
|
|
671
701
|
*
|
|
@@ -832,6 +862,42 @@ declare class CrawlPage {
|
|
|
832
862
|
* ```
|
|
833
863
|
*/
|
|
834
864
|
armDialog(opts: DialogOptions): Promise<void>;
|
|
865
|
+
/**
|
|
866
|
+
* Register a persistent dialog handler for all dialogs (alert, confirm, prompt, beforeunload).
|
|
867
|
+
*
|
|
868
|
+
* Unlike `armDialog()` which handles a single expected dialog, `onDialog()` handles
|
|
869
|
+
* every dialog that appears until cleared. This prevents unexpected dialogs from
|
|
870
|
+
* blocking the page.
|
|
871
|
+
*
|
|
872
|
+
* The handler receives a `DialogEvent` with `accept()` and `dismiss()` methods.
|
|
873
|
+
* If the handler throws or doesn't call either, the dialog is auto-dismissed.
|
|
874
|
+
*
|
|
875
|
+
* Pass `undefined` or `null` to clear the handler and restore default auto-dismiss.
|
|
876
|
+
*
|
|
877
|
+
* Note: `armDialog()` takes priority — if a one-shot handler is armed, it handles
|
|
878
|
+
* the next dialog instead of the persistent handler.
|
|
879
|
+
*
|
|
880
|
+
* @param handler - Callback for dialog events, or `undefined`/`null` to clear
|
|
881
|
+
*
|
|
882
|
+
* @example
|
|
883
|
+
* ```ts
|
|
884
|
+
* // Accept all confirm dialogs, dismiss everything else
|
|
885
|
+
* page.onDialog((event) => {
|
|
886
|
+
* if (event.type === 'confirm') event.accept();
|
|
887
|
+
* else event.dismiss();
|
|
888
|
+
* });
|
|
889
|
+
*
|
|
890
|
+
* // Log and auto-accept all dialogs
|
|
891
|
+
* page.onDialog(async (event) => {
|
|
892
|
+
* console.log(`Dialog: ${event.type} — ${event.message}`);
|
|
893
|
+
* await event.accept();
|
|
894
|
+
* });
|
|
895
|
+
*
|
|
896
|
+
* // Clear the handler (restore default auto-dismiss)
|
|
897
|
+
* page.onDialog(undefined);
|
|
898
|
+
* ```
|
|
899
|
+
*/
|
|
900
|
+
onDialog(handler: DialogHandler | undefined | null): Promise<void>;
|
|
835
901
|
/**
|
|
836
902
|
* Arm a one-shot file chooser handler.
|
|
837
903
|
*
|
|
@@ -1302,6 +1368,52 @@ declare class CrawlPage {
|
|
|
1302
1368
|
timeoutMs?: number;
|
|
1303
1369
|
pollMs?: number;
|
|
1304
1370
|
}): Promise<ChallengeWaitResult>;
|
|
1371
|
+
/**
|
|
1372
|
+
* Get the underlying Playwright `Page` object for this tab.
|
|
1373
|
+
*
|
|
1374
|
+
* Use this when browserclaw's API doesn't cover your use case and you need
|
|
1375
|
+
* direct access to Playwright's full API (custom locator strategies,
|
|
1376
|
+
* frame manipulation, request interception, etc.).
|
|
1377
|
+
*
|
|
1378
|
+
* **Warning:** Modifications made via the raw Playwright page may conflict
|
|
1379
|
+
* with browserclaw's internal state (e.g. ref tracking). Use with care.
|
|
1380
|
+
*
|
|
1381
|
+
* @returns The Playwright `Page` instance
|
|
1382
|
+
*
|
|
1383
|
+
* @example
|
|
1384
|
+
* ```ts
|
|
1385
|
+
* const pwPage = await page.playwrightPage();
|
|
1386
|
+
*
|
|
1387
|
+
* // Use Playwright's full API directly
|
|
1388
|
+
* await pwPage.locator('.my-component').waitFor({ state: 'visible' });
|
|
1389
|
+
* await pwPage.route('**\/api/**', route => route.fulfill({ body: '{}' }));
|
|
1390
|
+
*
|
|
1391
|
+
* // Access frames
|
|
1392
|
+
* const frame = pwPage.frameLocator('#my-iframe');
|
|
1393
|
+
* ```
|
|
1394
|
+
*/
|
|
1395
|
+
playwrightPage(): Promise<Page>;
|
|
1396
|
+
/**
|
|
1397
|
+
* Create a Playwright `Locator` for a CSS selector on this page.
|
|
1398
|
+
*
|
|
1399
|
+
* Convenience method that returns a Playwright locator without needing
|
|
1400
|
+
* to first obtain the Page object. Useful for one-off Playwright operations.
|
|
1401
|
+
*
|
|
1402
|
+
* @param selector - CSS selector or Playwright selector string
|
|
1403
|
+
* @returns A Playwright `Locator` instance
|
|
1404
|
+
*
|
|
1405
|
+
* @example
|
|
1406
|
+
* ```ts
|
|
1407
|
+
* const loc = await page.locator('.modal-dialog button.confirm');
|
|
1408
|
+
* await loc.waitFor({ state: 'visible' });
|
|
1409
|
+
* await loc.click();
|
|
1410
|
+
*
|
|
1411
|
+
* // Use Playwright selectors
|
|
1412
|
+
* const input = await page.locator('input[name="email"]');
|
|
1413
|
+
* await input.fill('test@example.com');
|
|
1414
|
+
* ```
|
|
1415
|
+
*/
|
|
1416
|
+
locator(selector: string): Promise<Locator>;
|
|
1305
1417
|
}
|
|
1306
1418
|
/**
|
|
1307
1419
|
* Main entry point for browserclaw.
|
|
@@ -1548,6 +1660,16 @@ declare function withPageScopedCdpClient<T>(opts: {
|
|
|
1548
1660
|
fn: (send: (method: string, params?: Record<string, unknown>) => Promise<unknown>) => Promise<T>;
|
|
1549
1661
|
}): Promise<T>;
|
|
1550
1662
|
declare function ensureContextState(context: BrowserContext): ContextState;
|
|
1663
|
+
/**
|
|
1664
|
+
* Set or clear a persistent dialog handler for a page.
|
|
1665
|
+
* When set, this handler is called for every dialog that is not covered by armDialog().
|
|
1666
|
+
* Pass `undefined` to clear the handler and restore default auto-dismiss.
|
|
1667
|
+
*/
|
|
1668
|
+
declare function setDialogHandler(opts: {
|
|
1669
|
+
cdpUrl: string;
|
|
1670
|
+
targetId?: string;
|
|
1671
|
+
handler?: DialogHandler;
|
|
1672
|
+
}): Promise<void>;
|
|
1551
1673
|
/**
|
|
1552
1674
|
* Force-disconnect a Playwright browser connection for a given CDP target.
|
|
1553
1675
|
* Clears the connection cache, sends Runtime.terminateExecution via raw CDP
|
|
@@ -1633,4 +1755,4 @@ declare function waitForChallengeViaPlaywright(opts: {
|
|
|
1633
1755
|
pollMs?: number;
|
|
1634
1756
|
}): Promise<ChallengeWaitResult>;
|
|
1635
1757
|
|
|
1636
|
-
export { type AriaNode, type AriaSnapshotResult, type BatchAction, type BatchActionResult, BrowserClaw, type BrowserNavigationPolicyOptions, type BrowserNavigationRequestLike, type BrowserTab, BrowserTabNotFoundError, type ChallengeInfo, type ChallengeKind, type ChallengeWaitResult, type ChromeExecutable, type ChromeKind, type ClickOptions, type ColorScheme, type ConnectOptions, type ConsoleMessage, type ContextState, type CookieData, CrawlPage, type DialogOptions, type DownloadResult, type FormField, type FrameEvalResult, type GeolocationOptions, type HttpCredentials, InvalidBrowserNavigationUrlError, type LaunchOptions, type LookupFn, type NetworkRequest, type PageError, type PinnedHostname, type ResponseBodyResult, type RoleRefInfo, type RoleRefs, STEALTH_SCRIPT, type ScreenshotOptions, type SnapshotOptions, type SnapshotResult, type SnapshotStats, type SsrfPolicy, type StorageKind, type TraceStartOptions, type TypeOptions, type UntrustedContentMeta, type WaitOptions, assertBrowserNavigationAllowed, assertBrowserNavigationRedirectChainAllowed, assertBrowserNavigationResultAllowed, assertSafeUploadPaths, batchViaPlaywright, createPinnedLookup, detectChallengeViaPlaywright, ensureContextState, executeSingleAction, forceDisconnectPlaywrightForTarget, getChromeWebSocketUrl, getRestoredPageForTarget, isChromeCdpReady, isChromeReachable, normalizeCdpHttpBaseForJsonEndpoints, parseRoleRef, requireRef, requireRefOrSelector, requiresInspectableBrowserNavigationRedirects, resolveBoundedDelayMs, resolveInteractionTimeoutMs, resolvePageByTargetIdOrThrow, resolvePinnedHostnameWithPolicy, resolveStrictExistingUploadPaths, sanitizeUntrustedFileName, waitForChallengeViaPlaywright, withBrowserNavigationPolicy, withPageScopedCdpClient, withPlaywrightPageCdpSession, writeViaSiblingTempPath };
|
|
1758
|
+
export { type AriaNode, type AriaSnapshotResult, type BatchAction, type BatchActionResult, BrowserClaw, type BrowserNavigationPolicyOptions, type BrowserNavigationRequestLike, type BrowserTab, BrowserTabNotFoundError, type ChallengeInfo, type ChallengeKind, type ChallengeWaitResult, type ChromeExecutable, type ChromeKind, type ClickOptions, type ColorScheme, type ConnectOptions, type ConsoleMessage, type ContextState, type CookieData, CrawlPage, type DialogEvent, type DialogHandler, type DialogOptions, type DownloadResult, type FormField, type FrameEvalResult, type GeolocationOptions, type HttpCredentials, InvalidBrowserNavigationUrlError, type LaunchOptions, type LookupFn, type NetworkRequest, type PageError, type PinnedHostname, type ResponseBodyResult, type RoleRefInfo, type RoleRefs, STEALTH_SCRIPT, type ScreenshotOptions, type SnapshotOptions, type SnapshotResult, type SnapshotStats, type SsrfPolicy, type StorageKind, type TraceStartOptions, type TypeOptions, type UntrustedContentMeta, type WaitOptions, assertBrowserNavigationAllowed, assertBrowserNavigationRedirectChainAllowed, assertBrowserNavigationResultAllowed, assertSafeUploadPaths, batchViaPlaywright, createPinnedLookup, detectChallengeViaPlaywright, ensureContextState, executeSingleAction, forceDisconnectPlaywrightForTarget, getChromeWebSocketUrl, getRestoredPageForTarget, isChromeCdpReady, isChromeReachable, normalizeCdpHttpBaseForJsonEndpoints, parseRoleRef, requireRef, requireRefOrSelector, requiresInspectableBrowserNavigationRedirects, resolveBoundedDelayMs, resolveInteractionTimeoutMs, resolvePageByTargetIdOrThrow, resolvePinnedHostnameWithPolicy, resolveStrictExistingUploadPaths, sanitizeUntrustedFileName, setDialogHandler, waitForChallengeViaPlaywright, withBrowserNavigationPolicy, withPageScopedCdpClient, withPlaywrightPageCdpSession, writeViaSiblingTempPath };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BrowserContext, Page, CDPSession } from 'playwright-core';
|
|
1
|
+
import { BrowserContext, Page, Locator, CDPSession } from 'playwright-core';
|
|
2
2
|
import { lookup } from 'node:dns';
|
|
3
3
|
import { lookup as lookup$1 } from 'node:dns/promises';
|
|
4
4
|
|
|
@@ -517,6 +517,21 @@ interface DialogOptions {
|
|
|
517
517
|
/** Timeout for waiting for the dialog. Default: `30000` */
|
|
518
518
|
timeoutMs?: number;
|
|
519
519
|
}
|
|
520
|
+
/** Information about a dialog event passed to `onDialog` handlers. */
|
|
521
|
+
interface DialogEvent {
|
|
522
|
+
/** Dialog type: `'alert'`, `'confirm'`, `'prompt'`, or `'beforeunload'` */
|
|
523
|
+
type: string;
|
|
524
|
+
/** The message displayed in the dialog */
|
|
525
|
+
message: string;
|
|
526
|
+
/** The default prompt value (for prompt dialogs) */
|
|
527
|
+
defaultValue: string;
|
|
528
|
+
/** Accept the dialog (optionally with prompt text) */
|
|
529
|
+
accept: (promptText?: string) => Promise<void>;
|
|
530
|
+
/** Dismiss the dialog */
|
|
531
|
+
dismiss: () => Promise<void>;
|
|
532
|
+
}
|
|
533
|
+
/** Callback for persistent dialog handling. */
|
|
534
|
+
type DialogHandler = (event: DialogEvent) => void | Promise<void>;
|
|
520
535
|
/** Result of intercepting a response body. */
|
|
521
536
|
interface ResponseBodyResult {
|
|
522
537
|
/** The response URL */
|
|
@@ -666,6 +681,21 @@ declare class CrawlPage {
|
|
|
666
681
|
* ```
|
|
667
682
|
*/
|
|
668
683
|
click(ref: string, opts?: ClickOptions): Promise<void>;
|
|
684
|
+
/**
|
|
685
|
+
* Click an element by CSS selector (no snapshot/ref needed).
|
|
686
|
+
*
|
|
687
|
+
* Finds and clicks atomically — no stale ref problem.
|
|
688
|
+
*
|
|
689
|
+
* @param selector - CSS selector (e.g. `'#submit-btn'`, `'.modal button'`)
|
|
690
|
+
* @param opts - Click options (double-click, button, modifiers)
|
|
691
|
+
*
|
|
692
|
+
* @example
|
|
693
|
+
* ```ts
|
|
694
|
+
* await page.clickBySelector('#submit-btn');
|
|
695
|
+
* await page.clickBySelector('.modal .close', { button: 'right' });
|
|
696
|
+
* ```
|
|
697
|
+
*/
|
|
698
|
+
clickBySelector(selector: string, opts?: ClickOptions): Promise<void>;
|
|
669
699
|
/**
|
|
670
700
|
* Click at specific page coordinates.
|
|
671
701
|
*
|
|
@@ -832,6 +862,42 @@ declare class CrawlPage {
|
|
|
832
862
|
* ```
|
|
833
863
|
*/
|
|
834
864
|
armDialog(opts: DialogOptions): Promise<void>;
|
|
865
|
+
/**
|
|
866
|
+
* Register a persistent dialog handler for all dialogs (alert, confirm, prompt, beforeunload).
|
|
867
|
+
*
|
|
868
|
+
* Unlike `armDialog()` which handles a single expected dialog, `onDialog()` handles
|
|
869
|
+
* every dialog that appears until cleared. This prevents unexpected dialogs from
|
|
870
|
+
* blocking the page.
|
|
871
|
+
*
|
|
872
|
+
* The handler receives a `DialogEvent` with `accept()` and `dismiss()` methods.
|
|
873
|
+
* If the handler throws or doesn't call either, the dialog is auto-dismissed.
|
|
874
|
+
*
|
|
875
|
+
* Pass `undefined` or `null` to clear the handler and restore default auto-dismiss.
|
|
876
|
+
*
|
|
877
|
+
* Note: `armDialog()` takes priority — if a one-shot handler is armed, it handles
|
|
878
|
+
* the next dialog instead of the persistent handler.
|
|
879
|
+
*
|
|
880
|
+
* @param handler - Callback for dialog events, or `undefined`/`null` to clear
|
|
881
|
+
*
|
|
882
|
+
* @example
|
|
883
|
+
* ```ts
|
|
884
|
+
* // Accept all confirm dialogs, dismiss everything else
|
|
885
|
+
* page.onDialog((event) => {
|
|
886
|
+
* if (event.type === 'confirm') event.accept();
|
|
887
|
+
* else event.dismiss();
|
|
888
|
+
* });
|
|
889
|
+
*
|
|
890
|
+
* // Log and auto-accept all dialogs
|
|
891
|
+
* page.onDialog(async (event) => {
|
|
892
|
+
* console.log(`Dialog: ${event.type} — ${event.message}`);
|
|
893
|
+
* await event.accept();
|
|
894
|
+
* });
|
|
895
|
+
*
|
|
896
|
+
* // Clear the handler (restore default auto-dismiss)
|
|
897
|
+
* page.onDialog(undefined);
|
|
898
|
+
* ```
|
|
899
|
+
*/
|
|
900
|
+
onDialog(handler: DialogHandler | undefined | null): Promise<void>;
|
|
835
901
|
/**
|
|
836
902
|
* Arm a one-shot file chooser handler.
|
|
837
903
|
*
|
|
@@ -1302,6 +1368,52 @@ declare class CrawlPage {
|
|
|
1302
1368
|
timeoutMs?: number;
|
|
1303
1369
|
pollMs?: number;
|
|
1304
1370
|
}): Promise<ChallengeWaitResult>;
|
|
1371
|
+
/**
|
|
1372
|
+
* Get the underlying Playwright `Page` object for this tab.
|
|
1373
|
+
*
|
|
1374
|
+
* Use this when browserclaw's API doesn't cover your use case and you need
|
|
1375
|
+
* direct access to Playwright's full API (custom locator strategies,
|
|
1376
|
+
* frame manipulation, request interception, etc.).
|
|
1377
|
+
*
|
|
1378
|
+
* **Warning:** Modifications made via the raw Playwright page may conflict
|
|
1379
|
+
* with browserclaw's internal state (e.g. ref tracking). Use with care.
|
|
1380
|
+
*
|
|
1381
|
+
* @returns The Playwright `Page` instance
|
|
1382
|
+
*
|
|
1383
|
+
* @example
|
|
1384
|
+
* ```ts
|
|
1385
|
+
* const pwPage = await page.playwrightPage();
|
|
1386
|
+
*
|
|
1387
|
+
* // Use Playwright's full API directly
|
|
1388
|
+
* await pwPage.locator('.my-component').waitFor({ state: 'visible' });
|
|
1389
|
+
* await pwPage.route('**\/api/**', route => route.fulfill({ body: '{}' }));
|
|
1390
|
+
*
|
|
1391
|
+
* // Access frames
|
|
1392
|
+
* const frame = pwPage.frameLocator('#my-iframe');
|
|
1393
|
+
* ```
|
|
1394
|
+
*/
|
|
1395
|
+
playwrightPage(): Promise<Page>;
|
|
1396
|
+
/**
|
|
1397
|
+
* Create a Playwright `Locator` for a CSS selector on this page.
|
|
1398
|
+
*
|
|
1399
|
+
* Convenience method that returns a Playwright locator without needing
|
|
1400
|
+
* to first obtain the Page object. Useful for one-off Playwright operations.
|
|
1401
|
+
*
|
|
1402
|
+
* @param selector - CSS selector or Playwright selector string
|
|
1403
|
+
* @returns A Playwright `Locator` instance
|
|
1404
|
+
*
|
|
1405
|
+
* @example
|
|
1406
|
+
* ```ts
|
|
1407
|
+
* const loc = await page.locator('.modal-dialog button.confirm');
|
|
1408
|
+
* await loc.waitFor({ state: 'visible' });
|
|
1409
|
+
* await loc.click();
|
|
1410
|
+
*
|
|
1411
|
+
* // Use Playwright selectors
|
|
1412
|
+
* const input = await page.locator('input[name="email"]');
|
|
1413
|
+
* await input.fill('test@example.com');
|
|
1414
|
+
* ```
|
|
1415
|
+
*/
|
|
1416
|
+
locator(selector: string): Promise<Locator>;
|
|
1305
1417
|
}
|
|
1306
1418
|
/**
|
|
1307
1419
|
* Main entry point for browserclaw.
|
|
@@ -1548,6 +1660,16 @@ declare function withPageScopedCdpClient<T>(opts: {
|
|
|
1548
1660
|
fn: (send: (method: string, params?: Record<string, unknown>) => Promise<unknown>) => Promise<T>;
|
|
1549
1661
|
}): Promise<T>;
|
|
1550
1662
|
declare function ensureContextState(context: BrowserContext): ContextState;
|
|
1663
|
+
/**
|
|
1664
|
+
* Set or clear a persistent dialog handler for a page.
|
|
1665
|
+
* When set, this handler is called for every dialog that is not covered by armDialog().
|
|
1666
|
+
* Pass `undefined` to clear the handler and restore default auto-dismiss.
|
|
1667
|
+
*/
|
|
1668
|
+
declare function setDialogHandler(opts: {
|
|
1669
|
+
cdpUrl: string;
|
|
1670
|
+
targetId?: string;
|
|
1671
|
+
handler?: DialogHandler;
|
|
1672
|
+
}): Promise<void>;
|
|
1551
1673
|
/**
|
|
1552
1674
|
* Force-disconnect a Playwright browser connection for a given CDP target.
|
|
1553
1675
|
* Clears the connection cache, sends Runtime.terminateExecution via raw CDP
|
|
@@ -1633,4 +1755,4 @@ declare function waitForChallengeViaPlaywright(opts: {
|
|
|
1633
1755
|
pollMs?: number;
|
|
1634
1756
|
}): Promise<ChallengeWaitResult>;
|
|
1635
1757
|
|
|
1636
|
-
export { type AriaNode, type AriaSnapshotResult, type BatchAction, type BatchActionResult, BrowserClaw, type BrowserNavigationPolicyOptions, type BrowserNavigationRequestLike, type BrowserTab, BrowserTabNotFoundError, type ChallengeInfo, type ChallengeKind, type ChallengeWaitResult, type ChromeExecutable, type ChromeKind, type ClickOptions, type ColorScheme, type ConnectOptions, type ConsoleMessage, type ContextState, type CookieData, CrawlPage, type DialogOptions, type DownloadResult, type FormField, type FrameEvalResult, type GeolocationOptions, type HttpCredentials, InvalidBrowserNavigationUrlError, type LaunchOptions, type LookupFn, type NetworkRequest, type PageError, type PinnedHostname, type ResponseBodyResult, type RoleRefInfo, type RoleRefs, STEALTH_SCRIPT, type ScreenshotOptions, type SnapshotOptions, type SnapshotResult, type SnapshotStats, type SsrfPolicy, type StorageKind, type TraceStartOptions, type TypeOptions, type UntrustedContentMeta, type WaitOptions, assertBrowserNavigationAllowed, assertBrowserNavigationRedirectChainAllowed, assertBrowserNavigationResultAllowed, assertSafeUploadPaths, batchViaPlaywright, createPinnedLookup, detectChallengeViaPlaywright, ensureContextState, executeSingleAction, forceDisconnectPlaywrightForTarget, getChromeWebSocketUrl, getRestoredPageForTarget, isChromeCdpReady, isChromeReachable, normalizeCdpHttpBaseForJsonEndpoints, parseRoleRef, requireRef, requireRefOrSelector, requiresInspectableBrowserNavigationRedirects, resolveBoundedDelayMs, resolveInteractionTimeoutMs, resolvePageByTargetIdOrThrow, resolvePinnedHostnameWithPolicy, resolveStrictExistingUploadPaths, sanitizeUntrustedFileName, waitForChallengeViaPlaywright, withBrowserNavigationPolicy, withPageScopedCdpClient, withPlaywrightPageCdpSession, writeViaSiblingTempPath };
|
|
1758
|
+
export { type AriaNode, type AriaSnapshotResult, type BatchAction, type BatchActionResult, BrowserClaw, type BrowserNavigationPolicyOptions, type BrowserNavigationRequestLike, type BrowserTab, BrowserTabNotFoundError, type ChallengeInfo, type ChallengeKind, type ChallengeWaitResult, type ChromeExecutable, type ChromeKind, type ClickOptions, type ColorScheme, type ConnectOptions, type ConsoleMessage, type ContextState, type CookieData, CrawlPage, type DialogEvent, type DialogHandler, type DialogOptions, type DownloadResult, type FormField, type FrameEvalResult, type GeolocationOptions, type HttpCredentials, InvalidBrowserNavigationUrlError, type LaunchOptions, type LookupFn, type NetworkRequest, type PageError, type PinnedHostname, type ResponseBodyResult, type RoleRefInfo, type RoleRefs, STEALTH_SCRIPT, type ScreenshotOptions, type SnapshotOptions, type SnapshotResult, type SnapshotStats, type SsrfPolicy, type StorageKind, type TraceStartOptions, type TypeOptions, type UntrustedContentMeta, type WaitOptions, assertBrowserNavigationAllowed, assertBrowserNavigationRedirectChainAllowed, assertBrowserNavigationResultAllowed, assertSafeUploadPaths, batchViaPlaywright, createPinnedLookup, detectChallengeViaPlaywright, ensureContextState, executeSingleAction, forceDisconnectPlaywrightForTarget, getChromeWebSocketUrl, getRestoredPageForTarget, isChromeCdpReady, isChromeReachable, normalizeCdpHttpBaseForJsonEndpoints, parseRoleRef, requireRef, requireRefOrSelector, requiresInspectableBrowserNavigationRedirects, resolveBoundedDelayMs, resolveInteractionTimeoutMs, resolvePageByTargetIdOrThrow, resolvePinnedHostnameWithPolicy, resolveStrictExistingUploadPaths, sanitizeUntrustedFileName, setDialogHandler, waitForChallengeViaPlaywright, withBrowserNavigationPolicy, withPageScopedCdpClient, withPlaywrightPageCdpSession, writeViaSiblingTempPath };
|
package/dist/index.js
CHANGED
|
@@ -1918,6 +1918,41 @@ function ensurePageState(page) {
|
|
|
1918
1918
|
});
|
|
1919
1919
|
page.on("dialog", (dialog) => {
|
|
1920
1920
|
if (state.armIdDialog > 0) return;
|
|
1921
|
+
if (state.dialogHandler) {
|
|
1922
|
+
let handled = false;
|
|
1923
|
+
const event = {
|
|
1924
|
+
type: dialog.type(),
|
|
1925
|
+
message: dialog.message(),
|
|
1926
|
+
defaultValue: dialog.defaultValue(),
|
|
1927
|
+
accept: (promptText) => {
|
|
1928
|
+
handled = true;
|
|
1929
|
+
return dialog.accept(promptText);
|
|
1930
|
+
},
|
|
1931
|
+
dismiss: () => {
|
|
1932
|
+
handled = true;
|
|
1933
|
+
return dialog.dismiss();
|
|
1934
|
+
}
|
|
1935
|
+
};
|
|
1936
|
+
Promise.resolve(state.dialogHandler(event)).then(() => {
|
|
1937
|
+
if (!handled) {
|
|
1938
|
+
dialog.dismiss().catch((err) => {
|
|
1939
|
+
console.warn(
|
|
1940
|
+
`[browserclaw] Failed to auto-dismiss dialog: ${err instanceof Error ? err.message : String(err)}`
|
|
1941
|
+
);
|
|
1942
|
+
});
|
|
1943
|
+
}
|
|
1944
|
+
}).catch((err) => {
|
|
1945
|
+
console.warn(`[browserclaw] onDialog handler error: ${err instanceof Error ? err.message : String(err)}`);
|
|
1946
|
+
if (!handled) {
|
|
1947
|
+
dialog.dismiss().catch((dismissErr) => {
|
|
1948
|
+
console.warn(
|
|
1949
|
+
`[browserclaw] Failed to dismiss dialog after handler error: ${dismissErr instanceof Error ? dismissErr.message : String(dismissErr)}`
|
|
1950
|
+
);
|
|
1951
|
+
});
|
|
1952
|
+
}
|
|
1953
|
+
});
|
|
1954
|
+
return;
|
|
1955
|
+
}
|
|
1921
1956
|
dialog.dismiss().catch((err) => {
|
|
1922
1957
|
console.warn(`[browserclaw] Failed to dismiss dialog: ${err instanceof Error ? err.message : String(err)}`);
|
|
1923
1958
|
});
|
|
@@ -1929,6 +1964,11 @@ function ensurePageState(page) {
|
|
|
1929
1964
|
}
|
|
1930
1965
|
return state;
|
|
1931
1966
|
}
|
|
1967
|
+
async function setDialogHandler(opts) {
|
|
1968
|
+
const page = await getPageForTargetId({ cdpUrl: opts.cdpUrl, targetId: opts.targetId });
|
|
1969
|
+
const state = ensurePageState(page);
|
|
1970
|
+
state.dialogHandler = opts.handler;
|
|
1971
|
+
}
|
|
1932
1972
|
function applyStealthToPage(page) {
|
|
1933
1973
|
page.evaluate(STEALTH_SCRIPT).catch((e) => {
|
|
1934
1974
|
if (process.env.DEBUG !== void 0 && process.env.DEBUG !== "")
|
|
@@ -2532,7 +2572,17 @@ var BLOCKED_IPV4_RANGES = /* @__PURE__ */ new Set([
|
|
|
2532
2572
|
"private",
|
|
2533
2573
|
"reserved"
|
|
2534
2574
|
]);
|
|
2535
|
-
var BLOCKED_IPV6_RANGES = /* @__PURE__ */ new Set([
|
|
2575
|
+
var BLOCKED_IPV6_RANGES = /* @__PURE__ */ new Set([
|
|
2576
|
+
"unspecified",
|
|
2577
|
+
"loopback",
|
|
2578
|
+
"linkLocal",
|
|
2579
|
+
"uniqueLocal",
|
|
2580
|
+
"multicast",
|
|
2581
|
+
"reserved",
|
|
2582
|
+
"benchmarking",
|
|
2583
|
+
"discard",
|
|
2584
|
+
"orchid2"
|
|
2585
|
+
]);
|
|
2536
2586
|
var RFC2544_BENCHMARK_PREFIX = [ipaddr.IPv4.parse("198.18.0.0"), 15];
|
|
2537
2587
|
var EMBEDDED_IPV4_SENTINEL_RULES = [
|
|
2538
2588
|
// IPv4-compatible (::a.b.c.d)
|
|
@@ -4196,6 +4246,7 @@ var CONTENT_ROLES = /* @__PURE__ */ new Set([
|
|
|
4196
4246
|
var STRUCTURAL_ROLES = /* @__PURE__ */ new Set([
|
|
4197
4247
|
"generic",
|
|
4198
4248
|
"group",
|
|
4249
|
+
"ignored",
|
|
4199
4250
|
"list",
|
|
4200
4251
|
"table",
|
|
4201
4252
|
"row",
|
|
@@ -4811,6 +4862,32 @@ var CrawlPage = class {
|
|
|
4811
4862
|
timeoutMs: opts?.timeoutMs
|
|
4812
4863
|
});
|
|
4813
4864
|
}
|
|
4865
|
+
/**
|
|
4866
|
+
* Click an element by CSS selector (no snapshot/ref needed).
|
|
4867
|
+
*
|
|
4868
|
+
* Finds and clicks atomically — no stale ref problem.
|
|
4869
|
+
*
|
|
4870
|
+
* @param selector - CSS selector (e.g. `'#submit-btn'`, `'.modal button'`)
|
|
4871
|
+
* @param opts - Click options (double-click, button, modifiers)
|
|
4872
|
+
*
|
|
4873
|
+
* @example
|
|
4874
|
+
* ```ts
|
|
4875
|
+
* await page.clickBySelector('#submit-btn');
|
|
4876
|
+
* await page.clickBySelector('.modal .close', { button: 'right' });
|
|
4877
|
+
* ```
|
|
4878
|
+
*/
|
|
4879
|
+
async clickBySelector(selector, opts) {
|
|
4880
|
+
return clickViaPlaywright({
|
|
4881
|
+
cdpUrl: this.cdpUrl,
|
|
4882
|
+
targetId: this.targetId,
|
|
4883
|
+
selector,
|
|
4884
|
+
doubleClick: opts?.doubleClick,
|
|
4885
|
+
button: opts?.button,
|
|
4886
|
+
modifiers: opts?.modifiers,
|
|
4887
|
+
delayMs: opts?.delayMs,
|
|
4888
|
+
timeoutMs: opts?.timeoutMs
|
|
4889
|
+
});
|
|
4890
|
+
}
|
|
4814
4891
|
/**
|
|
4815
4892
|
* Click at specific page coordinates.
|
|
4816
4893
|
*
|
|
@@ -5054,6 +5131,48 @@ var CrawlPage = class {
|
|
|
5054
5131
|
timeoutMs: opts.timeoutMs
|
|
5055
5132
|
});
|
|
5056
5133
|
}
|
|
5134
|
+
/**
|
|
5135
|
+
* Register a persistent dialog handler for all dialogs (alert, confirm, prompt, beforeunload).
|
|
5136
|
+
*
|
|
5137
|
+
* Unlike `armDialog()` which handles a single expected dialog, `onDialog()` handles
|
|
5138
|
+
* every dialog that appears until cleared. This prevents unexpected dialogs from
|
|
5139
|
+
* blocking the page.
|
|
5140
|
+
*
|
|
5141
|
+
* The handler receives a `DialogEvent` with `accept()` and `dismiss()` methods.
|
|
5142
|
+
* If the handler throws or doesn't call either, the dialog is auto-dismissed.
|
|
5143
|
+
*
|
|
5144
|
+
* Pass `undefined` or `null` to clear the handler and restore default auto-dismiss.
|
|
5145
|
+
*
|
|
5146
|
+
* Note: `armDialog()` takes priority — if a one-shot handler is armed, it handles
|
|
5147
|
+
* the next dialog instead of the persistent handler.
|
|
5148
|
+
*
|
|
5149
|
+
* @param handler - Callback for dialog events, or `undefined`/`null` to clear
|
|
5150
|
+
*
|
|
5151
|
+
* @example
|
|
5152
|
+
* ```ts
|
|
5153
|
+
* // Accept all confirm dialogs, dismiss everything else
|
|
5154
|
+
* page.onDialog((event) => {
|
|
5155
|
+
* if (event.type === 'confirm') event.accept();
|
|
5156
|
+
* else event.dismiss();
|
|
5157
|
+
* });
|
|
5158
|
+
*
|
|
5159
|
+
* // Log and auto-accept all dialogs
|
|
5160
|
+
* page.onDialog(async (event) => {
|
|
5161
|
+
* console.log(`Dialog: ${event.type} — ${event.message}`);
|
|
5162
|
+
* await event.accept();
|
|
5163
|
+
* });
|
|
5164
|
+
*
|
|
5165
|
+
* // Clear the handler (restore default auto-dismiss)
|
|
5166
|
+
* page.onDialog(undefined);
|
|
5167
|
+
* ```
|
|
5168
|
+
*/
|
|
5169
|
+
async onDialog(handler) {
|
|
5170
|
+
return setDialogHandler({
|
|
5171
|
+
cdpUrl: this.cdpUrl,
|
|
5172
|
+
targetId: this.targetId,
|
|
5173
|
+
handler: handler ?? void 0
|
|
5174
|
+
});
|
|
5175
|
+
}
|
|
5057
5176
|
/**
|
|
5058
5177
|
* Arm a one-shot file chooser handler.
|
|
5059
5178
|
*
|
|
@@ -5721,6 +5840,58 @@ var CrawlPage = class {
|
|
|
5721
5840
|
pollMs: opts?.pollMs
|
|
5722
5841
|
});
|
|
5723
5842
|
}
|
|
5843
|
+
// ── Playwright Escape Hatches ─────────────────────────────────
|
|
5844
|
+
/**
|
|
5845
|
+
* Get the underlying Playwright `Page` object for this tab.
|
|
5846
|
+
*
|
|
5847
|
+
* Use this when browserclaw's API doesn't cover your use case and you need
|
|
5848
|
+
* direct access to Playwright's full API (custom locator strategies,
|
|
5849
|
+
* frame manipulation, request interception, etc.).
|
|
5850
|
+
*
|
|
5851
|
+
* **Warning:** Modifications made via the raw Playwright page may conflict
|
|
5852
|
+
* with browserclaw's internal state (e.g. ref tracking). Use with care.
|
|
5853
|
+
*
|
|
5854
|
+
* @returns The Playwright `Page` instance
|
|
5855
|
+
*
|
|
5856
|
+
* @example
|
|
5857
|
+
* ```ts
|
|
5858
|
+
* const pwPage = await page.playwrightPage();
|
|
5859
|
+
*
|
|
5860
|
+
* // Use Playwright's full API directly
|
|
5861
|
+
* await pwPage.locator('.my-component').waitFor({ state: 'visible' });
|
|
5862
|
+
* await pwPage.route('**\/api/**', route => route.fulfill({ body: '{}' }));
|
|
5863
|
+
*
|
|
5864
|
+
* // Access frames
|
|
5865
|
+
* const frame = pwPage.frameLocator('#my-iframe');
|
|
5866
|
+
* ```
|
|
5867
|
+
*/
|
|
5868
|
+
async playwrightPage() {
|
|
5869
|
+
return getRestoredPageForTarget({ cdpUrl: this.cdpUrl, targetId: this.targetId });
|
|
5870
|
+
}
|
|
5871
|
+
/**
|
|
5872
|
+
* Create a Playwright `Locator` for a CSS selector on this page.
|
|
5873
|
+
*
|
|
5874
|
+
* Convenience method that returns a Playwright locator without needing
|
|
5875
|
+
* to first obtain the Page object. Useful for one-off Playwright operations.
|
|
5876
|
+
*
|
|
5877
|
+
* @param selector - CSS selector or Playwright selector string
|
|
5878
|
+
* @returns A Playwright `Locator` instance
|
|
5879
|
+
*
|
|
5880
|
+
* @example
|
|
5881
|
+
* ```ts
|
|
5882
|
+
* const loc = await page.locator('.modal-dialog button.confirm');
|
|
5883
|
+
* await loc.waitFor({ state: 'visible' });
|
|
5884
|
+
* await loc.click();
|
|
5885
|
+
*
|
|
5886
|
+
* // Use Playwright selectors
|
|
5887
|
+
* const input = await page.locator('input[name="email"]');
|
|
5888
|
+
* await input.fill('test@example.com');
|
|
5889
|
+
* ```
|
|
5890
|
+
*/
|
|
5891
|
+
async locator(selector) {
|
|
5892
|
+
const pwPage = await getRestoredPageForTarget({ cdpUrl: this.cdpUrl, targetId: this.targetId });
|
|
5893
|
+
return pwPage.locator(selector);
|
|
5894
|
+
}
|
|
5724
5895
|
};
|
|
5725
5896
|
var BrowserClaw = class _BrowserClaw {
|
|
5726
5897
|
cdpUrl;
|
|
@@ -5884,6 +6055,6 @@ var BrowserClaw = class _BrowserClaw {
|
|
|
5884
6055
|
}
|
|
5885
6056
|
};
|
|
5886
6057
|
|
|
5887
|
-
export { BrowserClaw, BrowserTabNotFoundError, CrawlPage, InvalidBrowserNavigationUrlError, STEALTH_SCRIPT, assertBrowserNavigationAllowed, assertBrowserNavigationRedirectChainAllowed, assertBrowserNavigationResultAllowed, assertSafeUploadPaths, batchViaPlaywright, createPinnedLookup, detectChallengeViaPlaywright, ensureContextState, executeSingleAction, forceDisconnectPlaywrightForTarget, getChromeWebSocketUrl, getRestoredPageForTarget, isChromeCdpReady, isChromeReachable, normalizeCdpHttpBaseForJsonEndpoints, parseRoleRef, requireRef, requireRefOrSelector, requiresInspectableBrowserNavigationRedirects, resolveBoundedDelayMs, resolveInteractionTimeoutMs, resolvePageByTargetIdOrThrow, resolvePinnedHostnameWithPolicy, resolveStrictExistingUploadPaths, sanitizeUntrustedFileName, waitForChallengeViaPlaywright, withBrowserNavigationPolicy, withPageScopedCdpClient, withPlaywrightPageCdpSession, writeViaSiblingTempPath };
|
|
6058
|
+
export { BrowserClaw, BrowserTabNotFoundError, CrawlPage, InvalidBrowserNavigationUrlError, STEALTH_SCRIPT, assertBrowserNavigationAllowed, assertBrowserNavigationRedirectChainAllowed, assertBrowserNavigationResultAllowed, assertSafeUploadPaths, batchViaPlaywright, createPinnedLookup, detectChallengeViaPlaywright, ensureContextState, executeSingleAction, forceDisconnectPlaywrightForTarget, getChromeWebSocketUrl, getRestoredPageForTarget, isChromeCdpReady, isChromeReachable, normalizeCdpHttpBaseForJsonEndpoints, parseRoleRef, requireRef, requireRefOrSelector, requiresInspectableBrowserNavigationRedirects, resolveBoundedDelayMs, resolveInteractionTimeoutMs, resolvePageByTargetIdOrThrow, resolvePinnedHostnameWithPolicy, resolveStrictExistingUploadPaths, sanitizeUntrustedFileName, setDialogHandler, waitForChallengeViaPlaywright, withBrowserNavigationPolicy, withPageScopedCdpClient, withPlaywrightPageCdpSession, writeViaSiblingTempPath };
|
|
5888
6059
|
//# sourceMappingURL=index.js.map
|
|
5889
6060
|
//# sourceMappingURL=index.js.map
|