Typing (Python, JS Playwright/Puppeteer, .NET)
- Absolute-time Typist: log-normal hold (~100 ms), key-pair dependent
inter-key gaps (space, same/other hand, repeated letter), rollover via
queued releases, Shift often released before the letter, no key pressed
twice, all held keys released on error. A lower-case press of a key is
released before Shift + the same key goes down ("xX", "1!"), so no
keydown with repeat=true.
- Defaults moved to Aalto 136M Keystrokes: typing_delay 150, key_hold
(60, 175), mistype_chance 0.04; careful preset updated.
Mouse
- Fitts-law stroke duration (mouse_time_base / per_bit / spread),
log-normal run-to-run spread, frame-rate events, time-warped
minimum-jerk profile with an early velocity peak, gentle curvature and
wobble, no zero-movement events, notch-free overshoot correction.
Scroll
- Whole wheel notches of the persona's platform (Win 100, mac 40,
Linux 120; scroll_notch_px override) in short flicks, so deltaY agrees
with CDP's one-notch wheelDeltaY; overshoot measured in notches.
- scroller() in the isolated-world helpers walks the containing-block
chain: fixed boxes skip ancestors that do not establish a containing
block for them, absolute boxes skip static ancestors. A fixed modal in
a scrolling panel is clicked instead of timing out with "element is
outside of the viewport". All three helper copies stay byte-identical.
Removed
- Settings with no effect after the change: mouse_steps_divisor,
mouse_burst_size, mouse_burst_pause, scroll_delta_base,
scroll_delta_variance (and the .NET properties). Python drops them from
human_config with a FutureWarning that points at the caller; JS and the .NET override
dictionary ignore them. The standalone .NET HumanScroll wheels in whole
notches too. READMEs updated to the new defaults.
- .NET: a "\r\n" text element is inserted as text again (it threw
"Unknown key" from KeyDownAsync).
Tests: timing/rollover/notch/zero-move tests; five #593 cases in Python,
JS and .NET; puppeteer/stealth tests updated to the new semantics.
Co-authored-by: evelaa123 <189992797+evelaa123@users.noreply.github.com>
A dropdown is now picked the way a person picks from a long list: open it,
type the first letters of the option, add a few arrow keys when that is
shorter, press Enter.
- The plan comes from a new __cloakH helper (typeAheadPlan), shared byte for
byte by Python, JS and .NET. It picks the shortest prefix that matches
exactly one enabled option, so the result does not depend on which row the
open popup highlights. That row cannot be read from the page, and on headed
Linux it can be the one under the OS pointer (#580). Prefixes of the
option's own name win; a neighbour's prefix plus up to 3 arrows is used only
when it is shorter. Runs of one letter ("aa") are avoided because Blink
cycles on them.
- Blink joins letters typed within 1s into one search, so a second
select_option on the same page waits for the previous search to lapse.
- The deadline is checked before every key; on timeout the popup is closed
with Escape and a TimeoutError is raised (#581: timeout= was ignored).
- macOS hosts (no arrow keys in the native popup) type the shortest unique
prefix instead of the whole label.
- Labels with no unique prefix (duplicates) fall back to Home + arrows, or the
full label on macOS.
Measured on headed Linux (Xvfb), humanize defaults: #581's 205-option list
1.5-2s per pick (was 20-30s); 166-country list and #580's page with the OS
pointer parked over the popup, 144/144 correct.
Humanized actions in the Playwright wrappers (Python, JS, .NET) now run through a
single shared engine built on Playwright's own selector engine: full locator support
(roles, chains, filters, frame locators, strict mode), Playwright options honoured,
value inputs operated with real input, persona-aware keys, and errors instead of
silent fallbacks. Puppeteer: frame-scoped actions, button/count, Shift on typos.
Follow-ups: macOS dropdowns via type-ahead, nested same-box element handles,
stale handles fail fast, CI fails on a missing test binary.