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 CHANGED
@@ -201,7 +201,11 @@ Log levels: `[INFO]` · `[SUCCESS]` · `[WARN]` · `[ERROR]` · `[TASK]` (job di
201
201
 
202
202
  ---
203
203
 
204
- ## 📝 Changelog
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.4",
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
@@ -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.4";
4
+ let workerVersion = "1.2.5";
5
5
  try {
6
6
  const pkg = require("../package.json");
7
7
  if (pkg?.version) workerVersion = pkg.version;
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.4";
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
- await page.waitForSelector(refreshSelector, { timeout: 3000 });
292
- await page.click(refreshSelector);
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