@humanjs/playwright 0.4.0 → 0.6.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.
- package/README.md +151 -2
- package/dist/index.cjs +605 -206
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +274 -8
- package/dist/index.d.ts +274 -8
- package/dist/index.js +605 -206
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,8 +1,81 @@
|
|
|
1
|
-
import { ReadKind, PersonalityConfig, HumanPlugin,
|
|
1
|
+
import { Point, ReadKind, PersonalityConfig, HumanPlugin, Personality } from '@humanjs/core';
|
|
2
2
|
export { ActionResult, ActionType, BezierPathOptions, ComputeReadingDwellOptions, DwellProfile, HumanAction, HumanPlugin, HumanizePathOptions, Keystroke, KnownActionType, MouseProfile, Personality, PersonalityConfig, PersonalityExtension, PlanTypingOptions, PluginContext, Point, PresetName, ReadKind, ReadingProfile, Rng, ScrollProfile, ScrollSegment, TypingProfile, applyMicroJitter, applyVelocityProfile, bezierPath, blend, careful, computeReadingDwellMs, countWords, createRng, distracted, fast, humanizePath, planScroll, planTypeKeystrokes, precise, resolvePersonality, sleep } from '@humanjs/core';
|
|
3
3
|
import { Locator, BrowserContext, Page } from 'playwright';
|
|
4
4
|
export { Browser, BrowserContext, BrowserContextOptions, ElementHandle, LaunchOptions, Locator, Page, chromium, firefox, webkit } from 'playwright';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Modifier tokens accepted in a `human.press()` chord. `Mod` and `CmdOrCtrl` /
|
|
8
|
+
* `CommandOrControl` are the magic auto-mapping tokens (Meta on Mac,
|
|
9
|
+
* Control elsewhere). The rest are literal — they always resolve to the
|
|
10
|
+
* keycode they name, on every platform.
|
|
11
|
+
*
|
|
12
|
+
* Canonical-case names are listed here for IntelliSense; the runtime
|
|
13
|
+
* parser is case-insensitive, so `'cmd+s'` and `'CMD+S'` work too — they
|
|
14
|
+
* just won't autocomplete.
|
|
15
|
+
*/
|
|
16
|
+
type KeyModifier = 'Mod' | 'CmdOrCtrl' | 'CommandOrControl' | 'Cmd' | 'Command' | 'Meta' | 'Win' | 'Super' | 'Ctrl' | 'Control' | 'Alt' | 'Option' | 'Opt' | 'Shift';
|
|
17
|
+
/**
|
|
18
|
+
* The canonical key names that autocomplete in a `KeyOrChord`. Mirrors
|
|
19
|
+
* Playwright's accepted key vocabulary, plus a few common synonyms.
|
|
20
|
+
* CamelCase names (`ArrowDown`, `PageUp`) are listed in their canonical
|
|
21
|
+
* form — `normalizeKey` preserves case from the input, so what you type is
|
|
22
|
+
* what gets dispatched.
|
|
23
|
+
*
|
|
24
|
+
* Not exhaustive: every other Playwright key (less-common Numpad keys,
|
|
25
|
+
* `BracketLeft`, locale-specific keys, etc.) is outside the typed union
|
|
26
|
+
* and needs a cast at the call site (`'BracketLeft' as KeyOrChord`). The
|
|
27
|
+
* runtime parser handles them — the type just doesn't enumerate them,
|
|
28
|
+
* because adding a `(string & {})` escape hatch would collapse TypeScript's
|
|
29
|
+
* template-literal IntelliSense for the chord autocompletes.
|
|
30
|
+
*/
|
|
31
|
+
type KeyName = 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'F1' | 'F2' | 'F3' | 'F4' | 'F5' | 'F6' | 'F7' | 'F8' | 'F9' | 'F10' | 'F11' | 'F12' | 'ArrowUp' | 'ArrowDown' | 'ArrowLeft' | 'ArrowRight' | 'PageUp' | 'PageDown' | 'Home' | 'End' | 'Enter' | 'Tab' | 'Escape' | 'Space' | 'Backspace' | 'Delete' | 'Insert' | 'CapsLock' | 'NumLock' | 'ScrollLock' | 'PrintScreen' | 'Pause';
|
|
32
|
+
/**
|
|
33
|
+
* Strings accepted by `human.press(key)`:
|
|
34
|
+
*
|
|
35
|
+
* - A bare known key: `'Enter'`, `'F4'`, `'ArrowDown'`, `'S'`, …
|
|
36
|
+
* - One known modifier + a known key: `'Mod+S'`, `'Shift+ArrowDown'`, …
|
|
37
|
+
* - Two known modifiers + a known key: `'Mod+Shift+P'`, `'Ctrl+Alt+Tab'`, …
|
|
38
|
+
*
|
|
39
|
+
* Every member of the union is a fully-enumerated literal, which is what
|
|
40
|
+
* makes IDE autocomplete work — type `'Shift+'` and you get every
|
|
41
|
+
* `Shift+<key>` combination as a completion. Adding a `(string & {})`
|
|
42
|
+
* escape hatch anywhere would collapse that down to a single wide
|
|
43
|
+
* template member, killing the completion list.
|
|
44
|
+
*
|
|
45
|
+
* Modifier typos (`'Mosd+S'`) and uncommon-key typos (`'Mod+BraketLeft'`)
|
|
46
|
+
* are both TS errors at the call site — the closed sets on both sides
|
|
47
|
+
* give you compile-time protection that Playwright's plain `string` key
|
|
48
|
+
* type can't.
|
|
49
|
+
*
|
|
50
|
+
* **Escape hatch for uncommon keys.** Less-common Playwright keys
|
|
51
|
+
* (`'BracketLeft'`, `'NumpadAdd'`, locale-specific keys, …) and 3+
|
|
52
|
+
* modifier chords (`'Ctrl+Shift+Alt+K'`) aren't in the union and need a
|
|
53
|
+
* cast at the call site:
|
|
54
|
+
*
|
|
55
|
+
* ```ts
|
|
56
|
+
* await human.press('Mod+BracketLeft' as KeyOrChord);
|
|
57
|
+
* await human.press('Ctrl+Shift+Alt+K' as KeyOrChord);
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* The runtime parser handles these fine — the cast just acknowledges
|
|
61
|
+
* "I'm using a key outside the autocomplete vocabulary." If you find
|
|
62
|
+
* yourself casting often for a specific key, propose adding it to
|
|
63
|
+
* `KeyName` in a PR.
|
|
64
|
+
*
|
|
65
|
+
* Lowercase modifiers (`'mod+s'`) also don't typecheck even though the
|
|
66
|
+
* runtime accepts them — TS-strict steers users toward the canonical
|
|
67
|
+
* casing, which keeps key strings consistent across a codebase.
|
|
68
|
+
*/
|
|
69
|
+
type KeyOrChord = KeyName | `${KeyModifier}+${KeyName}` | `${KeyModifier}+${KeyModifier}+${KeyName}`;
|
|
70
|
+
/** Result of a `press` action. */
|
|
71
|
+
interface PressResult {
|
|
72
|
+
/** The exact chord that was dispatched (after Mod-resolution). */
|
|
73
|
+
readonly dispatched: string;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Anything that can resolve to a click/move point. */
|
|
77
|
+
type MouseTarget = Locator | string | Point;
|
|
78
|
+
|
|
6
79
|
/**
|
|
7
80
|
* What to read:
|
|
8
81
|
* - `string`: a Playwright-compatible selector (matches `click()` / `type()`).
|
|
@@ -385,14 +458,69 @@ interface Human {
|
|
|
385
458
|
/**
|
|
386
459
|
* Move the mouse along a humanized Bezier path to `target` and click.
|
|
387
460
|
*
|
|
388
|
-
* `target` accepts
|
|
389
|
-
* `'button:has-text("Buy now")'`)
|
|
390
|
-
*
|
|
461
|
+
* `target` accepts a Playwright-compatible selector string (e.g.
|
|
462
|
+
* `'button:has-text("Buy now")'`), a built `Locator`, or a raw `Point`.
|
|
463
|
+
* For element targets the click point is Gaussian-distributed around the
|
|
464
|
+
* center; for a raw `Point` the exact coordinates are clicked. The
|
|
465
|
+
* `Point` form is the fallback for things with no clean selector —
|
|
466
|
+
* icon-only buttons, canvas, SVG — where you can see the pixel position
|
|
467
|
+
* but can't address the element.
|
|
468
|
+
*
|
|
469
|
+
* In `speed: 'instant'`, all humanization is skipped: element targets use
|
|
470
|
+
* Playwright's native `locator.click()`; a `Point` dispatches one
|
|
471
|
+
* `mouse.click()` at the coordinates.
|
|
472
|
+
*/
|
|
473
|
+
click(target: MouseTarget): Promise<void>;
|
|
474
|
+
/**
|
|
475
|
+
* Right-click `target` — opens a native context menu. Same Bezier-path
|
|
476
|
+
* motion and hover dwell as `click()`; only the dispatched button differs.
|
|
477
|
+
* Accepts the same selector / `Locator` / `Point` targets as `click()`.
|
|
478
|
+
*
|
|
479
|
+
* In `speed: 'instant'`, element targets fall back to
|
|
480
|
+
* `locator.click({ button: 'right' })`; a `Point` dispatches one
|
|
481
|
+
* `mouse.click({ button: 'right' })` at the coordinates.
|
|
482
|
+
*/
|
|
483
|
+
rightClick(target: MouseTarget): Promise<void>;
|
|
484
|
+
/**
|
|
485
|
+
* Move the cursor to `target` along a humanized Bezier path and settle
|
|
486
|
+
* on it — no click is dispatched. Useful for hover-triggered UI
|
|
487
|
+
* (tooltips, dropdowns), for positioning the cursor before a non-target
|
|
488
|
+
* action, or for visible demos where the cursor should pause on
|
|
489
|
+
* something noteworthy.
|
|
490
|
+
*
|
|
491
|
+
* In `speed: 'instant'`, dispatches one `mouse.move()` to the element's
|
|
492
|
+
* center.
|
|
493
|
+
*/
|
|
494
|
+
hover(target: Locator | string): Promise<void>;
|
|
495
|
+
/**
|
|
496
|
+
* Move the cursor to `target` along a humanized Bezier path. Pure
|
|
497
|
+
* positioning — no settle dwell, no element interaction. `target` accepts
|
|
498
|
+
* a CSS selector, a `Locator`, or a literal `Point`; the `Point` form
|
|
499
|
+
* lets you position the cursor anywhere (canvas, SVG, dead space) without
|
|
500
|
+
* a DOM element to anchor on.
|
|
501
|
+
*
|
|
502
|
+
* Distinct from `hover()`: `hover` is element-bound and includes a settle
|
|
503
|
+
* dwell to let hover-state UI fire (tooltips, dropdowns). `move` is
|
|
504
|
+
* positional only — use it when you want the cursor placed somewhere
|
|
505
|
+
* without implying interaction with what's under it (pre-press
|
|
506
|
+
* placement, canvas painting, cinematic beats).
|
|
507
|
+
*
|
|
508
|
+
* In `speed: 'instant'`, dispatches one `mouse.move()` at the resolved
|
|
509
|
+
* coordinates.
|
|
510
|
+
*/
|
|
511
|
+
move(target: MouseTarget): Promise<void>;
|
|
512
|
+
/**
|
|
513
|
+
* Drag from `from` to `to`. Each endpoint accepts a CSS selector, a
|
|
514
|
+
* `Locator`, or a literal `Point` — the last form matters for canvas /
|
|
515
|
+
* SVG / slider drags where the destination isn't a DOM element.
|
|
516
|
+
*
|
|
517
|
+
* The motion is two humanized paths back-to-back: cursor → source,
|
|
518
|
+
* then source → destination with the left button held throughout.
|
|
391
519
|
*
|
|
392
|
-
* In `speed: 'instant'`,
|
|
393
|
-
*
|
|
520
|
+
* In `speed: 'instant'`, dispatches `mouse.down → move → up` at the
|
|
521
|
+
* resolved coordinates without humanized motion.
|
|
394
522
|
*/
|
|
395
|
-
|
|
523
|
+
drag(from: MouseTarget, to: MouseTarget): Promise<void>;
|
|
396
524
|
/**
|
|
397
525
|
* Type `value` into `target` with humanized per-key timing, optional typo
|
|
398
526
|
* injection (with backspace recovery), and occasional think-pauses.
|
|
@@ -404,6 +532,48 @@ interface Human {
|
|
|
404
532
|
* zero inter-key delay — events still fire, but humanization is skipped.
|
|
405
533
|
*/
|
|
406
534
|
type(target: Locator | string, value: string): Promise<void>;
|
|
535
|
+
/**
|
|
536
|
+
* Insert `value` into `target` in one shot — the Cmd-V semantic. No
|
|
537
|
+
* per-character timing. Like `type()`, drives an implicit click to focus
|
|
538
|
+
* the field first; unlike `type()`, dispatches the whole value via
|
|
539
|
+
* `keyboard.insertText` rather than per-key presses.
|
|
540
|
+
*
|
|
541
|
+
* Use this for long strings (code blocks, multi-line content, secrets)
|
|
542
|
+
* where the typing simulation would be slow and unnecessary. If you need
|
|
543
|
+
* the page's `paste` event handler to fire, call `human.press('Mod+V')`
|
|
544
|
+
* after setting clipboard contents yourself.
|
|
545
|
+
*
|
|
546
|
+
* In `speed: 'instant'`, behaves identically — paste is already instant
|
|
547
|
+
* by nature.
|
|
548
|
+
*/
|
|
549
|
+
paste(target: Locator | string, value: string): Promise<void>;
|
|
550
|
+
/**
|
|
551
|
+
* Press a single key (`'Tab'`, `'Enter'`, `'Escape'`, `'ArrowDown'`, …)
|
|
552
|
+
* or a keyboard chord (`'Mod+S'`, `'Cmd+Shift+P'`, `'Ctrl+C'`, …).
|
|
553
|
+
*
|
|
554
|
+
* Modifier rules:
|
|
555
|
+
*
|
|
556
|
+
* - `Mod` / `CmdOrCtrl` / `CommandOrControl` — magic: `Meta` on Mac,
|
|
557
|
+
* `Control` elsewhere. Use for cross-platform app shortcuts. The three
|
|
558
|
+
* are aliases; `Mod` is shortest.
|
|
559
|
+
* - `Cmd`, `Command`, `Meta`, `Win`, `Super` — literal `Meta` keycode
|
|
560
|
+
* (Command on Mac, Windows key on Windows, Super on Linux).
|
|
561
|
+
* - `Ctrl`, `Control` — literal Control. Stays Control on every OS.
|
|
562
|
+
* - `Alt`, `Option`, `Opt` — literal Alt.
|
|
563
|
+
* - `Shift` — literal Shift.
|
|
564
|
+
*
|
|
565
|
+
* Case-insensitive. Throws on unknown modifiers. The `KeyOrChord` type
|
|
566
|
+
* is a template-literal union of every modifier × key combination (up to
|
|
567
|
+
* two literal modifiers + a key), so IDEs autocomplete common bare keys
|
|
568
|
+
* and chords as you type. Less common keys (`BracketLeft`, `NumpadAdd`,
|
|
569
|
+
* locale-specific keys) still typecheck through the union's string
|
|
570
|
+
* escape hatch — they just don't autocomplete.
|
|
571
|
+
*
|
|
572
|
+
* Does **not** move the cursor — keyboard input dispatches against
|
|
573
|
+
* focus, not cursor position. Compose with `click` / `hover` / `move`
|
|
574
|
+
* when you need both.
|
|
575
|
+
*/
|
|
576
|
+
press(key: KeyOrChord): Promise<void>;
|
|
407
577
|
/**
|
|
408
578
|
* Dwell as if reading `target` — the third pillar of humanization after
|
|
409
579
|
* the cursor and the keyboard. Real users pause to read; HumanJS models
|
|
@@ -508,6 +678,102 @@ interface Human {
|
|
|
508
678
|
*/
|
|
509
679
|
record(fn: () => Promise<void>): Promise<Recording>;
|
|
510
680
|
record(options: HumanRecordOptions, fn: () => Promise<void>): Promise<Recording>;
|
|
681
|
+
/**
|
|
682
|
+
* Take a screenshot of the page. Forwards to `page.screenshot(options)`
|
|
683
|
+
* unchanged — see Playwright docs for the full options shape.
|
|
684
|
+
*
|
|
685
|
+
* Not a humanized action: no plugin events fire. Pure ergonomic
|
|
686
|
+
* re-export so `human.*` stays a single surface.
|
|
687
|
+
*/
|
|
688
|
+
screenshot(options?: Parameters<Page['screenshot']>[0]): Promise<Buffer>;
|
|
689
|
+
/**
|
|
690
|
+
* Visible text content of the page (`document.body.innerText`). Forwards
|
|
691
|
+
* to `page.innerText('body')`. Useful for AI agents that need to
|
|
692
|
+
* understand what's on screen without parsing HTML.
|
|
693
|
+
*
|
|
694
|
+
* For a region instead of the whole page, use `page.innerText(selector)`.
|
|
695
|
+
*
|
|
696
|
+
* Not a humanized action: no plugin events fire.
|
|
697
|
+
*/
|
|
698
|
+
pageText(): Promise<string>;
|
|
699
|
+
/**
|
|
700
|
+
* Full HTML of the page. Forwards to `page.content()`. Often large
|
|
701
|
+
* (50–500 KB on typical sites) — prefer {@link Human.pageText} when
|
|
702
|
+
* passing to an LLM unless structure matters.
|
|
703
|
+
*
|
|
704
|
+
* Not a humanized action: no plugin events fire.
|
|
705
|
+
*/
|
|
706
|
+
content(): Promise<string>;
|
|
707
|
+
/**
|
|
708
|
+
* Current URL of the page. Forwards to `page.url()`. Synchronous return
|
|
709
|
+
* because Playwright's underlying API is sync.
|
|
710
|
+
*
|
|
711
|
+
* Not a humanized action: no plugin events fire.
|
|
712
|
+
*/
|
|
713
|
+
url(): string;
|
|
714
|
+
/**
|
|
715
|
+
* Current document title. Forwards to `page.title()`.
|
|
716
|
+
*
|
|
717
|
+
* Not a humanized action: no plugin events fire.
|
|
718
|
+
*/
|
|
719
|
+
title(): Promise<string>;
|
|
720
|
+
/**
|
|
721
|
+
* Reload the current page. Forwards to `page.reload(options)`. Real-user
|
|
722
|
+
* analog of hitting the refresh button — the click motion is *not*
|
|
723
|
+
* humanized (we treat reload as navigation, not a cursor action).
|
|
724
|
+
*
|
|
725
|
+
* Plugins observe a `'reload'` action.
|
|
726
|
+
*/
|
|
727
|
+
reload(options?: Parameters<Page['reload']>[0]): Promise<void>;
|
|
728
|
+
/**
|
|
729
|
+
* Navigate back in the browser history. Forwards to `page.goBack(options)`.
|
|
730
|
+
*
|
|
731
|
+
* Plugins observe a `'goBack'` action.
|
|
732
|
+
*/
|
|
733
|
+
goBack(options?: Parameters<Page['goBack']>[0]): Promise<void>;
|
|
734
|
+
/**
|
|
735
|
+
* Navigate forward in the browser history. Forwards to
|
|
736
|
+
* `page.goForward(options)`.
|
|
737
|
+
*
|
|
738
|
+
* Plugins observe a `'goForward'` action.
|
|
739
|
+
*/
|
|
740
|
+
goForward(options?: Parameters<Page['goForward']>[0]): Promise<void>;
|
|
741
|
+
/**
|
|
742
|
+
* Wait until the page reaches the specified load state. Forwards to
|
|
743
|
+
* `page.waitForLoadState(state, options)`. Common after a humanized
|
|
744
|
+
* click that triggers navigation — gives the page time to settle before
|
|
745
|
+
* the next action.
|
|
746
|
+
*
|
|
747
|
+
* Not a humanized action: no plugin events fire.
|
|
748
|
+
*/
|
|
749
|
+
waitForLoadState(state?: Parameters<Page['waitForLoadState']>[0], options?: Parameters<Page['waitForLoadState']>[1]): Promise<void>;
|
|
750
|
+
/**
|
|
751
|
+
* Wait until the page's URL matches `url` (string, RegExp, or predicate).
|
|
752
|
+
* Forwards to `page.waitForURL(url, options)`. Common post-action wait
|
|
753
|
+
* (e.g. after `human.click('#login')`, wait for `/dashboard`).
|
|
754
|
+
*
|
|
755
|
+
* Not a humanized action: no plugin events fire.
|
|
756
|
+
*/
|
|
757
|
+
waitForURL(url: Parameters<Page['waitForURL']>[0], options?: Parameters<Page['waitForURL']>[1]): Promise<void>;
|
|
758
|
+
/**
|
|
759
|
+
* Resize the viewport. Forwards to `page.setViewportSize(size)`. Useful
|
|
760
|
+
* for testing responsive layouts or switching between breakpoints
|
|
761
|
+
* mid-session.
|
|
762
|
+
*
|
|
763
|
+
* Not a humanized action: no plugin events fire.
|
|
764
|
+
*/
|
|
765
|
+
setViewportSize(size: {
|
|
766
|
+
width: number;
|
|
767
|
+
height: number;
|
|
768
|
+
}): Promise<void>;
|
|
769
|
+
/**
|
|
770
|
+
* Render the page as a PDF. Forwards to `page.pdf(options)`. Chromium
|
|
771
|
+
* only; works most reliably in headless mode (in headed mode, Playwright
|
|
772
|
+
* silently switches to a print-style render).
|
|
773
|
+
*
|
|
774
|
+
* Not a humanized action: no plugin events fire.
|
|
775
|
+
*/
|
|
776
|
+
pdf(options?: Parameters<Page['pdf']>[0]): Promise<Buffer>;
|
|
511
777
|
}
|
|
512
778
|
/** Options for {@link Human.record}. */
|
|
513
779
|
interface HumanRecordOptions {
|
|
@@ -545,4 +811,4 @@ interface HumanRecordOptions {
|
|
|
545
811
|
*/
|
|
546
812
|
declare function createHuman(page: Page, options?: CreateHumanOptions): Promise<Human>;
|
|
547
813
|
|
|
548
|
-
export { type CreateHumanOptions, type FfmpegPreset, type FfmpegTune, type Human, type HumanRecordOptions, type InstallMouseHelperOptions, type ReadOptions, type ReadResult, type ReadTarget, Recording, type RecordingQuality, type ScrollOptions, type ScrollResult, type ScrollTarget, type Speed, type Timeline, type TimelineEvent, type ToGifOptions, type ToVideoOptions, createHuman, installMouseHelper };
|
|
814
|
+
export { type CreateHumanOptions, type FfmpegPreset, type FfmpegTune, type Human, type HumanRecordOptions, type InstallMouseHelperOptions, type KeyModifier, type KeyName, type KeyOrChord, type MouseTarget, type PressResult, type ReadOptions, type ReadResult, type ReadTarget, Recording, type RecordingQuality, type ScrollOptions, type ScrollResult, type ScrollTarget, type Speed, type Timeline, type TimelineEvent, type ToGifOptions, type ToVideoOptions, createHuman, installMouseHelper };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,81 @@
|
|
|
1
|
-
import { ReadKind, PersonalityConfig, HumanPlugin,
|
|
1
|
+
import { Point, ReadKind, PersonalityConfig, HumanPlugin, Personality } from '@humanjs/core';
|
|
2
2
|
export { ActionResult, ActionType, BezierPathOptions, ComputeReadingDwellOptions, DwellProfile, HumanAction, HumanPlugin, HumanizePathOptions, Keystroke, KnownActionType, MouseProfile, Personality, PersonalityConfig, PersonalityExtension, PlanTypingOptions, PluginContext, Point, PresetName, ReadKind, ReadingProfile, Rng, ScrollProfile, ScrollSegment, TypingProfile, applyMicroJitter, applyVelocityProfile, bezierPath, blend, careful, computeReadingDwellMs, countWords, createRng, distracted, fast, humanizePath, planScroll, planTypeKeystrokes, precise, resolvePersonality, sleep } from '@humanjs/core';
|
|
3
3
|
import { Locator, BrowserContext, Page } from 'playwright';
|
|
4
4
|
export { Browser, BrowserContext, BrowserContextOptions, ElementHandle, LaunchOptions, Locator, Page, chromium, firefox, webkit } from 'playwright';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Modifier tokens accepted in a `human.press()` chord. `Mod` and `CmdOrCtrl` /
|
|
8
|
+
* `CommandOrControl` are the magic auto-mapping tokens (Meta on Mac,
|
|
9
|
+
* Control elsewhere). The rest are literal — they always resolve to the
|
|
10
|
+
* keycode they name, on every platform.
|
|
11
|
+
*
|
|
12
|
+
* Canonical-case names are listed here for IntelliSense; the runtime
|
|
13
|
+
* parser is case-insensitive, so `'cmd+s'` and `'CMD+S'` work too — they
|
|
14
|
+
* just won't autocomplete.
|
|
15
|
+
*/
|
|
16
|
+
type KeyModifier = 'Mod' | 'CmdOrCtrl' | 'CommandOrControl' | 'Cmd' | 'Command' | 'Meta' | 'Win' | 'Super' | 'Ctrl' | 'Control' | 'Alt' | 'Option' | 'Opt' | 'Shift';
|
|
17
|
+
/**
|
|
18
|
+
* The canonical key names that autocomplete in a `KeyOrChord`. Mirrors
|
|
19
|
+
* Playwright's accepted key vocabulary, plus a few common synonyms.
|
|
20
|
+
* CamelCase names (`ArrowDown`, `PageUp`) are listed in their canonical
|
|
21
|
+
* form — `normalizeKey` preserves case from the input, so what you type is
|
|
22
|
+
* what gets dispatched.
|
|
23
|
+
*
|
|
24
|
+
* Not exhaustive: every other Playwright key (less-common Numpad keys,
|
|
25
|
+
* `BracketLeft`, locale-specific keys, etc.) is outside the typed union
|
|
26
|
+
* and needs a cast at the call site (`'BracketLeft' as KeyOrChord`). The
|
|
27
|
+
* runtime parser handles them — the type just doesn't enumerate them,
|
|
28
|
+
* because adding a `(string & {})` escape hatch would collapse TypeScript's
|
|
29
|
+
* template-literal IntelliSense for the chord autocompletes.
|
|
30
|
+
*/
|
|
31
|
+
type KeyName = 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z' | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'F1' | 'F2' | 'F3' | 'F4' | 'F5' | 'F6' | 'F7' | 'F8' | 'F9' | 'F10' | 'F11' | 'F12' | 'ArrowUp' | 'ArrowDown' | 'ArrowLeft' | 'ArrowRight' | 'PageUp' | 'PageDown' | 'Home' | 'End' | 'Enter' | 'Tab' | 'Escape' | 'Space' | 'Backspace' | 'Delete' | 'Insert' | 'CapsLock' | 'NumLock' | 'ScrollLock' | 'PrintScreen' | 'Pause';
|
|
32
|
+
/**
|
|
33
|
+
* Strings accepted by `human.press(key)`:
|
|
34
|
+
*
|
|
35
|
+
* - A bare known key: `'Enter'`, `'F4'`, `'ArrowDown'`, `'S'`, …
|
|
36
|
+
* - One known modifier + a known key: `'Mod+S'`, `'Shift+ArrowDown'`, …
|
|
37
|
+
* - Two known modifiers + a known key: `'Mod+Shift+P'`, `'Ctrl+Alt+Tab'`, …
|
|
38
|
+
*
|
|
39
|
+
* Every member of the union is a fully-enumerated literal, which is what
|
|
40
|
+
* makes IDE autocomplete work — type `'Shift+'` and you get every
|
|
41
|
+
* `Shift+<key>` combination as a completion. Adding a `(string & {})`
|
|
42
|
+
* escape hatch anywhere would collapse that down to a single wide
|
|
43
|
+
* template member, killing the completion list.
|
|
44
|
+
*
|
|
45
|
+
* Modifier typos (`'Mosd+S'`) and uncommon-key typos (`'Mod+BraketLeft'`)
|
|
46
|
+
* are both TS errors at the call site — the closed sets on both sides
|
|
47
|
+
* give you compile-time protection that Playwright's plain `string` key
|
|
48
|
+
* type can't.
|
|
49
|
+
*
|
|
50
|
+
* **Escape hatch for uncommon keys.** Less-common Playwright keys
|
|
51
|
+
* (`'BracketLeft'`, `'NumpadAdd'`, locale-specific keys, …) and 3+
|
|
52
|
+
* modifier chords (`'Ctrl+Shift+Alt+K'`) aren't in the union and need a
|
|
53
|
+
* cast at the call site:
|
|
54
|
+
*
|
|
55
|
+
* ```ts
|
|
56
|
+
* await human.press('Mod+BracketLeft' as KeyOrChord);
|
|
57
|
+
* await human.press('Ctrl+Shift+Alt+K' as KeyOrChord);
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* The runtime parser handles these fine — the cast just acknowledges
|
|
61
|
+
* "I'm using a key outside the autocomplete vocabulary." If you find
|
|
62
|
+
* yourself casting often for a specific key, propose adding it to
|
|
63
|
+
* `KeyName` in a PR.
|
|
64
|
+
*
|
|
65
|
+
* Lowercase modifiers (`'mod+s'`) also don't typecheck even though the
|
|
66
|
+
* runtime accepts them — TS-strict steers users toward the canonical
|
|
67
|
+
* casing, which keeps key strings consistent across a codebase.
|
|
68
|
+
*/
|
|
69
|
+
type KeyOrChord = KeyName | `${KeyModifier}+${KeyName}` | `${KeyModifier}+${KeyModifier}+${KeyName}`;
|
|
70
|
+
/** Result of a `press` action. */
|
|
71
|
+
interface PressResult {
|
|
72
|
+
/** The exact chord that was dispatched (after Mod-resolution). */
|
|
73
|
+
readonly dispatched: string;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Anything that can resolve to a click/move point. */
|
|
77
|
+
type MouseTarget = Locator | string | Point;
|
|
78
|
+
|
|
6
79
|
/**
|
|
7
80
|
* What to read:
|
|
8
81
|
* - `string`: a Playwright-compatible selector (matches `click()` / `type()`).
|
|
@@ -385,14 +458,69 @@ interface Human {
|
|
|
385
458
|
/**
|
|
386
459
|
* Move the mouse along a humanized Bezier path to `target` and click.
|
|
387
460
|
*
|
|
388
|
-
* `target` accepts
|
|
389
|
-
* `'button:has-text("Buy now")'`)
|
|
390
|
-
*
|
|
461
|
+
* `target` accepts a Playwright-compatible selector string (e.g.
|
|
462
|
+
* `'button:has-text("Buy now")'`), a built `Locator`, or a raw `Point`.
|
|
463
|
+
* For element targets the click point is Gaussian-distributed around the
|
|
464
|
+
* center; for a raw `Point` the exact coordinates are clicked. The
|
|
465
|
+
* `Point` form is the fallback for things with no clean selector —
|
|
466
|
+
* icon-only buttons, canvas, SVG — where you can see the pixel position
|
|
467
|
+
* but can't address the element.
|
|
468
|
+
*
|
|
469
|
+
* In `speed: 'instant'`, all humanization is skipped: element targets use
|
|
470
|
+
* Playwright's native `locator.click()`; a `Point` dispatches one
|
|
471
|
+
* `mouse.click()` at the coordinates.
|
|
472
|
+
*/
|
|
473
|
+
click(target: MouseTarget): Promise<void>;
|
|
474
|
+
/**
|
|
475
|
+
* Right-click `target` — opens a native context menu. Same Bezier-path
|
|
476
|
+
* motion and hover dwell as `click()`; only the dispatched button differs.
|
|
477
|
+
* Accepts the same selector / `Locator` / `Point` targets as `click()`.
|
|
478
|
+
*
|
|
479
|
+
* In `speed: 'instant'`, element targets fall back to
|
|
480
|
+
* `locator.click({ button: 'right' })`; a `Point` dispatches one
|
|
481
|
+
* `mouse.click({ button: 'right' })` at the coordinates.
|
|
482
|
+
*/
|
|
483
|
+
rightClick(target: MouseTarget): Promise<void>;
|
|
484
|
+
/**
|
|
485
|
+
* Move the cursor to `target` along a humanized Bezier path and settle
|
|
486
|
+
* on it — no click is dispatched. Useful for hover-triggered UI
|
|
487
|
+
* (tooltips, dropdowns), for positioning the cursor before a non-target
|
|
488
|
+
* action, or for visible demos where the cursor should pause on
|
|
489
|
+
* something noteworthy.
|
|
490
|
+
*
|
|
491
|
+
* In `speed: 'instant'`, dispatches one `mouse.move()` to the element's
|
|
492
|
+
* center.
|
|
493
|
+
*/
|
|
494
|
+
hover(target: Locator | string): Promise<void>;
|
|
495
|
+
/**
|
|
496
|
+
* Move the cursor to `target` along a humanized Bezier path. Pure
|
|
497
|
+
* positioning — no settle dwell, no element interaction. `target` accepts
|
|
498
|
+
* a CSS selector, a `Locator`, or a literal `Point`; the `Point` form
|
|
499
|
+
* lets you position the cursor anywhere (canvas, SVG, dead space) without
|
|
500
|
+
* a DOM element to anchor on.
|
|
501
|
+
*
|
|
502
|
+
* Distinct from `hover()`: `hover` is element-bound and includes a settle
|
|
503
|
+
* dwell to let hover-state UI fire (tooltips, dropdowns). `move` is
|
|
504
|
+
* positional only — use it when you want the cursor placed somewhere
|
|
505
|
+
* without implying interaction with what's under it (pre-press
|
|
506
|
+
* placement, canvas painting, cinematic beats).
|
|
507
|
+
*
|
|
508
|
+
* In `speed: 'instant'`, dispatches one `mouse.move()` at the resolved
|
|
509
|
+
* coordinates.
|
|
510
|
+
*/
|
|
511
|
+
move(target: MouseTarget): Promise<void>;
|
|
512
|
+
/**
|
|
513
|
+
* Drag from `from` to `to`. Each endpoint accepts a CSS selector, a
|
|
514
|
+
* `Locator`, or a literal `Point` — the last form matters for canvas /
|
|
515
|
+
* SVG / slider drags where the destination isn't a DOM element.
|
|
516
|
+
*
|
|
517
|
+
* The motion is two humanized paths back-to-back: cursor → source,
|
|
518
|
+
* then source → destination with the left button held throughout.
|
|
391
519
|
*
|
|
392
|
-
* In `speed: 'instant'`,
|
|
393
|
-
*
|
|
520
|
+
* In `speed: 'instant'`, dispatches `mouse.down → move → up` at the
|
|
521
|
+
* resolved coordinates without humanized motion.
|
|
394
522
|
*/
|
|
395
|
-
|
|
523
|
+
drag(from: MouseTarget, to: MouseTarget): Promise<void>;
|
|
396
524
|
/**
|
|
397
525
|
* Type `value` into `target` with humanized per-key timing, optional typo
|
|
398
526
|
* injection (with backspace recovery), and occasional think-pauses.
|
|
@@ -404,6 +532,48 @@ interface Human {
|
|
|
404
532
|
* zero inter-key delay — events still fire, but humanization is skipped.
|
|
405
533
|
*/
|
|
406
534
|
type(target: Locator | string, value: string): Promise<void>;
|
|
535
|
+
/**
|
|
536
|
+
* Insert `value` into `target` in one shot — the Cmd-V semantic. No
|
|
537
|
+
* per-character timing. Like `type()`, drives an implicit click to focus
|
|
538
|
+
* the field first; unlike `type()`, dispatches the whole value via
|
|
539
|
+
* `keyboard.insertText` rather than per-key presses.
|
|
540
|
+
*
|
|
541
|
+
* Use this for long strings (code blocks, multi-line content, secrets)
|
|
542
|
+
* where the typing simulation would be slow and unnecessary. If you need
|
|
543
|
+
* the page's `paste` event handler to fire, call `human.press('Mod+V')`
|
|
544
|
+
* after setting clipboard contents yourself.
|
|
545
|
+
*
|
|
546
|
+
* In `speed: 'instant'`, behaves identically — paste is already instant
|
|
547
|
+
* by nature.
|
|
548
|
+
*/
|
|
549
|
+
paste(target: Locator | string, value: string): Promise<void>;
|
|
550
|
+
/**
|
|
551
|
+
* Press a single key (`'Tab'`, `'Enter'`, `'Escape'`, `'ArrowDown'`, …)
|
|
552
|
+
* or a keyboard chord (`'Mod+S'`, `'Cmd+Shift+P'`, `'Ctrl+C'`, …).
|
|
553
|
+
*
|
|
554
|
+
* Modifier rules:
|
|
555
|
+
*
|
|
556
|
+
* - `Mod` / `CmdOrCtrl` / `CommandOrControl` — magic: `Meta` on Mac,
|
|
557
|
+
* `Control` elsewhere. Use for cross-platform app shortcuts. The three
|
|
558
|
+
* are aliases; `Mod` is shortest.
|
|
559
|
+
* - `Cmd`, `Command`, `Meta`, `Win`, `Super` — literal `Meta` keycode
|
|
560
|
+
* (Command on Mac, Windows key on Windows, Super on Linux).
|
|
561
|
+
* - `Ctrl`, `Control` — literal Control. Stays Control on every OS.
|
|
562
|
+
* - `Alt`, `Option`, `Opt` — literal Alt.
|
|
563
|
+
* - `Shift` — literal Shift.
|
|
564
|
+
*
|
|
565
|
+
* Case-insensitive. Throws on unknown modifiers. The `KeyOrChord` type
|
|
566
|
+
* is a template-literal union of every modifier × key combination (up to
|
|
567
|
+
* two literal modifiers + a key), so IDEs autocomplete common bare keys
|
|
568
|
+
* and chords as you type. Less common keys (`BracketLeft`, `NumpadAdd`,
|
|
569
|
+
* locale-specific keys) still typecheck through the union's string
|
|
570
|
+
* escape hatch — they just don't autocomplete.
|
|
571
|
+
*
|
|
572
|
+
* Does **not** move the cursor — keyboard input dispatches against
|
|
573
|
+
* focus, not cursor position. Compose with `click` / `hover` / `move`
|
|
574
|
+
* when you need both.
|
|
575
|
+
*/
|
|
576
|
+
press(key: KeyOrChord): Promise<void>;
|
|
407
577
|
/**
|
|
408
578
|
* Dwell as if reading `target` — the third pillar of humanization after
|
|
409
579
|
* the cursor and the keyboard. Real users pause to read; HumanJS models
|
|
@@ -508,6 +678,102 @@ interface Human {
|
|
|
508
678
|
*/
|
|
509
679
|
record(fn: () => Promise<void>): Promise<Recording>;
|
|
510
680
|
record(options: HumanRecordOptions, fn: () => Promise<void>): Promise<Recording>;
|
|
681
|
+
/**
|
|
682
|
+
* Take a screenshot of the page. Forwards to `page.screenshot(options)`
|
|
683
|
+
* unchanged — see Playwright docs for the full options shape.
|
|
684
|
+
*
|
|
685
|
+
* Not a humanized action: no plugin events fire. Pure ergonomic
|
|
686
|
+
* re-export so `human.*` stays a single surface.
|
|
687
|
+
*/
|
|
688
|
+
screenshot(options?: Parameters<Page['screenshot']>[0]): Promise<Buffer>;
|
|
689
|
+
/**
|
|
690
|
+
* Visible text content of the page (`document.body.innerText`). Forwards
|
|
691
|
+
* to `page.innerText('body')`. Useful for AI agents that need to
|
|
692
|
+
* understand what's on screen without parsing HTML.
|
|
693
|
+
*
|
|
694
|
+
* For a region instead of the whole page, use `page.innerText(selector)`.
|
|
695
|
+
*
|
|
696
|
+
* Not a humanized action: no plugin events fire.
|
|
697
|
+
*/
|
|
698
|
+
pageText(): Promise<string>;
|
|
699
|
+
/**
|
|
700
|
+
* Full HTML of the page. Forwards to `page.content()`. Often large
|
|
701
|
+
* (50–500 KB on typical sites) — prefer {@link Human.pageText} when
|
|
702
|
+
* passing to an LLM unless structure matters.
|
|
703
|
+
*
|
|
704
|
+
* Not a humanized action: no plugin events fire.
|
|
705
|
+
*/
|
|
706
|
+
content(): Promise<string>;
|
|
707
|
+
/**
|
|
708
|
+
* Current URL of the page. Forwards to `page.url()`. Synchronous return
|
|
709
|
+
* because Playwright's underlying API is sync.
|
|
710
|
+
*
|
|
711
|
+
* Not a humanized action: no plugin events fire.
|
|
712
|
+
*/
|
|
713
|
+
url(): string;
|
|
714
|
+
/**
|
|
715
|
+
* Current document title. Forwards to `page.title()`.
|
|
716
|
+
*
|
|
717
|
+
* Not a humanized action: no plugin events fire.
|
|
718
|
+
*/
|
|
719
|
+
title(): Promise<string>;
|
|
720
|
+
/**
|
|
721
|
+
* Reload the current page. Forwards to `page.reload(options)`. Real-user
|
|
722
|
+
* analog of hitting the refresh button — the click motion is *not*
|
|
723
|
+
* humanized (we treat reload as navigation, not a cursor action).
|
|
724
|
+
*
|
|
725
|
+
* Plugins observe a `'reload'` action.
|
|
726
|
+
*/
|
|
727
|
+
reload(options?: Parameters<Page['reload']>[0]): Promise<void>;
|
|
728
|
+
/**
|
|
729
|
+
* Navigate back in the browser history. Forwards to `page.goBack(options)`.
|
|
730
|
+
*
|
|
731
|
+
* Plugins observe a `'goBack'` action.
|
|
732
|
+
*/
|
|
733
|
+
goBack(options?: Parameters<Page['goBack']>[0]): Promise<void>;
|
|
734
|
+
/**
|
|
735
|
+
* Navigate forward in the browser history. Forwards to
|
|
736
|
+
* `page.goForward(options)`.
|
|
737
|
+
*
|
|
738
|
+
* Plugins observe a `'goForward'` action.
|
|
739
|
+
*/
|
|
740
|
+
goForward(options?: Parameters<Page['goForward']>[0]): Promise<void>;
|
|
741
|
+
/**
|
|
742
|
+
* Wait until the page reaches the specified load state. Forwards to
|
|
743
|
+
* `page.waitForLoadState(state, options)`. Common after a humanized
|
|
744
|
+
* click that triggers navigation — gives the page time to settle before
|
|
745
|
+
* the next action.
|
|
746
|
+
*
|
|
747
|
+
* Not a humanized action: no plugin events fire.
|
|
748
|
+
*/
|
|
749
|
+
waitForLoadState(state?: Parameters<Page['waitForLoadState']>[0], options?: Parameters<Page['waitForLoadState']>[1]): Promise<void>;
|
|
750
|
+
/**
|
|
751
|
+
* Wait until the page's URL matches `url` (string, RegExp, or predicate).
|
|
752
|
+
* Forwards to `page.waitForURL(url, options)`. Common post-action wait
|
|
753
|
+
* (e.g. after `human.click('#login')`, wait for `/dashboard`).
|
|
754
|
+
*
|
|
755
|
+
* Not a humanized action: no plugin events fire.
|
|
756
|
+
*/
|
|
757
|
+
waitForURL(url: Parameters<Page['waitForURL']>[0], options?: Parameters<Page['waitForURL']>[1]): Promise<void>;
|
|
758
|
+
/**
|
|
759
|
+
* Resize the viewport. Forwards to `page.setViewportSize(size)`. Useful
|
|
760
|
+
* for testing responsive layouts or switching between breakpoints
|
|
761
|
+
* mid-session.
|
|
762
|
+
*
|
|
763
|
+
* Not a humanized action: no plugin events fire.
|
|
764
|
+
*/
|
|
765
|
+
setViewportSize(size: {
|
|
766
|
+
width: number;
|
|
767
|
+
height: number;
|
|
768
|
+
}): Promise<void>;
|
|
769
|
+
/**
|
|
770
|
+
* Render the page as a PDF. Forwards to `page.pdf(options)`. Chromium
|
|
771
|
+
* only; works most reliably in headless mode (in headed mode, Playwright
|
|
772
|
+
* silently switches to a print-style render).
|
|
773
|
+
*
|
|
774
|
+
* Not a humanized action: no plugin events fire.
|
|
775
|
+
*/
|
|
776
|
+
pdf(options?: Parameters<Page['pdf']>[0]): Promise<Buffer>;
|
|
511
777
|
}
|
|
512
778
|
/** Options for {@link Human.record}. */
|
|
513
779
|
interface HumanRecordOptions {
|
|
@@ -545,4 +811,4 @@ interface HumanRecordOptions {
|
|
|
545
811
|
*/
|
|
546
812
|
declare function createHuman(page: Page, options?: CreateHumanOptions): Promise<Human>;
|
|
547
813
|
|
|
548
|
-
export { type CreateHumanOptions, type FfmpegPreset, type FfmpegTune, type Human, type HumanRecordOptions, type InstallMouseHelperOptions, type ReadOptions, type ReadResult, type ReadTarget, Recording, type RecordingQuality, type ScrollOptions, type ScrollResult, type ScrollTarget, type Speed, type Timeline, type TimelineEvent, type ToGifOptions, type ToVideoOptions, createHuman, installMouseHelper };
|
|
814
|
+
export { type CreateHumanOptions, type FfmpegPreset, type FfmpegTune, type Human, type HumanRecordOptions, type InstallMouseHelperOptions, type KeyModifier, type KeyName, type KeyOrChord, type MouseTarget, type PressResult, type ReadOptions, type ReadResult, type ReadTarget, Recording, type RecordingQuality, type ScrollOptions, type ScrollResult, type ScrollTarget, type Speed, type Timeline, type TimelineEvent, type ToGifOptions, type ToVideoOptions, createHuman, installMouseHelper };
|