@cutleryapp/agent 1.0.8 → 1.0.10

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/dist/cli.js CHANGED
@@ -417,7 +417,24 @@ function runConnect(opts) {
417
417
  }
418
418
  if (message.type === "registered") {
419
419
  registered = true;
420
- log(chalk_1.default.green(`✓ Registration confirmed by server`));
420
+ // Render the resolved plan / cap / utilisation when the server
421
+ // provides them (added in server.ts >= today). Older servers send
422
+ // only { type, agentName, timestamp } — the optional chains below
423
+ // make the line gracefully degrade to the previous one-liner.
424
+ const planName = message?.plan?.name;
425
+ const cap = typeof message?.cap === "number" ? message.cap : null;
426
+ const used = typeof message?.used === "number" ? message.used : null;
427
+ if (planName && cap !== null && used !== null) {
428
+ const fraction = cap === -1 ? "∞ agents allowed" : `${used}/${cap} agents used`;
429
+ log(chalk_1.default.green(`✓ Registration confirmed by server`) +
430
+ chalk_1.default.gray(` · ${planName} plan · ${fraction}`));
431
+ if (cap !== -1 && used >= cap) {
432
+ log(chalk_1.default.yellow(` ⚠ You're at your plan's concurrent-agent cap. Disconnect another agent or upgrade at ${message.upgradeUrl ?? "/pricing"}.`));
433
+ }
434
+ }
435
+ else {
436
+ log(chalk_1.default.green(`✓ Registration confirmed by server`));
437
+ }
421
438
  opts.onRegistered?.();
422
439
  }
423
440
  else if (message.type === "evicted") {
@@ -77,11 +77,16 @@ class TestExecutor {
77
77
  }
78
78
  else if (lower.includes("click")) {
79
79
  const labelMatch = raw.match(/click\s+(?:on\s+)?(?:the\s+)?"?([^"]+?)"?\s*(?:button|link|tab)?$/i);
80
- const label = labelMatch?.[1]?.trim();
80
+ let label = labelMatch?.[1]?.trim();
81
81
  if (label) {
82
- const nameRe = new RegExp(label, 'i');
83
- // Use a short probe timeout so fallbacks are fast
84
- const clicked = await tryClick(page, nameRe, label);
82
+ // Split "Add to cart under Sauce Labs Bike Light product" into target + scope
83
+ const scopeMatch = label.match(/^(.+?)\s+(?:under|inside|within|in the)\s+(.+)$/i);
84
+ const target = scopeMatch ? scopeMatch[1].trim() : label;
85
+ const scope = scopeMatch ? scopeMatch[2].trim() : null;
86
+ const nameRe = new RegExp(escapeRegex(target), 'i');
87
+ const clicked = scope
88
+ ? await tryClickScoped(page, nameRe, target, scope)
89
+ : await tryClick(page, nameRe, target);
85
90
  if (!clicked)
86
91
  throw new Error(`Could not find clickable element: "${label}"`);
87
92
  }
@@ -216,6 +221,26 @@ async function tryClick(page, nameRe, label) {
216
221
  }
217
222
  return false;
218
223
  }
224
+ async function tryClickScoped(page, nameRe, target, scope) {
225
+ const FAST = 3000;
226
+ // Find a container that contains the scope text, then click the target inside it
227
+ const strategies = [
228
+ () => page.locator(`:has-text("${scope}")`).last().getByRole('button', { name: nameRe }).first().click({ timeout: FAST }),
229
+ () => page.locator(`:has-text("${scope}")`).last().getByRole('link', { name: nameRe }).first().click({ timeout: FAST }),
230
+ () => page.locator(`:has-text("${scope}")`).last().getByText(nameRe).first().click({ timeout: FAST }),
231
+ // Fallback: ignore scope and click anywhere
232
+ () => page.getByRole('button', { name: nameRe }).first().click({ timeout: FAST }),
233
+ () => page.getByText(nameRe).first().click({ timeout: FAST }),
234
+ ];
235
+ for (const fn of strategies) {
236
+ try {
237
+ await fn();
238
+ return true;
239
+ }
240
+ catch { /* try next */ }
241
+ }
242
+ return false;
243
+ }
219
244
  async function tryFill(page, label, value) {
220
245
  const FAST = 1500;
221
246
  const labelRe = new RegExp(escapeRegex(label), "i");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cutleryapp/agent",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "Local agent that connects your machine to the Cutlery QA platform and runs UI tests via Playwright",
5
5
  "main": "dist/cli.js",
6
6
  "bin": {