skopix 2.0.18 → 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 +7 -32
- 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(200);
|
|
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,45 +372,20 @@ 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
|
|
376
|
-
await page.locator(s).nth(bi).scrollIntoViewIfNeeded({ timeout: 3000 }).catch(() => {});
|
|
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 {} }
|
|
377
376
|
await page.locator(s).nth(bi).click({ timeout: 5000 }); clicked = true;
|
|
378
377
|
} else if (count === 1) {
|
|
379
|
-
await page.locator(s).first().scrollIntoViewIfNeeded({ timeout: 3000 }).catch(() => {});
|
|
380
378
|
await page.locator(s).first().click({ timeout: 5000 }); clicked = true;
|
|
381
379
|
}
|
|
382
380
|
} catch {}
|
|
383
381
|
}
|
|
384
382
|
}
|
|
385
|
-
|
|
383
|
+
// Simple click fallback
|
|
384
|
+
if (!clicked) { for (const s of selectors) { if (clicked) break; try { await page.locator(s).first().click({ timeout: 5000 }); clicked = true; } catch {} } }
|
|
385
|
+
// Force click (for off-screen elements)
|
|
386
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 {} } }
|
|
387
|
-
if (!clicked) {
|
|
388
|
-
// Last resort — JS dispatch for framework-managed elements
|
|
389
|
-
for (const s of selectors) {
|
|
390
|
-
if (clicked) break;
|
|
391
|
-
try {
|
|
392
|
-
await page.locator(s).first().evaluate(el => {
|
|
393
|
-
el.dispatchEvent(new MouseEvent('mousedown', { bubbles: true, cancelable: true }));
|
|
394
|
-
el.dispatchEvent(new MouseEvent('mouseup', { bubbles: true, cancelable: true }));
|
|
395
|
-
el.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true }));
|
|
396
|
-
});
|
|
397
|
-
clicked = true;
|
|
398
|
-
} catch {}
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
387
|
if (!clicked) throw new Error('Could not click: ' + selectors.join(', '));
|
|
402
|
-
|
|
403
|
-
// Special handling for Bootstrap dropdowns — wait for menu to appear
|
|
404
|
-
try {
|
|
405
|
-
const el = await page.locator(selectors[0]).first();
|
|
406
|
-
const isDropdown = await el.evaluate(e => e.hasAttribute('data-toggle') && e.getAttribute('data-toggle') === 'dropdown').catch(() => false);
|
|
407
|
-
if (isDropdown) {
|
|
408
|
-
await page.waitForSelector('.dropdown-menu:visible, .dropdown.open .dropdown-menu', { timeout: 3000 }).catch(() => {});
|
|
409
|
-
await page.waitForTimeout(300);
|
|
410
|
-
}
|
|
411
|
-
} catch {}
|
|
412
|
-
|
|
413
|
-
await page.waitForTimeout(400);
|
|
388
|
+
await page.waitForTimeout(200);
|
|
414
389
|
|
|
415
390
|
} else if (step.action === 'type') {
|
|
416
391
|
await page.locator(sel).first().click({ timeout: 5000 });
|
package/package.json
CHANGED