@roxybrowser/playwright 2.0.2-beta.10 → 2.0.2-beta.13
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/human/bubbleCursor.d.ts +2 -0
- package/dist/human/bubbleCursor.d.ts.map +1 -0
- package/dist/human/bubbleCursor.js +126 -0
- package/dist/human/bubbleCursor.js.map +1 -0
- package/dist/human/controller.d.ts +3 -0
- package/dist/human/controller.d.ts.map +1 -1
- package/dist/human/controller.js +41 -17
- package/dist/human/controller.js.map +1 -1
- package/dist/human/profile.d.ts.map +1 -1
- package/dist/human/profile.js +18 -22
- package/dist/human/profile.js.map +1 -1
- package/dist/human/types.d.ts +1 -1
- package/dist/human/types.d.ts.map +1 -1
- package/dist/locator.js +1 -1
- package/dist/locator.js.map +1 -1
- package/dist/mcp/backend/keyboard.d.ts +28 -0
- package/dist/mcp/backend/keyboard.d.ts.map +1 -1
- package/dist/mcp/backend/keyboard.js +9 -3
- package/dist/mcp/backend/keyboard.js.map +1 -1
- package/dist/mcp/connectedBrowser.d.ts.map +1 -1
- package/dist/mcp/connectedBrowser.js +83 -4
- package/dist/mcp/connectedBrowser.js.map +1 -1
- package/dist/mcp/runtime.d.ts +3 -1
- package/dist/mcp/runtime.d.ts.map +1 -1
- package/dist/mcp/runtime.js +6 -2
- package/dist/mcp/runtime.js.map +1 -1
- package/dist/mcp/tools/mouse.d.ts.map +1 -1
- package/dist/mcp/tools/mouse.js +5 -2
- package/dist/mcp/tools/mouse.js.map +1 -1
- package/dist/mcp/types.d.ts +5 -1
- package/dist/mcp/types.d.ts.map +1 -1
- package/dist/protocol/bidi/backend.d.ts.map +1 -1
- package/dist/protocol/bidi/backend.js +10 -3
- package/dist/protocol/bidi/backend.js.map +1 -1
- package/dist/protocol/cdp/backend.d.ts.map +1 -1
- package/dist/protocol/cdp/backend.js +8 -3
- package/dist/protocol/cdp/backend.js.map +1 -1
- package/dist/types/options.d.ts +0 -1
- package/dist/types/options.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { defineTabTool } from "./tool.js";
|
|
3
3
|
import { elementSchema } from "./snapshot.js";
|
|
4
|
+
const humanSchema = z.object({
|
|
5
|
+
profile: z.enum(["cautious", "balanced", "fast"]).optional().describe("Humanization timing profile, defaults to balanced")
|
|
6
|
+
}).optional();
|
|
4
7
|
const typeSchema = elementSchema.extend({
|
|
5
8
|
text: z.string().describe("Text to type into the element"),
|
|
6
9
|
submit: z.boolean().optional().describe("Whether to submit entered text (press Enter after)"),
|
|
7
|
-
slowly: z.boolean().optional().describe("Whether to type one character at a time. Useful for triggering key handlers in the page. By default entire text is filled in at once.")
|
|
10
|
+
slowly: z.boolean().optional().describe("Whether to type one character at a time. Useful for triggering key handlers in the page. By default entire text is filled in at once."),
|
|
11
|
+
human: humanSchema.describe("Humanization settings for this typing action")
|
|
8
12
|
});
|
|
9
13
|
export const press = defineTabTool({
|
|
10
14
|
capability: "core-input",
|
|
@@ -13,7 +17,8 @@ export const press = defineTabTool({
|
|
|
13
17
|
title: "Press a key",
|
|
14
18
|
description: "Press a key on the keyboard",
|
|
15
19
|
inputSchema: z.object({
|
|
16
|
-
key: z.string().describe("Key to press, e.g. Enter, Escape, Tab, ArrowLeft, Backspace, Delete, or printable characters")
|
|
20
|
+
key: z.string().describe("Key to press, e.g. Enter, Escape, Tab, ArrowLeft, Backspace, Delete, or printable characters"),
|
|
21
|
+
human: humanSchema.describe("Humanization settings for this key press")
|
|
17
22
|
}),
|
|
18
23
|
type: "input"
|
|
19
24
|
},
|
|
@@ -22,7 +27,7 @@ export const press = defineTabTool({
|
|
|
22
27
|
response.addTextResult(`Pressed key "${params.key}".`);
|
|
23
28
|
response.addCode(`await page.keyboard.press(${JSON.stringify(params.key)});`);
|
|
24
29
|
await tab.waitForCompletion(async () => {
|
|
25
|
-
await tab.pressKey(params.key);
|
|
30
|
+
await tab.context.runtime.pressKey(params.key, undefined, params.human?.profile !== undefined ? { profile: params.human.profile } : undefined);
|
|
26
31
|
});
|
|
27
32
|
}
|
|
28
33
|
});
|
|
@@ -55,6 +60,7 @@ export const type = defineTabTool({
|
|
|
55
60
|
await locator.type(params.text, {
|
|
56
61
|
...(params.submit !== undefined ? { submit: params.submit } : {}),
|
|
57
62
|
...(params.slowly !== undefined ? { slowly: params.slowly } : {}),
|
|
63
|
+
...(params.human !== undefined ? { human: params.human } : {}),
|
|
58
64
|
...tab.actionTimeoutOptions
|
|
59
65
|
});
|
|
60
66
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyboard.js","sourceRoot":"","sources":["../../../src/mcp/backend/keyboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC;IACtC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;IAC1D,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oDAAoD,CAAC;IAC7F,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CACrC,uIAAuI,CACxI;
|
|
1
|
+
{"version":3,"file":"keyboard.js","sourceRoot":"","sources":["../../../src/mcp/backend/keyboard.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connectedBrowser.d.ts","sourceRoot":"","sources":["../../src/mcp/connectedBrowser.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"connectedBrowser.d.ts","sourceRoot":"","sources":["../../src/mcp/connectedBrowser.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAOV,uBAAuB,EACvB,sBAAsB,EAQvB,MAAM,YAAY,CAAC;AAk8GpB,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,sBAAsB,GAC3B,OAAO,CAAC,uBAAuB,CAAC,CAMlC"}
|
|
@@ -5,6 +5,7 @@ import { normalizeAriaSnapshotOptions, retryUntilReady } from "../ariaSnapshot.j
|
|
|
5
5
|
import { PLAYWRIGHT_ARIA_SNAPSHOT_EVALUATE_SOURCE as ARIA_SNAPSHOT_EVALUATE_SOURCE } from "../vendor/playwright/ariaSnapshotEvaluate.js";
|
|
6
6
|
import { getBidiClientFactory } from "../protocol/bidi/client.js";
|
|
7
7
|
import { parseSerializedEvaluationResult, wrapWithSerializedEvaluationResult } from "../protocol/evaluationSerializer.js";
|
|
8
|
+
import { BUBBLE_CURSOR_INSTALL_SOURCE } from "../human/bubbleCursor.js";
|
|
8
9
|
import { McpToolError } from "./errors.js";
|
|
9
10
|
import { ACTION_POINT_EVALUATE_SOURCE, ACTION_POINT_BY_SELECTOR_SOURCE } from "./snapshot.js";
|
|
10
11
|
import { configuredTempDir } from "./output.js";
|
|
@@ -214,6 +215,7 @@ const SCROLL_ELEMENT_SOURCE = String.raw `(payload) => {
|
|
|
214
215
|
target.scrollBy({ left: payload.deltaX, top: payload.deltaY, behavior: 'instant' });
|
|
215
216
|
return { ok: true };
|
|
216
217
|
}`;
|
|
218
|
+
const ENSURE_BUBBLE_CURSOR_SOURCE = BUBBLE_CURSOR_INSTALL_SOURCE;
|
|
217
219
|
const GET_ELEMENT_OBJECT_SOURCE = String.raw `(payload) => {
|
|
218
220
|
const state = globalThis.__roxyMcpState;
|
|
219
221
|
return payload.nodeToken
|
|
@@ -406,6 +408,45 @@ async function evaluateBiDiRef(client, contextId, functionSource, arg) {
|
|
|
406
408
|
...(response.result?.value?.handle !== undefined ? { handle: response.result.value.handle } : {})
|
|
407
409
|
};
|
|
408
410
|
}
|
|
411
|
+
async function splitScrollDeltas(deltaX, deltaY, stepPx) {
|
|
412
|
+
const dominantDistance = Math.max(Math.abs(deltaX), Math.abs(deltaY));
|
|
413
|
+
if (dominantDistance === 0) {
|
|
414
|
+
return [];
|
|
415
|
+
}
|
|
416
|
+
const steps = Math.max(1, Math.ceil(dominantDistance / Math.max(1, stepPx)));
|
|
417
|
+
const chunks = [];
|
|
418
|
+
let appliedX = 0;
|
|
419
|
+
let appliedY = 0;
|
|
420
|
+
for (let index = 0; index < steps; index += 1) {
|
|
421
|
+
const nextAppliedX = Math.round((deltaX * (index + 1)) / steps);
|
|
422
|
+
const nextAppliedY = Math.round((deltaY * (index + 1)) / steps);
|
|
423
|
+
chunks.push({
|
|
424
|
+
deltaX: nextAppliedX - appliedX,
|
|
425
|
+
deltaY: nextAppliedY - appliedY
|
|
426
|
+
});
|
|
427
|
+
appliedX = nextAppliedX;
|
|
428
|
+
appliedY = nextAppliedY;
|
|
429
|
+
}
|
|
430
|
+
return chunks.filter((chunk) => chunk.deltaX !== 0 || chunk.deltaY !== 0);
|
|
431
|
+
}
|
|
432
|
+
function maybeReverseScrollChunk(chunk, index, total) {
|
|
433
|
+
if (total < 3 || index === 0 || index === total - 1) {
|
|
434
|
+
return null;
|
|
435
|
+
}
|
|
436
|
+
if (Math.random() > 0.18) {
|
|
437
|
+
return null;
|
|
438
|
+
}
|
|
439
|
+
return {
|
|
440
|
+
deltaX: -Math.round(chunk.deltaX * (0.18 + Math.random() * 0.18)),
|
|
441
|
+
deltaY: -Math.round(chunk.deltaY * (0.18 + Math.random() * 0.18))
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
function shouldPauseToObserve(index, total) {
|
|
445
|
+
if (index === total - 1) {
|
|
446
|
+
return false;
|
|
447
|
+
}
|
|
448
|
+
return total > 2 && Math.random() < 0.22;
|
|
449
|
+
}
|
|
409
450
|
function extractBiDiValue(value) {
|
|
410
451
|
if (!value) {
|
|
411
452
|
return undefined;
|
|
@@ -785,11 +826,26 @@ class CdpConnectedBrowserSession {
|
|
|
785
826
|
deviceScaleFactor: 1
|
|
786
827
|
});
|
|
787
828
|
}
|
|
788
|
-
async scroll(target, deltaX, deltaY) {
|
|
829
|
+
async scroll(target, deltaX, deltaY, options) {
|
|
789
830
|
const pageClient = await this.getActivePageClient();
|
|
790
831
|
const contextId = await this.getActiveUtilityContextId(pageClient);
|
|
791
832
|
const arg = target ? this.targetArg(target) : {};
|
|
792
|
-
await evaluateCdp(pageClient,
|
|
833
|
+
await evaluateCdp(pageClient, ENSURE_BUBBLE_CURSOR_SOURCE, undefined, contextId).catch(() => false);
|
|
834
|
+
const chunks = await splitScrollDeltas(deltaX, deltaY, options?.stepPx ?? Math.max(Math.abs(deltaX), Math.abs(deltaY), 1));
|
|
835
|
+
for (const [index, chunk] of chunks.entries()) {
|
|
836
|
+
await evaluateCdp(pageClient, SCROLL_ELEMENT_SOURCE, { ...arg, deltaX: chunk.deltaX, deltaY: chunk.deltaY }, contextId);
|
|
837
|
+
const reverseChunk = maybeReverseScrollChunk(chunk, index, chunks.length);
|
|
838
|
+
if (reverseChunk) {
|
|
839
|
+
await delay(60 + Math.round(Math.random() * 120));
|
|
840
|
+
await evaluateCdp(pageClient, SCROLL_ELEMENT_SOURCE, { ...arg, deltaX: reverseChunk.deltaX, deltaY: reverseChunk.deltaY }, contextId);
|
|
841
|
+
}
|
|
842
|
+
if (shouldPauseToObserve(index, chunks.length)) {
|
|
843
|
+
await delay(220 + Math.round(Math.random() * 520));
|
|
844
|
+
}
|
|
845
|
+
if ((options?.stepDelayMs ?? 0) > 0) {
|
|
846
|
+
await delay(options.stepDelayMs);
|
|
847
|
+
}
|
|
848
|
+
}
|
|
793
849
|
}
|
|
794
850
|
async screenshot(options = {}) {
|
|
795
851
|
const pageClient = await this.getActivePageClient();
|
|
@@ -2032,10 +2088,33 @@ class BidiConnectedBrowserSession {
|
|
|
2032
2088
|
viewport: { width, height }
|
|
2033
2089
|
});
|
|
2034
2090
|
}
|
|
2035
|
-
async scroll(target, deltaX, deltaY) {
|
|
2091
|
+
async scroll(target, deltaX, deltaY, options) {
|
|
2036
2092
|
const tabId = await this.getActiveTabId();
|
|
2037
2093
|
const arg = target ? ("nodeToken" in target ? { nodeToken: target.nodeToken } : { selector: target.selector }) : {};
|
|
2038
|
-
await evaluateBiDi(this.client, tabId,
|
|
2094
|
+
await evaluateBiDi(this.client, tabId, ENSURE_BUBBLE_CURSOR_SOURCE).catch(() => false);
|
|
2095
|
+
const chunks = await splitScrollDeltas(deltaX, deltaY, options?.stepPx ?? Math.max(Math.abs(deltaX), Math.abs(deltaY), 1));
|
|
2096
|
+
for (const [index, chunk] of chunks.entries()) {
|
|
2097
|
+
await evaluateBiDi(this.client, tabId, SCROLL_ELEMENT_SOURCE, {
|
|
2098
|
+
...arg,
|
|
2099
|
+
deltaX: chunk.deltaX,
|
|
2100
|
+
deltaY: chunk.deltaY
|
|
2101
|
+
});
|
|
2102
|
+
const reverseChunk = maybeReverseScrollChunk(chunk, index, chunks.length);
|
|
2103
|
+
if (reverseChunk) {
|
|
2104
|
+
await delay(60 + Math.round(Math.random() * 120));
|
|
2105
|
+
await evaluateBiDi(this.client, tabId, SCROLL_ELEMENT_SOURCE, {
|
|
2106
|
+
...arg,
|
|
2107
|
+
deltaX: reverseChunk.deltaX,
|
|
2108
|
+
deltaY: reverseChunk.deltaY
|
|
2109
|
+
});
|
|
2110
|
+
}
|
|
2111
|
+
if (shouldPauseToObserve(index, chunks.length)) {
|
|
2112
|
+
await delay(220 + Math.round(Math.random() * 520));
|
|
2113
|
+
}
|
|
2114
|
+
if ((options?.stepDelayMs ?? 0) > 0) {
|
|
2115
|
+
await delay(options.stepDelayMs);
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2039
2118
|
}
|
|
2040
2119
|
async screenshot(options = {}) {
|
|
2041
2120
|
const tabId = await this.getActiveTabId();
|