skopix 2.0.19 → 2.0.20
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/cli/commands/agent.js +6 -42
- package/package.json +1 -1
package/cli/commands/agent.js
CHANGED
|
@@ -361,10 +361,10 @@ export async function agentCommand(options) {
|
|
|
361
361
|
await page.waitForTimeout(800);
|
|
362
362
|
|
|
363
363
|
} else if (step.action === 'click') {
|
|
364
|
-
await page.waitForTimeout(100);
|
|
365
364
|
let clicked = false;
|
|
366
365
|
const selectors = [step.stableSelector, step.selector].filter(Boolean).map(sanitiseSelector);
|
|
367
|
-
|
|
366
|
+
// Try position-matched click first (for elements with coordinates)
|
|
367
|
+
if (step.elementX || step.clickX) {
|
|
368
368
|
const tx = step.elementX || step.clickX, ty = step.elementY || step.clickY;
|
|
369
369
|
for (const s of selectors) {
|
|
370
370
|
if (clicked) break;
|
|
@@ -372,7 +372,7 @@ export async function agentCommand(options) {
|
|
|
372
372
|
const count = await page.locator(s).count();
|
|
373
373
|
if (count > 1) {
|
|
374
374
|
let bi = 0, bd = Infinity;
|
|
375
|
-
for (let i = 0; i < count; i++) { try { const box = await page.locator(s).nth(i).boundingBox({ timeout: 2000 }); if (!box) continue; const d = Math.sqrt(Math.pow(box.x
|
|
375
|
+
for (let i = 0; i < count; i++) { try { const box = await page.locator(s).nth(i).boundingBox({ timeout: 2000 }); if (!box) continue; const d = Math.sqrt(Math.pow(box.x+box.width/2-tx,2)+Math.pow(box.y+box.height/2-ty,2)); if (d < bd) { bd=d; bi=i; } } catch {} }
|
|
376
376
|
await page.locator(s).nth(bi).click({ timeout: 5000 }); clicked = true;
|
|
377
377
|
} else if (count === 1) {
|
|
378
378
|
await page.locator(s).first().click({ timeout: 5000 }); clicked = true;
|
|
@@ -380,48 +380,12 @@ export async function agentCommand(options) {
|
|
|
380
380
|
} catch {}
|
|
381
381
|
}
|
|
382
382
|
}
|
|
383
|
+
// Simple click fallback
|
|
383
384
|
if (!clicked) { for (const s of selectors) { if (clicked) break; try { await page.locator(s).first().click({ timeout: 5000 }); clicked = true; } catch {} } }
|
|
384
|
-
|
|
385
|
+
// Force click (for off-screen elements)
|
|
385
386
|
if (!clicked) { for (const s of selectors) { if (clicked) break; try { await page.locator(s).first().click({ force: true, timeout: 5000 }); clicked = true; } catch {} } }
|
|
386
|
-
if (!clicked) {
|
|
387
|
-
// Last resort — JS dispatch for framework-managed elements
|
|
388
|
-
for (const s of selectors) {
|
|
389
|
-
if (clicked) break;
|
|
390
|
-
try {
|
|
391
|
-
await page.locator(s).first().evaluate(el => {
|
|
392
|
-
el.dispatchEvent(new MouseEvent('mousedown', { bubbles: true, cancelable: true }));
|
|
393
|
-
el.dispatchEvent(new MouseEvent('mouseup', { bubbles: true, cancelable: true }));
|
|
394
|
-
el.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true }));
|
|
395
|
-
});
|
|
396
|
-
clicked = true;
|
|
397
|
-
} catch {}
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
387
|
if (!clicked) throw new Error('Could not click: ' + selectors.join(', '));
|
|
401
|
-
|
|
402
|
-
// Special handling for Bootstrap dropdowns — wait for menu to appear
|
|
403
|
-
try {
|
|
404
|
-
const el = page.locator(selectors[0]).first();
|
|
405
|
-
const isDropdown = await el.evaluate(e => e.hasAttribute('data-toggle') && e.getAttribute('data-toggle') === 'dropdown').catch(() => false);
|
|
406
|
-
if (isDropdown) {
|
|
407
|
-
// Try jQuery dropdown toggle first (Bootstrap 3)
|
|
408
|
-
const toggled = await page.evaluate((sel) => {
|
|
409
|
-
try {
|
|
410
|
-
const el = document.querySelector(sel);
|
|
411
|
-
if (el && window.$) { window.$(el).dropdown('toggle'); return true; }
|
|
412
|
-
} catch {}
|
|
413
|
-
return false;
|
|
414
|
-
}, selectors[0]).catch(() => false);
|
|
415
|
-
if (!toggled) {
|
|
416
|
-
// Fallback: dispatch click on the element
|
|
417
|
-
await el.evaluate(e => e.click());
|
|
418
|
-
}
|
|
419
|
-
await page.waitForSelector('.dropdown-menu', { state: 'visible', timeout: 3000 }).catch(() => {});
|
|
420
|
-
await page.waitForTimeout(400);
|
|
421
|
-
}
|
|
422
|
-
} catch {}
|
|
423
|
-
|
|
424
|
-
await page.waitForTimeout(400);
|
|
388
|
+
await page.waitForTimeout(200);
|
|
425
389
|
|
|
426
390
|
} else if (step.action === 'type') {
|
|
427
391
|
await page.locator(sel).first().click({ timeout: 5000 });
|
package/package.json
CHANGED