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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arn-browser",
3
- "version": "0.0.6",
3
+ "version": "0.0.7",
4
4
  "description": "A lightweight, browser autmation helper.",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
@@ -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, click, then fill instantly
74
- await this.click(options);
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 this.click(options);
83
- await cursor._page.keyboard.press('Control+A');
84
- await sleep(randInt(50, 100));
85
- // Human type with delays
86
- await cursor._type(value, options);
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 this.click(options);
94
- await cursor._type(text, options);
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 this.click(options);
146
- await cursor._type(text, options);
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