mirror of
https://github.com/CloakHQ/CloakBrowser.git
synced 2026-06-23 11:41:46 +02:00
feat(js): add types to humanized method options (#205)
Replace `any` with proper TypeScript types on all humanized method options (Playwright, Puppeteer, ElementHandle, Frame). Support flat per-call config overrides alongside existing `human_config` style. Internalize `humanIdle` duration computation with backward-compatible overloads. Co-authored-by: Eternal <chasezou09@gmail.com>
This commit is contained in:
+185
-185
@@ -106,9 +106,9 @@ describe("humanMove", () => {
|
||||
return {
|
||||
raw: {
|
||||
move: vi.fn(async (x: number, y: number) => { moves.push({ x, y }); }),
|
||||
down: vi.fn(async () => {}),
|
||||
up: vi.fn(async () => {}),
|
||||
wheel: vi.fn(async () => {}),
|
||||
down: vi.fn(async () => { }),
|
||||
up: vi.fn(async () => { }),
|
||||
wheel: vi.fn(async () => { }),
|
||||
},
|
||||
moves,
|
||||
};
|
||||
@@ -180,10 +180,10 @@ describe("humanClick", () => {
|
||||
const cfg = resolveConfig("default");
|
||||
const callOrder: string[] = [];
|
||||
const raw = {
|
||||
move: vi.fn(async () => {}),
|
||||
move: vi.fn(async () => { }),
|
||||
down: vi.fn(async () => { callOrder.push("down"); }),
|
||||
up: vi.fn(async () => { callOrder.push("up"); }),
|
||||
wheel: vi.fn(async () => {}),
|
||||
wheel: vi.fn(async () => { }),
|
||||
};
|
||||
await humanClick(raw, false, cfg);
|
||||
expect(raw.down).toHaveBeenCalledTimes(1);
|
||||
@@ -199,12 +199,12 @@ describe("humanIdle", () => {
|
||||
it("calls raw.move at least once during idle", async () => {
|
||||
const cfg = resolveConfig("default");
|
||||
const raw = {
|
||||
move: vi.fn(async () => {}),
|
||||
down: vi.fn(async () => {}),
|
||||
up: vi.fn(async () => {}),
|
||||
wheel: vi.fn(async () => {}),
|
||||
move: vi.fn(async () => { }),
|
||||
down: vi.fn(async () => { }),
|
||||
up: vi.fn(async () => { }),
|
||||
wheel: vi.fn(async () => { }),
|
||||
};
|
||||
await humanIdle(raw, 10, 100, 100, cfg);
|
||||
await humanIdle(raw, 100, 100, cfg);
|
||||
expect(raw.move).toHaveBeenCalled();
|
||||
}, 15000);
|
||||
});
|
||||
@@ -265,7 +265,7 @@ describe("patchPage fill", () => {
|
||||
const cursor = { x: 0, y: 0, initialized: false };
|
||||
patchPage(page as any, cfg, cursor as any);
|
||||
|
||||
try { await (page as any).fill("input#name", "hello"); } catch (_) {}
|
||||
try { await (page as any).fill("input#name", "hello"); } catch (_) { }
|
||||
|
||||
const expected = process.platform === "darwin" ? "Meta+a" : "Control+a";
|
||||
const wrong = process.platform === "darwin" ? "Control+a" : "Meta+a";
|
||||
@@ -298,7 +298,7 @@ describe("patchPage check/uncheck idle", () => {
|
||||
const cursor = { x: 100, y: 100, initialized: true };
|
||||
patchPage(page as any, cfg, cursor as any);
|
||||
|
||||
try { await (page as any).check("input#cb"); } catch (_) {}
|
||||
try { await (page as any).check("input#cb"); } catch (_) { }
|
||||
|
||||
// humanCheckFn → humanIdle → humanClickFn → humanClick → raw.down
|
||||
expect(downCalled).toBe(true);
|
||||
@@ -321,7 +321,7 @@ describe("patchPage check/uncheck idle", () => {
|
||||
const cursor = { x: 100, y: 100, initialized: true };
|
||||
patchPage(page as any, cfg, cursor as any);
|
||||
|
||||
try { await (page as any).uncheck("input#cb"); } catch (_) {}
|
||||
try { await (page as any).uncheck("input#cb"); } catch (_) { }
|
||||
|
||||
expect(downCalled).toBe(true);
|
||||
}, 30000);
|
||||
@@ -354,7 +354,7 @@ describe("patchPage press focus", () => {
|
||||
const cursor = { x: 50, y: 50, initialized: true };
|
||||
patchPage(page as any, cfg, cursor as any);
|
||||
|
||||
try { await (page as any).press("input#field", "Enter"); } catch (_) {}
|
||||
try { await (page as any).press("input#field", "Enter"); } catch (_) { }
|
||||
|
||||
expect(downCount).toBeGreaterThan(0);
|
||||
});
|
||||
@@ -372,7 +372,7 @@ describe("patchPage press focus", () => {
|
||||
const cursor = { x: 50, y: 50, initialized: true };
|
||||
patchPage(page as any, cfg, cursor as any);
|
||||
|
||||
try { await (page as any).press("input#field", "Enter"); } catch (_) {}
|
||||
try { await (page as any).press("input#field", "Enter"); } catch (_) { }
|
||||
|
||||
expect(downCount).toBe(0);
|
||||
});
|
||||
@@ -528,7 +528,7 @@ describe("patchBrowser CDP-connected workflow", () => {
|
||||
pages: vi.fn(() => [page]),
|
||||
on: vi.fn(),
|
||||
newPage: vi.fn(async () => buildMockPage()),
|
||||
addInitScript: vi.fn(async () => {}),
|
||||
addInitScript: vi.fn(async () => { }),
|
||||
};
|
||||
const browser: any = {
|
||||
contexts: vi.fn(() => [context]),
|
||||
@@ -557,7 +557,7 @@ describe("patchBrowser CDP-connected workflow", () => {
|
||||
pages: vi.fn(() => [page]),
|
||||
on: vi.fn(),
|
||||
newPage: vi.fn(async () => buildMockPage()),
|
||||
addInitScript: vi.fn(async () => {}),
|
||||
addInitScript: vi.fn(async () => { }),
|
||||
};
|
||||
const browser: any = {
|
||||
contexts: vi.fn(() => [context]),
|
||||
@@ -568,7 +568,7 @@ describe("patchBrowser CDP-connected workflow", () => {
|
||||
patchBrowser(browser, resolveConfig("default"));
|
||||
|
||||
// Click through the patched method — should go through humanize path
|
||||
try { await (page as any).click("button"); } catch (_) {}
|
||||
try { await (page as any).click("button"); } catch (_) { }
|
||||
|
||||
expect(downCalled).toBe(true);
|
||||
}, 30000);
|
||||
@@ -581,7 +581,7 @@ describe("patchBrowser CDP-connected workflow", () => {
|
||||
pages: vi.fn(() => [newPage]),
|
||||
on: vi.fn(),
|
||||
newPage: vi.fn(async () => buildMockPage()),
|
||||
addInitScript: vi.fn(async () => {}),
|
||||
addInitScript: vi.fn(async () => { }),
|
||||
};
|
||||
const browser: any = {
|
||||
contexts: vi.fn(() => []),
|
||||
@@ -605,27 +605,27 @@ describe("patchBrowser CDP-connected workflow", () => {
|
||||
function buildMockPage(overrides: Record<string, any> = {}): any {
|
||||
const mainFrameObj = overrides.mainFrameReturn ?? {
|
||||
childFrames: vi.fn(() => []),
|
||||
click: vi.fn(async () => {}),
|
||||
dblclick: vi.fn(async () => {}),
|
||||
hover: vi.fn(async () => {}),
|
||||
type: vi.fn(async () => {}),
|
||||
fill: vi.fn(async () => {}),
|
||||
check: vi.fn(async () => {}),
|
||||
uncheck: vi.fn(async () => {}),
|
||||
selectOption: vi.fn(async () => {}),
|
||||
press: vi.fn(async () => {}),
|
||||
clear: vi.fn(async () => {}),
|
||||
dragAndDrop: vi.fn(async () => {}),
|
||||
click: vi.fn(async () => { }),
|
||||
dblclick: vi.fn(async () => { }),
|
||||
hover: vi.fn(async () => { }),
|
||||
type: vi.fn(async () => { }),
|
||||
fill: vi.fn(async () => { }),
|
||||
check: vi.fn(async () => { }),
|
||||
uncheck: vi.fn(async () => { }),
|
||||
selectOption: vi.fn(async () => { }),
|
||||
press: vi.fn(async () => { }),
|
||||
clear: vi.fn(async () => { }),
|
||||
dragAndDrop: vi.fn(async () => { }),
|
||||
locator: vi.fn(() => ({
|
||||
boundingBox: vi.fn(async () => ({ x: 0, y: 0, width: 100, height: 30 })),
|
||||
first: vi.fn(function(this: any) { return this; }),
|
||||
first: vi.fn(function (this: any) { return this; }),
|
||||
})),
|
||||
};
|
||||
|
||||
const makeLocator = () => {
|
||||
const loc: any = {
|
||||
boundingBox: vi.fn(async () => ({ x: 100, y: 100, width: 200, height: 30 })),
|
||||
scrollIntoViewIfNeeded: vi.fn(async () => {}),
|
||||
scrollIntoViewIfNeeded: vi.fn(async () => { }),
|
||||
isChecked: overrides.isChecked ?? vi.fn(async () => false),
|
||||
};
|
||||
loc.first = vi.fn(() => loc);
|
||||
@@ -634,33 +634,33 @@ function buildMockPage(overrides: Record<string, any> = {}): any {
|
||||
|
||||
const page: any = {
|
||||
evaluate: overrides.evaluate ?? vi.fn(async () => false),
|
||||
addInitScript: vi.fn(async () => {}),
|
||||
addInitScript: vi.fn(async () => { }),
|
||||
mouse: {
|
||||
move: vi.fn(async () => {}),
|
||||
down: vi.fn(async () => {}),
|
||||
up: vi.fn(async () => {}),
|
||||
click: vi.fn(async () => {}),
|
||||
dblclick: vi.fn(async () => {}),
|
||||
wheel: vi.fn(async () => {}),
|
||||
move: vi.fn(async () => { }),
|
||||
down: vi.fn(async () => { }),
|
||||
up: vi.fn(async () => { }),
|
||||
click: vi.fn(async () => { }),
|
||||
dblclick: vi.fn(async () => { }),
|
||||
wheel: vi.fn(async () => { }),
|
||||
},
|
||||
keyboard: {
|
||||
press: overrides.keyboardPress
|
||||
? vi.fn(overrides.keyboardPress)
|
||||
: vi.fn(async () => {}),
|
||||
type: vi.fn(async () => {}),
|
||||
down: vi.fn(async () => {}),
|
||||
up: vi.fn(async () => {}),
|
||||
insertText: vi.fn(async () => {}),
|
||||
: vi.fn(async () => { }),
|
||||
type: vi.fn(async () => { }),
|
||||
down: vi.fn(async () => { }),
|
||||
up: vi.fn(async () => { }),
|
||||
insertText: vi.fn(async () => { }),
|
||||
},
|
||||
click: vi.fn(async () => {}),
|
||||
dblclick: vi.fn(async () => {}),
|
||||
hover: vi.fn(async () => {}),
|
||||
type: vi.fn(async () => {}),
|
||||
fill: vi.fn(async () => {}),
|
||||
check: vi.fn(async () => {}),
|
||||
uncheck: vi.fn(async () => {}),
|
||||
selectOption: vi.fn(async () => {}),
|
||||
press: vi.fn(async () => {}),
|
||||
click: vi.fn(async () => { }),
|
||||
dblclick: vi.fn(async () => { }),
|
||||
hover: vi.fn(async () => { }),
|
||||
type: vi.fn(async () => { }),
|
||||
fill: vi.fn(async () => { }),
|
||||
check: vi.fn(async () => { }),
|
||||
uncheck: vi.fn(async () => { }),
|
||||
selectOption: vi.fn(async () => { }),
|
||||
press: vi.fn(async () => { }),
|
||||
goto: vi.fn(async () => ({})),
|
||||
isChecked: overrides.isChecked ?? vi.fn(async () => false),
|
||||
locator: vi.fn(() => makeLocator()),
|
||||
@@ -669,10 +669,10 @@ function buildMockPage(overrides: Record<string, any> = {}): any {
|
||||
frames: vi.fn(() => []),
|
||||
context: vi.fn(() => ({
|
||||
pages: vi.fn(() => []),
|
||||
addInitScript: vi.fn(async () => {}),
|
||||
addInitScript: vi.fn(async () => { }),
|
||||
})),
|
||||
url: vi.fn(() => "about:blank"),
|
||||
waitForTimeout: vi.fn(async () => {}),
|
||||
waitForTimeout: vi.fn(async () => { }),
|
||||
};
|
||||
return page;
|
||||
}
|
||||
@@ -686,8 +686,8 @@ describe("humanType non-ASCII", () => {
|
||||
const insertedChars: string[] = [];
|
||||
const raw = {
|
||||
down: vi.fn(async (k: string) => { downKeys.push(k); }),
|
||||
up: vi.fn(async () => {}),
|
||||
type: vi.fn(async () => {}),
|
||||
up: vi.fn(async () => { }),
|
||||
type: vi.fn(async () => { }),
|
||||
insertText: vi.fn(async (t: string) => { insertedChars.push(t); }),
|
||||
};
|
||||
return { raw, downKeys, insertedChars };
|
||||
@@ -759,18 +759,18 @@ describe("humanType non-ASCII", () => {
|
||||
|
||||
function buildMockElementHandle(overrides: Record<string, any> = {}): any {
|
||||
const el: any = {
|
||||
click: vi.fn(async () => {}),
|
||||
dblclick: vi.fn(async () => {}),
|
||||
hover: vi.fn(async () => {}),
|
||||
type: vi.fn(async () => {}),
|
||||
fill: vi.fn(async () => {}),
|
||||
press: vi.fn(async () => {}),
|
||||
selectOption: vi.fn(async () => {}),
|
||||
check: vi.fn(async () => {}),
|
||||
uncheck: vi.fn(async () => {}),
|
||||
setChecked: vi.fn(async () => {}),
|
||||
tap: vi.fn(async () => {}),
|
||||
focus: vi.fn(async () => {}),
|
||||
click: vi.fn(async () => { }),
|
||||
dblclick: vi.fn(async () => { }),
|
||||
hover: vi.fn(async () => { }),
|
||||
type: vi.fn(async () => { }),
|
||||
fill: vi.fn(async () => { }),
|
||||
press: vi.fn(async () => { }),
|
||||
selectOption: vi.fn(async () => { }),
|
||||
check: vi.fn(async () => { }),
|
||||
uncheck: vi.fn(async () => { }),
|
||||
setChecked: vi.fn(async () => { }),
|
||||
tap: vi.fn(async () => { }),
|
||||
focus: vi.fn(async () => { }),
|
||||
boundingBox: overrides.boundingBox ?? vi.fn(async () => ({ x: 100, y: 100, width: 200, height: 30 })),
|
||||
evaluate: overrides.evaluate ?? vi.fn(async () => false),
|
||||
isChecked: overrides.isChecked ?? vi.fn(async () => false),
|
||||
@@ -788,21 +788,21 @@ describe("patchSingleElementHandle", () => {
|
||||
const cfg = resolveConfig("default");
|
||||
const cursor = { x: 100, y: 100, initialized: true };
|
||||
const raw = {
|
||||
move: vi.fn(async () => {}),
|
||||
down: vi.fn(async () => {}),
|
||||
up: vi.fn(async () => {}),
|
||||
wheel: vi.fn(async () => {}),
|
||||
move: vi.fn(async () => { }),
|
||||
down: vi.fn(async () => { }),
|
||||
up: vi.fn(async () => { }),
|
||||
wheel: vi.fn(async () => { }),
|
||||
};
|
||||
const rawKb = {
|
||||
down: vi.fn(async () => {}),
|
||||
up: vi.fn(async () => {}),
|
||||
type: vi.fn(async () => {}),
|
||||
insertText: vi.fn(async () => {}),
|
||||
down: vi.fn(async () => { }),
|
||||
up: vi.fn(async () => { }),
|
||||
type: vi.fn(async () => { }),
|
||||
insertText: vi.fn(async () => { }),
|
||||
};
|
||||
const originals = {
|
||||
keyboardPress: vi.fn(async () => {}),
|
||||
keyboardDown: vi.fn(async () => {}),
|
||||
keyboardUp: vi.fn(async () => {}),
|
||||
keyboardPress: vi.fn(async () => { }),
|
||||
keyboardDown: vi.fn(async () => { }),
|
||||
keyboardUp: vi.fn(async () => { }),
|
||||
};
|
||||
|
||||
const el = buildMockElementHandle();
|
||||
@@ -825,23 +825,23 @@ describe("patchSingleElementHandle", () => {
|
||||
move: vi.fn(async () => { moveCount++; }),
|
||||
down: vi.fn(async () => { downCalled = true; }),
|
||||
up: vi.fn(async () => { upCalled = true; }),
|
||||
wheel: vi.fn(async () => {}),
|
||||
wheel: vi.fn(async () => { }),
|
||||
};
|
||||
const rawKb = {
|
||||
down: vi.fn(async () => {}),
|
||||
up: vi.fn(async () => {}),
|
||||
type: vi.fn(async () => {}),
|
||||
insertText: vi.fn(async () => {}),
|
||||
down: vi.fn(async () => { }),
|
||||
up: vi.fn(async () => { }),
|
||||
type: vi.fn(async () => { }),
|
||||
insertText: vi.fn(async () => { }),
|
||||
};
|
||||
const originals = {
|
||||
keyboardPress: vi.fn(async () => {}),
|
||||
keyboardDown: vi.fn(async () => {}),
|
||||
keyboardUp: vi.fn(async () => {}),
|
||||
keyboardPress: vi.fn(async () => { }),
|
||||
keyboardDown: vi.fn(async () => { }),
|
||||
keyboardUp: vi.fn(async () => { }),
|
||||
};
|
||||
|
||||
const el = buildMockElementHandle();
|
||||
const page = buildMockPage();
|
||||
(page as any)._ensureCursorInit = vi.fn(async () => {});
|
||||
(page as any)._ensureCursorInit = vi.fn(async () => { });
|
||||
|
||||
patchSingleElementHandle(el, page as any, cfg, cursor as any, raw, rawKb, originals, null);
|
||||
|
||||
@@ -859,22 +859,22 @@ describe("patchSingleElementHandle", () => {
|
||||
|
||||
let downCalled = false;
|
||||
const raw = {
|
||||
move: vi.fn(async () => {}),
|
||||
move: vi.fn(async () => { }),
|
||||
down: vi.fn(async () => { downCalled = true; }),
|
||||
up: vi.fn(async () => {}),
|
||||
wheel: vi.fn(async () => {}),
|
||||
up: vi.fn(async () => { }),
|
||||
wheel: vi.fn(async () => { }),
|
||||
};
|
||||
const rawKb = {
|
||||
down: vi.fn(async () => {}),
|
||||
up: vi.fn(async () => {}),
|
||||
type: vi.fn(async () => {}),
|
||||
insertText: vi.fn(async () => {}),
|
||||
down: vi.fn(async () => { }),
|
||||
up: vi.fn(async () => { }),
|
||||
type: vi.fn(async () => { }),
|
||||
insertText: vi.fn(async () => { }),
|
||||
};
|
||||
const originals = { keyboardPress: vi.fn(async () => {}), keyboardDown: vi.fn(async () => {}), keyboardUp: vi.fn(async () => {}) };
|
||||
const originals = { keyboardPress: vi.fn(async () => { }), keyboardDown: vi.fn(async () => { }), keyboardUp: vi.fn(async () => { }) };
|
||||
|
||||
const el = buildMockElementHandle();
|
||||
const page = buildMockPage();
|
||||
(page as any)._ensureCursorInit = vi.fn(async () => {});
|
||||
(page as any)._ensureCursorInit = vi.fn(async () => { });
|
||||
|
||||
patchSingleElementHandle(el, page as any, cfg, cursor as any, raw, rawKb, originals, null);
|
||||
|
||||
@@ -890,22 +890,22 @@ describe("patchSingleElementHandle", () => {
|
||||
const cursor = { x: 50, y: 50, initialized: true };
|
||||
|
||||
const raw = {
|
||||
move: vi.fn(async () => {}),
|
||||
down: vi.fn(async () => {}),
|
||||
up: vi.fn(async () => {}),
|
||||
wheel: vi.fn(async () => {}),
|
||||
move: vi.fn(async () => { }),
|
||||
down: vi.fn(async () => { }),
|
||||
up: vi.fn(async () => { }),
|
||||
wheel: vi.fn(async () => { }),
|
||||
};
|
||||
const rawKb = {
|
||||
down: vi.fn(async () => {}),
|
||||
up: vi.fn(async () => {}),
|
||||
type: vi.fn(async () => {}),
|
||||
insertText: vi.fn(async () => {}),
|
||||
down: vi.fn(async () => { }),
|
||||
up: vi.fn(async () => { }),
|
||||
type: vi.fn(async () => { }),
|
||||
insertText: vi.fn(async () => { }),
|
||||
};
|
||||
const originals = { keyboardPress: vi.fn(async () => {}), keyboardDown: vi.fn(async () => {}), keyboardUp: vi.fn(async () => {}) };
|
||||
const originals = { keyboardPress: vi.fn(async () => { }), keyboardDown: vi.fn(async () => { }), keyboardUp: vi.fn(async () => { }) };
|
||||
|
||||
const el = buildMockElementHandle({ evaluate: vi.fn(async () => true) }); // isInput = true
|
||||
const page = buildMockPage();
|
||||
(page as any)._ensureCursorInit = vi.fn(async () => {});
|
||||
(page as any)._ensureCursorInit = vi.fn(async () => { });
|
||||
|
||||
patchSingleElementHandle(el, page as any, cfg, cursor as any, raw, rawKb, originals, null);
|
||||
|
||||
@@ -923,26 +923,26 @@ describe("patchSingleElementHandle", () => {
|
||||
|
||||
const pressedKeys: string[] = [];
|
||||
const raw = {
|
||||
move: vi.fn(async () => {}),
|
||||
down: vi.fn(async () => {}),
|
||||
up: vi.fn(async () => {}),
|
||||
wheel: vi.fn(async () => {}),
|
||||
move: vi.fn(async () => { }),
|
||||
down: vi.fn(async () => { }),
|
||||
up: vi.fn(async () => { }),
|
||||
wheel: vi.fn(async () => { }),
|
||||
};
|
||||
const rawKb = {
|
||||
down: vi.fn(async () => {}),
|
||||
up: vi.fn(async () => {}),
|
||||
type: vi.fn(async () => {}),
|
||||
insertText: vi.fn(async () => {}),
|
||||
down: vi.fn(async () => { }),
|
||||
up: vi.fn(async () => { }),
|
||||
type: vi.fn(async () => { }),
|
||||
insertText: vi.fn(async () => { }),
|
||||
};
|
||||
const originals = {
|
||||
keyboardPress: vi.fn(async (key: string) => { pressedKeys.push(key); }),
|
||||
keyboardDown: vi.fn(async () => {}),
|
||||
keyboardUp: vi.fn(async () => {}),
|
||||
keyboardDown: vi.fn(async () => { }),
|
||||
keyboardUp: vi.fn(async () => { }),
|
||||
};
|
||||
|
||||
const el = buildMockElementHandle({ evaluate: vi.fn(async () => true) });
|
||||
const page = buildMockPage();
|
||||
(page as any)._ensureCursorInit = vi.fn(async () => {});
|
||||
(page as any)._ensureCursorInit = vi.fn(async () => { });
|
||||
|
||||
patchSingleElementHandle(el, page as any, cfg, cursor as any, raw, rawKb, originals, null);
|
||||
|
||||
@@ -957,9 +957,9 @@ describe("patchSingleElementHandle", () => {
|
||||
const { patchSingleElementHandle } = await import("../src/human/elementhandle.js");
|
||||
const cfg = resolveConfig("default");
|
||||
const cursor = { x: 0, y: 0, initialized: false };
|
||||
const raw = { move: vi.fn(async () => {}), down: vi.fn(async () => {}), up: vi.fn(async () => {}), wheel: vi.fn(async () => {}) };
|
||||
const rawKb = { down: vi.fn(async () => {}), up: vi.fn(async () => {}), type: vi.fn(async () => {}), insertText: vi.fn(async () => {}) };
|
||||
const originals = { keyboardPress: vi.fn(async () => {}), keyboardDown: vi.fn(async () => {}), keyboardUp: vi.fn(async () => {}) };
|
||||
const raw = { move: vi.fn(async () => { }), down: vi.fn(async () => { }), up: vi.fn(async () => { }), wheel: vi.fn(async () => { }) };
|
||||
const rawKb = { down: vi.fn(async () => { }), up: vi.fn(async () => { }), type: vi.fn(async () => { }), insertText: vi.fn(async () => { }) };
|
||||
const originals = { keyboardPress: vi.fn(async () => { }), keyboardDown: vi.fn(async () => { }), keyboardUp: vi.fn(async () => { }) };
|
||||
|
||||
const el = buildMockElementHandle();
|
||||
const page = buildMockPage();
|
||||
@@ -976,9 +976,9 @@ describe("patchSingleElementHandle", () => {
|
||||
const { patchSingleElementHandle } = await import("../src/human/elementhandle.js");
|
||||
const cfg = resolveConfig("default");
|
||||
const cursor = { x: 0, y: 0, initialized: false };
|
||||
const raw = { move: vi.fn(async () => {}), down: vi.fn(async () => {}), up: vi.fn(async () => {}), wheel: vi.fn(async () => {}) };
|
||||
const rawKb = { down: vi.fn(async () => {}), up: vi.fn(async () => {}), type: vi.fn(async () => {}), insertText: vi.fn(async () => {}) };
|
||||
const originals = { keyboardPress: vi.fn(async () => {}), keyboardDown: vi.fn(async () => {}), keyboardUp: vi.fn(async () => {}) };
|
||||
const raw = { move: vi.fn(async () => { }), down: vi.fn(async () => { }), up: vi.fn(async () => { }), wheel: vi.fn(async () => { }) };
|
||||
const rawKb = { down: vi.fn(async () => { }), up: vi.fn(async () => { }), type: vi.fn(async () => { }), insertText: vi.fn(async () => { }) };
|
||||
const originals = { keyboardPress: vi.fn(async () => { }), keyboardDown: vi.fn(async () => { }), keyboardUp: vi.fn(async () => { }) };
|
||||
|
||||
const child = buildMockElementHandle();
|
||||
const el = buildMockElementHandle();
|
||||
@@ -998,9 +998,9 @@ describe("patchPageElementHandles", () => {
|
||||
const { patchPageElementHandles } = await import("../src/human/elementhandle.js");
|
||||
const cfg = resolveConfig("default");
|
||||
const cursor = { x: 0, y: 0, initialized: false };
|
||||
const raw = { move: vi.fn(async () => {}), down: vi.fn(async () => {}), up: vi.fn(async () => {}), wheel: vi.fn(async () => {}) };
|
||||
const rawKb = { down: vi.fn(async () => {}), up: vi.fn(async () => {}), type: vi.fn(async () => {}), insertText: vi.fn(async () => {}) };
|
||||
const originals = { keyboardPress: vi.fn(async () => {}), keyboardDown: vi.fn(async () => {}), keyboardUp: vi.fn(async () => {}) };
|
||||
const raw = { move: vi.fn(async () => { }), down: vi.fn(async () => { }), up: vi.fn(async () => { }), wheel: vi.fn(async () => { }) };
|
||||
const rawKb = { down: vi.fn(async () => { }), up: vi.fn(async () => { }), type: vi.fn(async () => { }), insertText: vi.fn(async () => { }) };
|
||||
const originals = { keyboardPress: vi.fn(async () => { }), keyboardDown: vi.fn(async () => { }), keyboardUp: vi.fn(async () => { }) };
|
||||
|
||||
const el = buildMockElementHandle();
|
||||
const page = buildMockPage();
|
||||
@@ -1018,9 +1018,9 @@ describe("patchPageElementHandles", () => {
|
||||
const { patchPageElementHandles } = await import("../src/human/elementhandle.js");
|
||||
const cfg = resolveConfig("default");
|
||||
const cursor = { x: 0, y: 0, initialized: false };
|
||||
const raw = { move: vi.fn(async () => {}), down: vi.fn(async () => {}), up: vi.fn(async () => {}), wheel: vi.fn(async () => {}) };
|
||||
const rawKb = { down: vi.fn(async () => {}), up: vi.fn(async () => {}), type: vi.fn(async () => {}), insertText: vi.fn(async () => {}) };
|
||||
const originals = { keyboardPress: vi.fn(async () => {}), keyboardDown: vi.fn(async () => {}), keyboardUp: vi.fn(async () => {}) };
|
||||
const raw = { move: vi.fn(async () => { }), down: vi.fn(async () => { }), up: vi.fn(async () => { }), wheel: vi.fn(async () => { }) };
|
||||
const rawKb = { down: vi.fn(async () => { }), up: vi.fn(async () => { }), type: vi.fn(async () => { }), insertText: vi.fn(async () => { }) };
|
||||
const originals = { keyboardPress: vi.fn(async () => { }), keyboardDown: vi.fn(async () => { }), keyboardUp: vi.fn(async () => { }) };
|
||||
|
||||
const el1 = buildMockElementHandle();
|
||||
const el2 = buildMockElementHandle();
|
||||
@@ -1040,9 +1040,9 @@ describe("patchPageElementHandles", () => {
|
||||
const { patchPageElementHandles } = await import("../src/human/elementhandle.js");
|
||||
const cfg = resolveConfig("default");
|
||||
const cursor = { x: 0, y: 0, initialized: false };
|
||||
const raw = { move: vi.fn(async () => {}), down: vi.fn(async () => {}), up: vi.fn(async () => {}), wheel: vi.fn(async () => {}) };
|
||||
const rawKb = { down: vi.fn(async () => {}), up: vi.fn(async () => {}), type: vi.fn(async () => {}), insertText: vi.fn(async () => {}) };
|
||||
const originals = { keyboardPress: vi.fn(async () => {}), keyboardDown: vi.fn(async () => {}), keyboardUp: vi.fn(async () => {}) };
|
||||
const raw = { move: vi.fn(async () => { }), down: vi.fn(async () => { }), up: vi.fn(async () => { }), wheel: vi.fn(async () => { }) };
|
||||
const rawKb = { down: vi.fn(async () => { }), up: vi.fn(async () => { }), type: vi.fn(async () => { }), insertText: vi.fn(async () => { }) };
|
||||
const originals = { keyboardPress: vi.fn(async () => { }), keyboardDown: vi.fn(async () => { }), keyboardUp: vi.fn(async () => { }) };
|
||||
|
||||
const el = buildMockElementHandle();
|
||||
const page = buildMockPage();
|
||||
@@ -1060,9 +1060,9 @@ describe("patchPageElementHandles", () => {
|
||||
const { patchPageElementHandles } = await import("../src/human/elementhandle.js");
|
||||
const cfg = resolveConfig("default");
|
||||
const cursor = { x: 0, y: 0, initialized: false };
|
||||
const raw = { move: vi.fn(async () => {}), down: vi.fn(async () => {}), up: vi.fn(async () => {}), wheel: vi.fn(async () => {}) };
|
||||
const rawKb = { down: vi.fn(async () => {}), up: vi.fn(async () => {}), type: vi.fn(async () => {}), insertText: vi.fn(async () => {}) };
|
||||
const originals = { keyboardPress: vi.fn(async () => {}), keyboardDown: vi.fn(async () => {}), keyboardUp: vi.fn(async () => {}) };
|
||||
const raw = { move: vi.fn(async () => { }), down: vi.fn(async () => { }), up: vi.fn(async () => { }), wheel: vi.fn(async () => { }) };
|
||||
const rawKb = { down: vi.fn(async () => { }), up: vi.fn(async () => { }), type: vi.fn(async () => { }), insertText: vi.fn(async () => { }) };
|
||||
const originals = { keyboardPress: vi.fn(async () => { }), keyboardDown: vi.fn(async () => { }), keyboardUp: vi.fn(async () => { }) };
|
||||
|
||||
const page = buildMockPage();
|
||||
(page as any).$ = vi.fn(async () => null);
|
||||
@@ -1106,19 +1106,19 @@ function buildMockFrame(): any {
|
||||
locator.first = vi.fn(() => locator);
|
||||
|
||||
return {
|
||||
click: vi.fn(async () => {}),
|
||||
dblclick: vi.fn(async () => {}),
|
||||
hover: vi.fn(async () => {}),
|
||||
type: vi.fn(async () => {}),
|
||||
fill: vi.fn(async () => {}),
|
||||
check: vi.fn(async () => {}),
|
||||
uncheck: vi.fn(async () => {}),
|
||||
selectOption: vi.fn(async () => {}),
|
||||
press: vi.fn(async () => {}),
|
||||
pressSequentially: vi.fn(async () => {}),
|
||||
tap: vi.fn(async () => {}),
|
||||
clear: vi.fn(async () => {}),
|
||||
dragAndDrop: vi.fn(async () => {}),
|
||||
click: vi.fn(async () => { }),
|
||||
dblclick: vi.fn(async () => { }),
|
||||
hover: vi.fn(async () => { }),
|
||||
type: vi.fn(async () => { }),
|
||||
fill: vi.fn(async () => { }),
|
||||
check: vi.fn(async () => { }),
|
||||
uncheck: vi.fn(async () => { }),
|
||||
selectOption: vi.fn(async () => { }),
|
||||
press: vi.fn(async () => { }),
|
||||
pressSequentially: vi.fn(async () => { }),
|
||||
tap: vi.fn(async () => { }),
|
||||
clear: vi.fn(async () => { }),
|
||||
dragAndDrop: vi.fn(async () => { }),
|
||||
locator: vi.fn(() => locator),
|
||||
childFrames: vi.fn(() => []),
|
||||
};
|
||||
@@ -1169,10 +1169,10 @@ describe("page.click(selector, { timeout }) forwards timeout to scroll", () => {
|
||||
locator: vi.fn(() => ({ first: () => ({ boundingBox }) })),
|
||||
};
|
||||
const raw = {
|
||||
move: vi.fn(async () => {}),
|
||||
down: vi.fn(async () => {}),
|
||||
up: vi.fn(async () => {}),
|
||||
wheel: vi.fn(async () => {}),
|
||||
move: vi.fn(async () => { }),
|
||||
down: vi.fn(async () => { }),
|
||||
up: vi.fn(async () => { }),
|
||||
wheel: vi.fn(async () => { }),
|
||||
};
|
||||
|
||||
await scrollToElement(page, raw, "#x", 0, 0, cfg, 5000);
|
||||
@@ -1189,10 +1189,10 @@ describe("page.click(selector, { timeout }) forwards timeout to scroll", () => {
|
||||
locator: vi.fn(() => ({ first: () => ({ boundingBox }) })),
|
||||
};
|
||||
const raw = {
|
||||
move: vi.fn(async () => {}),
|
||||
down: vi.fn(async () => {}),
|
||||
up: vi.fn(async () => {}),
|
||||
wheel: vi.fn(async () => {}),
|
||||
move: vi.fn(async () => { }),
|
||||
down: vi.fn(async () => { }),
|
||||
up: vi.fn(async () => { }),
|
||||
wheel: vi.fn(async () => { }),
|
||||
};
|
||||
|
||||
await scrollToElement(page, raw, "#x", 0, 0, cfg);
|
||||
@@ -1224,10 +1224,10 @@ describe("page.click(selector, { timeout }) forwards timeout to scroll", () => {
|
||||
|
||||
|
||||
// =========================================================================
|
||||
// Per-call human_config override
|
||||
// Per-call human config override
|
||||
// =========================================================================
|
||||
describe("page.type / page.fill accept per-call human_config override", () => {
|
||||
it("page.type forwards merged config to humanType", async () => {
|
||||
describe("page.type / page.fill accept per-call human config override", () => {
|
||||
it("page.type forwards nested human_config to humanType", async () => {
|
||||
const keyboardMod = await import("../src/human/keyboard.js");
|
||||
const scrollMod = await import("../src/human/scroll.js");
|
||||
const { patchPage } = await import("../src/human/index.js");
|
||||
@@ -1267,7 +1267,7 @@ describe("page.type / page.fill accept per-call human_config override", () => {
|
||||
scrollSpy.mockRestore();
|
||||
}, 30000);
|
||||
|
||||
it("page.fill forwards merged config to humanType", async () => {
|
||||
it("page.fill forwards flat config to humanType", async () => {
|
||||
const keyboardMod = await import("../src/human/keyboard.js");
|
||||
const scrollMod = await import("../src/human/scroll.js");
|
||||
const { patchPage } = await import("../src/human/index.js");
|
||||
@@ -1293,7 +1293,7 @@ describe("page.type / page.fill accept per-call human_config override", () => {
|
||||
patchPage(page as any, cfg, cursor as any);
|
||||
|
||||
await (page as any).fill("#password", "secret", {
|
||||
human_config: { typing_delay: 150 },
|
||||
typing_delay: 150,
|
||||
});
|
||||
|
||||
expect(captured.typing_delay).toBe(150);
|
||||
@@ -1313,13 +1313,13 @@ describe("page.type / page.fill accept per-call human_config override", () => {
|
||||
async (_page, _raw, _text, callCfg) => { captured = callCfg; },
|
||||
);
|
||||
|
||||
const raw = { move: vi.fn(async () => {}), down: vi.fn(async () => {}), up: vi.fn(async () => {}), wheel: vi.fn(async () => {}) };
|
||||
const rawKb = { down: vi.fn(async () => {}), up: vi.fn(async () => {}), type: vi.fn(async () => {}), insertText: vi.fn(async () => {}) };
|
||||
const originals = { keyboardPress: vi.fn(async () => {}), keyboardDown: vi.fn(async () => {}), keyboardUp: vi.fn(async () => {}) };
|
||||
const raw = { move: vi.fn(async () => { }), down: vi.fn(async () => { }), up: vi.fn(async () => { }), wheel: vi.fn(async () => { }) };
|
||||
const rawKb = { down: vi.fn(async () => { }), up: vi.fn(async () => { }), type: vi.fn(async () => { }), insertText: vi.fn(async () => { }) };
|
||||
const originals = { keyboardPress: vi.fn(async () => { }), keyboardDown: vi.fn(async () => { }), keyboardUp: vi.fn(async () => { }) };
|
||||
|
||||
const el = buildMockElementHandle({ evaluate: vi.fn(async () => true) });
|
||||
const page = buildMockPage();
|
||||
(page as any)._ensureCursorInit = vi.fn(async () => {});
|
||||
(page as any)._ensureCursorInit = vi.fn(async () => { });
|
||||
|
||||
patchSingleElementHandle(el, page as any, cfg, cursor as any, raw, rawKb, originals, null);
|
||||
|
||||
@@ -1341,10 +1341,10 @@ describe("humanScrollIntoView", () => {
|
||||
|
||||
const page: any = { viewportSize: () => ({ width: 1280, height: 720 }) };
|
||||
const raw = {
|
||||
move: vi.fn(async () => {}),
|
||||
down: vi.fn(async () => {}),
|
||||
up: vi.fn(async () => {}),
|
||||
wheel: vi.fn(async () => {}),
|
||||
move: vi.fn(async () => { }),
|
||||
down: vi.fn(async () => { }),
|
||||
up: vi.fn(async () => { }),
|
||||
wheel: vi.fn(async () => { }),
|
||||
};
|
||||
// Box centered in viewport — squarely in scroll_target_zone
|
||||
const inViewBox = { x: 200, y: 300, width: 50, height: 30 };
|
||||
@@ -1366,10 +1366,10 @@ describe("humanScrollIntoView", () => {
|
||||
|
||||
const page: any = { viewportSize: () => ({ width: 1280, height: 720 }) };
|
||||
const raw = {
|
||||
move: vi.fn(async () => {}),
|
||||
down: vi.fn(async () => {}),
|
||||
up: vi.fn(async () => {}),
|
||||
wheel: vi.fn(async () => {}),
|
||||
move: vi.fn(async () => { }),
|
||||
down: vi.fn(async () => { }),
|
||||
up: vi.fn(async () => { }),
|
||||
wheel: vi.fn(async () => { }),
|
||||
};
|
||||
|
||||
const boxes = [
|
||||
@@ -1403,14 +1403,14 @@ describe("el.scrollIntoViewIfNeeded humanization", () => {
|
||||
|
||||
const cfg = resolveConfig("default", { idle_between_actions: false });
|
||||
const cursor = { x: 50, y: 50, initialized: true };
|
||||
const raw = { move: vi.fn(async () => {}), down: vi.fn(async () => {}), up: vi.fn(async () => {}), wheel: vi.fn(async () => {}) };
|
||||
const rawKb = { down: vi.fn(async () => {}), up: vi.fn(async () => {}), type: vi.fn(async () => {}), insertText: vi.fn(async () => {}) };
|
||||
const originals = { keyboardPress: vi.fn(async () => {}), keyboardDown: vi.fn(async () => {}), keyboardUp: vi.fn(async () => {}) };
|
||||
const raw = { move: vi.fn(async () => { }), down: vi.fn(async () => { }), up: vi.fn(async () => { }), wheel: vi.fn(async () => { }) };
|
||||
const rawKb = { down: vi.fn(async () => { }), up: vi.fn(async () => { }), type: vi.fn(async () => { }), insertText: vi.fn(async () => { }) };
|
||||
const originals = { keyboardPress: vi.fn(async () => { }), keyboardDown: vi.fn(async () => { }), keyboardUp: vi.fn(async () => { }) };
|
||||
|
||||
const el = buildMockElementHandle();
|
||||
el.scrollIntoViewIfNeeded = vi.fn(async () => {});
|
||||
el.scrollIntoViewIfNeeded = vi.fn(async () => { });
|
||||
const page = buildMockPage();
|
||||
(page as any)._ensureCursorInit = vi.fn(async () => {});
|
||||
(page as any)._ensureCursorInit = vi.fn(async () => { });
|
||||
|
||||
patchSingleElementHandle(el, page as any, cfg, cursor as any, raw, rawKb, originals, null);
|
||||
await el.scrollIntoViewIfNeeded();
|
||||
@@ -1429,15 +1429,15 @@ describe("el.scrollIntoViewIfNeeded humanization", () => {
|
||||
|
||||
const cfg = resolveConfig("default", { idle_between_actions: false });
|
||||
const cursor = { x: 50, y: 50, initialized: true };
|
||||
const raw = { move: vi.fn(async () => {}), down: vi.fn(async () => {}), up: vi.fn(async () => {}), wheel: vi.fn(async () => {}) };
|
||||
const rawKb = { down: vi.fn(async () => {}), up: vi.fn(async () => {}), type: vi.fn(async () => {}), insertText: vi.fn(async () => {}) };
|
||||
const originals = { keyboardPress: vi.fn(async () => {}), keyboardDown: vi.fn(async () => {}), keyboardUp: vi.fn(async () => {}) };
|
||||
const raw = { move: vi.fn(async () => { }), down: vi.fn(async () => { }), up: vi.fn(async () => { }), wheel: vi.fn(async () => { }) };
|
||||
const rawKb = { down: vi.fn(async () => { }), up: vi.fn(async () => { }), type: vi.fn(async () => { }), insertText: vi.fn(async () => { }) };
|
||||
const originals = { keyboardPress: vi.fn(async () => { }), keyboardDown: vi.fn(async () => { }), keyboardUp: vi.fn(async () => { }) };
|
||||
|
||||
const nativeFallback = vi.fn(async () => {});
|
||||
const nativeFallback = vi.fn(async () => { });
|
||||
const el = buildMockElementHandle();
|
||||
el.scrollIntoViewIfNeeded = nativeFallback;
|
||||
const page = buildMockPage();
|
||||
(page as any)._ensureCursorInit = vi.fn(async () => {});
|
||||
(page as any)._ensureCursorInit = vi.fn(async () => { });
|
||||
|
||||
patchSingleElementHandle(el, page as any, cfg, cursor as any, raw, rawKb, originals, null);
|
||||
await el.scrollIntoViewIfNeeded();
|
||||
|
||||
@@ -532,6 +532,52 @@ describe("Puppeteer: non-ASCII text avoids CDP shift path", () => {
|
||||
});
|
||||
|
||||
|
||||
// =========================================================================
|
||||
// Per-call human config override (Puppeteer page-level)
|
||||
// =========================================================================
|
||||
describe("Puppeteer: page.type accepts per-call human config override", () => {
|
||||
it("page.type forwards merged config to humanType", async () => {
|
||||
const keyboardMod = await import("../src/human-puppeteer/keyboard.js");
|
||||
const scrollMod = await import("../src/human-puppeteer/scroll.js");
|
||||
|
||||
const cfg = resolveConfig("default", {
|
||||
idle_between_actions: false,
|
||||
field_switch_delay: [0, 1],
|
||||
});
|
||||
expect(cfg.typing_delay).toBe(70);
|
||||
|
||||
let captured: any = null;
|
||||
const typeSpy = vi.spyOn(keyboardMod, "humanType").mockImplementation(
|
||||
async (_page, _raw, _text, callCfg) => { captured = callCfg; },
|
||||
);
|
||||
const scrollSpy = vi.spyOn(scrollMod, "scrollToElement").mockImplementation(
|
||||
async (_page, _raw, _sel, cx, cy) => ({
|
||||
box: { x: 100, y: 100, width: 50, height: 30 },
|
||||
cursorX: cx,
|
||||
cursorY: cy,
|
||||
}),
|
||||
);
|
||||
|
||||
const { patchPage } = await import("../src/human-puppeteer/index.js");
|
||||
const page = buildMockPage();
|
||||
const cursor = { x: 100, y: 100, initialized: true };
|
||||
patchPage(page as any, cfg, cursor as any);
|
||||
|
||||
await (page as any).type("#email", "hi", {
|
||||
typing_delay: 30,
|
||||
mistype_chance: 0,
|
||||
});
|
||||
|
||||
expect(captured.typing_delay).toBe(30);
|
||||
expect(captured.mistype_chance).toBe(0);
|
||||
expect(cfg.typing_delay).toBe(70);
|
||||
|
||||
typeSpy.mockRestore();
|
||||
scrollSpy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// =========================================================================
|
||||
// patchPage stealth infrastructure (Puppeteer)
|
||||
// =========================================================================
|
||||
|
||||
Reference in New Issue
Block a user