Last active
September 8, 2023 00:38
-
-
Save prescience-data/7345034897119256febccad5a8d8ca5e to your computer and use it in GitHub Desktop.
Demo of biometric typing skeleton logic for Playwright
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { chromium, Page } from "playwright-core" | |
/** | |
* Entrypoint. | |
* | |
* @remarks | |
* Demonstrates a safe typing algorithm that mimics human typing cadence. | |
* | |
* @public | |
*/ | |
export async function main(): Promise<void> { | |
const browser = await chromium.launch({ headless: false }) | |
const page = await browser.newPage() | |
await page.goto("https://www.google.com") | |
await typeInto(page, "input[name=q]", "Hello, World!") | |
} | |
/** | |
* Safely type into a text input. | |
* | |
* @param page - Current page instance. | |
* @param selector - DOM selector to type into. | |
* @param text - Text string to type. | |
* | |
* @internal | |
*/ | |
async function typeInto( | |
page: Page, | |
selector: string, | |
text: string | |
): Promise<void> { | |
// Split input text into characters. | |
const chars = text.split("") | |
for (let i = 0; i < chars.length; i++) { | |
const currentKey = chars[i] | |
const previousKey = i > 0 ? chars[i - 1] : undefined | |
// Handle biometric cadence delay between keys. | |
if (previousKey) { | |
const cadenceDelay = rollCadenceDelay(previousKey, currentKey) | |
await page.waitForTimeout(cadenceDelay) | |
// Handle typing mistakes. | |
const typoKey = rollTypo(previousKey, currentKey) | |
if (typoKey) { | |
const typoPressDelay = rollPressDelay(typoKey) | |
const typoCadenceDelay = rollCadenceDelay(previousKey, "Backspace") | |
await page.keyboard.press(typoKey, { delay: typoPressDelay }) | |
await page.waitForTimeout(typoCadenceDelay) | |
const backspacePressDelay = rollPressDelay("Backspace") | |
await page.keyboard.press("Backspace", { delay: backspacePressDelay }) | |
} | |
} | |
// Handle key up down delay. | |
const pressDelay = rollPressDelay(chars[i]) | |
await page.type(selector, chars[i], { delay: pressDelay }) | |
} | |
} | |
/** | |
* Biometrics logic for calculating a keypress delay for a specific key. | |
* | |
* @param fromKey - Source key. | |
* | |
* @returns Delay in milliseconds. | |
*/ | |
function rollPressDelay(fromKey: string): number { | |
// TODO: Add specific logic per key. | |
return rand(2, 5) | |
} | |
/** | |
* Biometrics logic for calculating a delay between keys. | |
* | |
* @param fromKey - Previous key. | |
* @param toKey - Current key. | |
* | |
* @returns Delay in milliseconds. | |
*/ | |
function rollCadenceDelay(fromKey: string, toKey: string): number { | |
// TODO: Add specific logic per key transition. | |
return rand(6, 8) | |
} | |
/** | |
* Biometrics logic for calculating a chance of a typo between keys. | |
* | |
* @param fromKey - Previous key. | |
* @param toKey - Current key. | |
* | |
* @returns True if a typo should be made. | |
*/ | |
function rollTypo(fromKey: string, toKey: string): string | undefined { | |
// TODO: Add specific logic per key transition. | |
if (chance(10)) { | |
// TODO: Pick a key most likely to be a typo based on vector. | |
return "abcdefghiklmnopqrstuvwxyz".split("")[rand(0, 25)] | |
} | |
return undefined | |
} | |
/** | |
* Generates a random number within range. | |
* | |
* @param min - Min value. | |
* @param max - Max value. | |
* | |
* @returns Random number. | |
*/ | |
function rand(min: number, max?: number): number { | |
return Math.floor(Math.random() * ((max ?? min) - (max ? min : 0)) + (max ? min : 0)) | |
} | |
/** | |
* Rolls a weighted chance. | |
* | |
* @param weight - Weight of chance. | |
* | |
* @returns True if chance is successful. | |
*/ | |
function chance(weight: number = 50): boolean { | |
return rand(0, 100) <= weight | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment