app-manager-edge-worker 1.2.1 → 1.2.2

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/README.md CHANGED
@@ -203,6 +203,11 @@ Log levels: `[INFO]` · `[SUCCESS]` · `[WARN]` · `[ERROR]` · `[TASK]` (job di
203
203
 
204
204
  ## 📝 Changelog
205
205
 
206
+ ### v1.2.2
207
+ - **Reactive Portal Form & Dynamic Captcha Reveal Compatibility**:
208
+ - Enhanced form input typing in `HITL_SESSION_INIT` and pre-scrape `TYPE` actions (`PREVIEW_PAGE`, `INSPECT_ELEMENT`) to dispatch DOM `input`, `change`, and `blur` events with a simulated `Tab` keypress.
209
+ - Guarantees immediate captcha generation on reactive frontend frameworks (AngularJS, React, Vue, jQuery) requiring input validation/blur before unhiding dynamic captcha elements.
210
+
206
211
  ### v1.2.1
207
212
  - **Smart Form Field & Leaf Control Element Resolution**:
208
213
  - Replaced single-surface `elementFromPoint` with full-stack `elementsFromPoint` coordinate sampling and multi-offset probing.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "app-manager-edge-worker",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
4
4
  "description": "Distributed Scraper Edge Worker for Apps Manager. Run on any local machine, VPS, or Termux Android device to serve browser and HTTP scraping jobs.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/banner.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { createRequire } from "module";
2
2
 
3
3
  const require = createRequire(import.meta.url);
4
- let workerVersion = "1.2.1";
4
+ let workerVersion = "1.2.2";
5
5
  try {
6
6
  const pkg = require("../package.json");
7
7
  if (pkg?.version) workerVersion = pkg.version;
package/src/client.js CHANGED
@@ -18,7 +18,7 @@ import fs from "fs";
18
18
  import { getWhatsAppHandler } from "./handlers/whatsappHandler.js";
19
19
  import { printBanner, logInfo, logSuccess, logWarn, logError, logJob } from "./banner.js";
20
20
 
21
- let workerPkgVersion = "1.2.1";
21
+ let workerPkgVersion = "1.2.2";
22
22
  try {
23
23
  const pkg = JSON.parse(fs.readFileSync(new URL("../package.json", import.meta.url), "utf-8"));
24
24
  if (pkg?.version) workerPkgVersion = pkg.version;
@@ -185,7 +185,18 @@ export async function handleInteractiveSessionInit(payload) {
185
185
  await page.type(input.selector, String(input.value), { delay: input.delayMs || 30 });
186
186
  }
187
187
 
188
- await new Promise((r) => setTimeout(r, 150));
188
+ // Explicitly dispatch input, change, and blur events to trigger AngularJS/React/portal validation listeners
189
+ await page.evaluate((sel) => {
190
+ const el = document.querySelector(sel);
191
+ if (el) {
192
+ el.dispatchEvent(new Event("input", { bubbles: true }));
193
+ el.dispatchEvent(new Event("change", { bubbles: true }));
194
+ el.dispatchEvent(new Event("blur", { bubbles: true }));
195
+ }
196
+ }, input.selector).catch(() => {});
197
+ await page.keyboard.press("Tab").catch(() => {});
198
+
199
+ await new Promise((r) => setTimeout(r, 250));
189
200
  }
190
201
  }
191
202
 
@@ -43,7 +43,16 @@ export async function handlePreviewPage(payload) {
43
43
  await page.click(action.selector);
44
44
  } else if (action.actionType === "TYPE" && action.selector && action.value) {
45
45
  await page.waitForSelector(action.selector, { timeout: 4000 });
46
- await page.type(action.selector, action.value, { delay: 30 });
46
+ await page.type(action.selector, action.value, { delay: action.delayMs || 30 });
47
+ await page.evaluate((sel) => {
48
+ const el = document.querySelector(sel);
49
+ if (el) {
50
+ el.dispatchEvent(new Event("input", { bubbles: true }));
51
+ el.dispatchEvent(new Event("change", { bubbles: true }));
52
+ el.dispatchEvent(new Event("blur", { bubbles: true }));
53
+ }
54
+ }, action.selector).catch(() => {});
55
+ await page.keyboard.press("Tab").catch(() => {});
47
56
  } else if (action.actionType === "SCROLL") {
48
57
  const scrollPixels = parseInt(action.value, 10) || 500;
49
58
  await page.evaluate((px) => window.scrollBy(0, px), scrollPixels);
@@ -150,7 +159,16 @@ export async function handleInspectElement(payload) {
150
159
  await page.click(action.selector);
151
160
  } else if (action.actionType === "TYPE" && action.selector && action.value) {
152
161
  await page.waitForSelector(action.selector, { timeout: 4000 });
153
- await page.type(action.selector, action.value, { delay: 30 });
162
+ await page.type(action.selector, action.value, { delay: action.delayMs || 30 });
163
+ await page.evaluate((sel) => {
164
+ const el = document.querySelector(sel);
165
+ if (el) {
166
+ el.dispatchEvent(new Event("input", { bubbles: true }));
167
+ el.dispatchEvent(new Event("change", { bubbles: true }));
168
+ el.dispatchEvent(new Event("blur", { bubbles: true }));
169
+ }
170
+ }, action.selector).catch(() => {});
171
+ await page.keyboard.press("Tab").catch(() => {});
154
172
  } else if (action.actionType === "SCROLL") {
155
173
  const scrollPixels = parseInt(action.value, 10) || 500;
156
174
  await page.evaluate((px) => window.scrollBy(0, px), scrollPixels);