app-manager-edge-worker 1.2.4 → 1.2.5
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 +5 -1
- package/package.json +1 -1
- package/src/banner.js +1 -1
- package/src/client.js +1 -1
- package/src/handlers/interactiveHandler.js +68 -7
package/README.md
CHANGED
|
@@ -201,7 +201,11 @@ Log levels: `[INFO]` · `[SUCCESS]` · `[WARN]` · `[ERROR]` · `[TASK]` (job di
|
|
|
201
201
|
|
|
202
202
|
---
|
|
203
203
|
|
|
204
|
-
|
|
204
|
+
### v1.2.5
|
|
205
|
+
- **Interactive Session Visual Inspector Sync & Robust Captcha Refresh**:
|
|
206
|
+
- `HITL_SESSION_INIT` now captures and returns full-page `pageScreenshotBase64`, dimensions, and title after typing initial form inputs, keeping the Visual Element Inspector synchronized with the active session.
|
|
207
|
+
- Enhanced `HITL_SESSION_REFRESH` with multi-selector fallback candidates (`button[ng-click*="refreshCaptcha"]`, `button[ng-click*="captcha"]`, `#reloadCaptcha`, etc.) ensuring reliable refresh on AngularJS and custom portal architectures.
|
|
208
|
+
- Captures and returns updated `pageScreenshotBase64` upon captcha refresh to keep inspect canvas up to date.
|
|
205
209
|
|
|
206
210
|
### v1.2.4
|
|
207
211
|
- **Preserved Live Inspection & Field Extraction on Results Pages**:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "app-manager-edge-worker",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.5",
|
|
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
package/src/client.js
CHANGED
|
@@ -19,7 +19,7 @@ import fs from "fs";
|
|
|
19
19
|
import { getWhatsAppHandler } from "./handlers/whatsappHandler.js";
|
|
20
20
|
import { printBanner, logInfo, logSuccess, logWarn, logError, logJob } from "./banner.js";
|
|
21
21
|
|
|
22
|
-
let workerPkgVersion = "1.2.
|
|
22
|
+
let workerPkgVersion = "1.2.5";
|
|
23
23
|
try {
|
|
24
24
|
const pkg = JSON.parse(fs.readFileSync(new URL("../package.json", import.meta.url), "utf-8"));
|
|
25
25
|
if (pkg?.version) workerPkgVersion = pkg.version;
|
|
@@ -223,6 +223,25 @@ export async function handleInteractiveSessionInit(payload) {
|
|
|
223
223
|
});
|
|
224
224
|
const imageBase64 = Buffer.from(screenshotBuffer).toString("base64");
|
|
225
225
|
|
|
226
|
+
// Settle briefly for form state & portal validation UI
|
|
227
|
+
await new Promise((r) => setTimeout(r, 400));
|
|
228
|
+
|
|
229
|
+
// Capture full-page screenshot showing the filled inputs and revealed captcha
|
|
230
|
+
const pageScreenshotBuffer = await page.screenshot({
|
|
231
|
+
encoding: "binary",
|
|
232
|
+
fullPage: false,
|
|
233
|
+
type: "jpeg",
|
|
234
|
+
quality: 85,
|
|
235
|
+
});
|
|
236
|
+
const pageScreenshotBase64 = `data:image/jpeg;base64,${Buffer.from(pageScreenshotBuffer).toString("base64")}`;
|
|
237
|
+
const title = (await page.title().catch(() => "")) || "Interactive Portal Session";
|
|
238
|
+
const dimensions = await page
|
|
239
|
+
.evaluate(() => ({
|
|
240
|
+
width: document.documentElement.scrollWidth || window.innerWidth,
|
|
241
|
+
height: document.documentElement.scrollHeight || window.innerHeight,
|
|
242
|
+
}))
|
|
243
|
+
.catch(() => ({ width: 1366, height: 900 }));
|
|
244
|
+
|
|
226
245
|
const sessionTtlSeconds = captchaConfig.sessionTimeoutSeconds || 90;
|
|
227
246
|
|
|
228
247
|
// Set auto-purge timer to prevent resource leaks
|
|
@@ -244,6 +263,9 @@ export async function handleInteractiveSessionInit(payload) {
|
|
|
244
263
|
return {
|
|
245
264
|
sessionId,
|
|
246
265
|
imageBase64: `data:image/png;base64,${imageBase64}`,
|
|
266
|
+
pageScreenshotBase64,
|
|
267
|
+
dimensions,
|
|
268
|
+
title,
|
|
247
269
|
expiresInSeconds: sessionTtlSeconds,
|
|
248
270
|
};
|
|
249
271
|
} catch (err) {
|
|
@@ -269,10 +291,6 @@ export async function handleInteractiveSessionRefresh(payload) {
|
|
|
269
291
|
const imageSelector = cfg.imageSelector || "img[src*='captcha'], #imgCaptcha";
|
|
270
292
|
const refreshSelector = cfg.refreshSelector;
|
|
271
293
|
|
|
272
|
-
if (!refreshSelector) {
|
|
273
|
-
throw new Error("refreshSelector is not configured for this captcha");
|
|
274
|
-
}
|
|
275
|
-
|
|
276
294
|
// 1. Snapshot current image hash and src attribute
|
|
277
295
|
const oldEl = await page.$(imageSelector);
|
|
278
296
|
if (!oldEl) {
|
|
@@ -287,9 +305,41 @@ export async function handleInteractiveSessionRefresh(payload) {
|
|
|
287
305
|
return el ? el.getAttribute("src") : null;
|
|
288
306
|
}, imageSelector);
|
|
289
307
|
|
|
290
|
-
// 2. Click the reload button
|
|
291
|
-
|
|
292
|
-
|
|
308
|
+
// 2. Click the reload button with robust candidate fallbacks
|
|
309
|
+
const candidateSelectors = [
|
|
310
|
+
refreshSelector,
|
|
311
|
+
"button[ng-click*='refreshCaptcha' i]",
|
|
312
|
+
"button[ng-click*='captcha' i]",
|
|
313
|
+
"*[ng-click*='refreshCaptcha' i]",
|
|
314
|
+
"*[ng-click*='captcha' i]",
|
|
315
|
+
"#reloadCaptcha",
|
|
316
|
+
"#refreshCaptcha",
|
|
317
|
+
"a[title*='refresh' i]",
|
|
318
|
+
"button[title*='refresh' i]",
|
|
319
|
+
"a[title*='reload' i]",
|
|
320
|
+
"button[title*='reload' i]",
|
|
321
|
+
".captcha-refresh",
|
|
322
|
+
".reload-captcha",
|
|
323
|
+
".glyphicon-refresh",
|
|
324
|
+
"i.fa-refresh",
|
|
325
|
+
"i.fa-arrows-rotate",
|
|
326
|
+
].filter(Boolean);
|
|
327
|
+
|
|
328
|
+
let clicked = false;
|
|
329
|
+
for (const sel of candidateSelectors) {
|
|
330
|
+
try {
|
|
331
|
+
const btn = await page.$(sel);
|
|
332
|
+
if (btn) {
|
|
333
|
+
await btn.click();
|
|
334
|
+
clicked = true;
|
|
335
|
+
break;
|
|
336
|
+
}
|
|
337
|
+
} catch (_) {}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
if (!clicked) {
|
|
341
|
+
throw new Error(`Captcha refresh button not found on page (tried: ${refreshSelector || "standard reload selectors"})`);
|
|
342
|
+
}
|
|
293
343
|
|
|
294
344
|
// 3. Wait for src attribute change first
|
|
295
345
|
await page
|
|
@@ -326,9 +376,20 @@ export async function handleInteractiveSessionRefresh(payload) {
|
|
|
326
376
|
}
|
|
327
377
|
|
|
328
378
|
const imageBase64 = Buffer.from(newBuffer).toString("base64");
|
|
379
|
+
|
|
380
|
+
// Capture updated full page screenshot showing new captcha
|
|
381
|
+
const pageScreenshotBuffer = await page.screenshot({
|
|
382
|
+
encoding: "binary",
|
|
383
|
+
fullPage: false,
|
|
384
|
+
type: "jpeg",
|
|
385
|
+
quality: 85,
|
|
386
|
+
});
|
|
387
|
+
const pageScreenshotBase64 = `data:image/jpeg;base64,${Buffer.from(pageScreenshotBuffer).toString("base64")}`;
|
|
388
|
+
|
|
329
389
|
return {
|
|
330
390
|
sessionId,
|
|
331
391
|
imageBase64: `data:image/png;base64,${imageBase64}`,
|
|
392
|
+
pageScreenshotBase64,
|
|
332
393
|
};
|
|
333
394
|
}
|
|
334
395
|
|