@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/dist/index.d.cts CHANGED
@@ -1,8 +1,81 @@
1
- import { ReadKind, PersonalityConfig, HumanPlugin, Point, Personality } from '@humanjs/core';
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 either a Playwright-compatible selector string (e.g.
389
- * `'button:has-text("Buy now")'`) or a built `Locator`. The click point
390
- * inside the element is Gaussian-distributed around the center.
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'`, all humanization is skipped and Playwright's
393
- * native `locator.click()` is used directly.
520
+ * In `speed: 'instant'`, dispatches `mouse.down move up` at the
521
+ * resolved coordinates without humanized motion.
394
522
  */
395
- click(target: Locator | string): Promise<void>;
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, Point, Personality } from '@humanjs/core';
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 either a Playwright-compatible selector string (e.g.
389
- * `'button:has-text("Buy now")'`) or a built `Locator`. The click point
390
- * inside the element is Gaussian-distributed around the center.
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'`, all humanization is skipped and Playwright's
393
- * native `locator.click()` is used directly.
520
+ * In `speed: 'instant'`, dispatches `mouse.down move up` at the
521
+ * resolved coordinates without humanized motion.
394
522
  */
395
- click(target: Locator | string): Promise<void>;
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 };