arn-browser 0.0.6 → 0.0.7
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/package.json +1 -1
- package/src/human-cursor/HumanCursor.js +35 -11
package/package.json
CHANGED
|
@@ -20,6 +20,22 @@ function sleep(ms) {
|
|
|
20
20
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Simple mutex for serializing keyboard operations
|
|
25
|
+
*/
|
|
26
|
+
let typingLock = Promise.resolve();
|
|
27
|
+
async function withTypingLock(fn) {
|
|
28
|
+
const previousLock = typingLock;
|
|
29
|
+
let releaseLock;
|
|
30
|
+
typingLock = new Promise(resolve => { releaseLock = resolve; });
|
|
31
|
+
await previousLock;
|
|
32
|
+
try {
|
|
33
|
+
return await fn();
|
|
34
|
+
} finally {
|
|
35
|
+
releaseLock();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
23
39
|
/**
|
|
24
40
|
* Creates a HumanLocator that wraps a Playwright Locator
|
|
25
41
|
* with human-like cursor movement for actions
|
|
@@ -70,8 +86,8 @@ function createHumanLocator(cursor, locator) {
|
|
|
70
86
|
if (!cursor.config.humanize) {
|
|
71
87
|
return await locator.fill(value, options);
|
|
72
88
|
}
|
|
73
|
-
// Humanize: Move to element,
|
|
74
|
-
await
|
|
89
|
+
// Humanize: Move to element, then fill instantly (Playwright handles focus)
|
|
90
|
+
await cursor._moveToLocator(locator, options);
|
|
75
91
|
return await locator.fill(value, options);
|
|
76
92
|
},
|
|
77
93
|
|
|
@@ -79,19 +95,24 @@ function createHumanLocator(cursor, locator) {
|
|
|
79
95
|
if (!cursor.config.humanize) {
|
|
80
96
|
return await locator.fill(value, options);
|
|
81
97
|
}
|
|
82
|
-
await
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
98
|
+
return await withTypingLock(async () => {
|
|
99
|
+
await this.click(options);
|
|
100
|
+
// Clear field reliably using fill('') before human typing
|
|
101
|
+
await locator.fill('');
|
|
102
|
+
await sleep(randInt(50, 100));
|
|
103
|
+
// Human type with delays
|
|
104
|
+
await cursor._type(value, options);
|
|
105
|
+
});
|
|
87
106
|
},
|
|
88
107
|
|
|
89
108
|
async type(text, options = {}) {
|
|
90
109
|
if (!cursor.config.humanize) {
|
|
91
110
|
return await locator.type(text, options);
|
|
92
111
|
}
|
|
93
|
-
await
|
|
94
|
-
|
|
112
|
+
return await withTypingLock(async () => {
|
|
113
|
+
await this.click(options);
|
|
114
|
+
await cursor._type(text, options);
|
|
115
|
+
});
|
|
95
116
|
},
|
|
96
117
|
|
|
97
118
|
async hover(options = {}) {
|
|
@@ -142,8 +163,11 @@ function createHumanLocator(cursor, locator) {
|
|
|
142
163
|
if (!cursor.config.humanize) {
|
|
143
164
|
return await locator.pressSequentially(text, options);
|
|
144
165
|
}
|
|
145
|
-
await
|
|
146
|
-
|
|
166
|
+
return await withTypingLock(async () => {
|
|
167
|
+
await this.click(options);
|
|
168
|
+
await locator.clear();
|
|
169
|
+
await cursor._type(text, options);
|
|
170
|
+
});
|
|
147
171
|
},
|
|
148
172
|
|
|
149
173
|
// Chainable methods that return new HumanLocators
|