ectrol 0.0.3 → 0.0.4
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.mts +12 -1
- package/dist/index.mjs +40 -13
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -88,9 +88,16 @@ declare class ElementHandle {
|
|
|
88
88
|
* 填充输入框内容。
|
|
89
89
|
* - 适用于 `<input>`、`<textarea>` 或 `contenteditable` 元素。
|
|
90
90
|
* - 会触发 `input` 事件(冒泡)。
|
|
91
|
+
* - 支持自定义输入间隔, 'auto' 表示模拟自然输入节奏
|
|
92
|
+
* @example
|
|
93
|
+
* ```
|
|
94
|
+
* await element.fill('Hello, World!', { interval: 100 });
|
|
95
|
+
* ```
|
|
91
96
|
*/
|
|
92
97
|
fill(value: string, options?: {
|
|
93
98
|
timeout?: number;
|
|
99
|
+
interval?: number | 'auto';
|
|
100
|
+
append?: boolean;
|
|
94
101
|
}): Promise<void>;
|
|
95
102
|
/**
|
|
96
103
|
* 在元素上发送按键事件。
|
|
@@ -237,6 +244,10 @@ declare class SessionStorage {
|
|
|
237
244
|
removeItem(key: string): Promise<void>;
|
|
238
245
|
}
|
|
239
246
|
//#endregion
|
|
247
|
+
//#region src/utils.d.ts
|
|
248
|
+
declare function getHumanTypingDelay(index: number, text: string): number;
|
|
249
|
+
declare function sleep(ms: number): Promise<unknown>;
|
|
250
|
+
//#endregion
|
|
240
251
|
//#region src/index.d.ts
|
|
241
252
|
/**
|
|
242
253
|
* Ectrol
|
|
@@ -261,4 +272,4 @@ declare class Ectrol {
|
|
|
261
272
|
$(selector: string): ElementHandle;
|
|
262
273
|
}
|
|
263
274
|
//#endregion
|
|
264
|
-
export { Ectrol, Ectrol as default, ElementHandle, IBoundingClientRect, ISize, IVector2D, LocalStorage, SessionStorage };
|
|
275
|
+
export { Ectrol, Ectrol as default, ElementHandle, IBoundingClientRect, ISize, IVector2D, LocalStorage, SessionStorage, getHumanTypingDelay, sleep };
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
//#region src/utils.ts
|
|
2
|
+
function getHumanTypingDelay(index, text) {
|
|
3
|
+
const char = text[index];
|
|
4
|
+
let delay = 90 + Math.random() * 60;
|
|
5
|
+
const progress = index / text.length;
|
|
6
|
+
if (progress < .15) delay *= 1.3;
|
|
7
|
+
else if (progress > .85) delay *= 1.25;
|
|
8
|
+
if (char === " ") delay += 40;
|
|
9
|
+
if (/[,.!?;:]/.test(char)) delay += 200 + Math.random() * 150;
|
|
10
|
+
if (Math.random() < .03) delay += 300 + Math.random() * 500;
|
|
11
|
+
return Math.max(40, Math.round(delay));
|
|
12
|
+
}
|
|
13
|
+
async function sleep(ms) {
|
|
14
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
1
18
|
//#region src/element.ts
|
|
2
19
|
/**
|
|
3
20
|
* ElementHandle
|
|
@@ -147,7 +164,7 @@ var ElementHandle = class {
|
|
|
147
164
|
button: options?.button || "left",
|
|
148
165
|
clickCount: 1
|
|
149
166
|
});
|
|
150
|
-
await
|
|
167
|
+
await sleep(options?.delay || 10);
|
|
151
168
|
this.contents.sendInputEvent({
|
|
152
169
|
type: "mouseUp",
|
|
153
170
|
x: rect.centerX,
|
|
@@ -198,22 +215,32 @@ var ElementHandle = class {
|
|
|
198
215
|
* 填充输入框内容。
|
|
199
216
|
* - 适用于 `<input>`、`<textarea>` 或 `contenteditable` 元素。
|
|
200
217
|
* - 会触发 `input` 事件(冒泡)。
|
|
218
|
+
* - 支持自定义输入间隔, 'auto' 表示模拟自然输入节奏
|
|
219
|
+
* @example
|
|
220
|
+
* ```
|
|
221
|
+
* await element.fill('Hello, World!', { interval: 100 });
|
|
222
|
+
* ```
|
|
201
223
|
*/
|
|
202
224
|
async fill(value, options) {
|
|
203
|
-
await this.
|
|
225
|
+
await this.focus({ timeout: options?.timeout });
|
|
226
|
+
let interval;
|
|
227
|
+
if (typeof options?.interval === "number") interval = options?.interval;
|
|
228
|
+
if (!options?.append) await this.contents.executeJavaScript(`
|
|
204
229
|
(function() {
|
|
205
230
|
const target = ${this._getElement(options?.timeout)};
|
|
206
|
-
if (
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
target.element.focus();
|
|
212
|
-
|
|
213
|
-
target.element.value = ${JSON.stringify(value)};
|
|
214
|
-
target.element.dispatchEvent(new Event('input', { bubbles: true }));
|
|
231
|
+
if (target && target.element) {
|
|
232
|
+
if (target.element.tagName !== 'INPUT' && target.element.tagName !== 'TEXTAREA' && !target.element.isContentEditable) return null;
|
|
233
|
+
target.element.value = "";
|
|
234
|
+
}
|
|
215
235
|
})()
|
|
216
236
|
`);
|
|
237
|
+
for (let index = 0; index < value.length; index++) {
|
|
238
|
+
await sleep(interval || getHumanTypingDelay(index, value));
|
|
239
|
+
this.contents.sendInputEvent({
|
|
240
|
+
type: "char",
|
|
241
|
+
keyCode: value[index]
|
|
242
|
+
});
|
|
243
|
+
}
|
|
217
244
|
}
|
|
218
245
|
/**
|
|
219
246
|
* 在元素上发送按键事件。
|
|
@@ -230,7 +257,7 @@ var ElementHandle = class {
|
|
|
230
257
|
type: "keyDown",
|
|
231
258
|
keyCode: key$1
|
|
232
259
|
});
|
|
233
|
-
await
|
|
260
|
+
await sleep(options?.delay || 10);
|
|
234
261
|
for (const key$1 of keys) this.contents.sendInputEvent({
|
|
235
262
|
type: "keyUp",
|
|
236
263
|
keyCode: key$1
|
|
@@ -587,4 +614,4 @@ var Ectrol = class {
|
|
|
587
614
|
var src_default = Ectrol;
|
|
588
615
|
|
|
589
616
|
//#endregion
|
|
590
|
-
export { Ectrol, ElementHandle, LocalStorage, SessionStorage, src_default as default };
|
|
617
|
+
export { Ectrol, ElementHandle, LocalStorage, SessionStorage, src_default as default, getHumanTypingDelay, sleep };
|
package/package.json
CHANGED