common-qa-mcp 0.7.1 → 0.8.1

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.
Files changed (39) hide show
  1. package/dist/adapters/remoteMcp/adapter.js +1 -1
  2. package/dist/adapters/simplifyqa/adapter.d.ts +24 -0
  3. package/dist/adapters/simplifyqa/adapter.d.ts.map +1 -1
  4. package/dist/adapters/simplifyqa/adapter.js +370 -28
  5. package/dist/adapters/simplifyqa/adapter.js.map +1 -1
  6. package/dist/adapters/simplifyqa/mapper.d.ts +2 -2
  7. package/dist/adapters/simplifyqa/mapper.d.ts.map +1 -1
  8. package/dist/adapters/simplifyqa/mapper.js +257 -64
  9. package/dist/adapters/simplifyqa/mapper.js.map +1 -1
  10. package/dist/domain/types.d.ts +36 -6
  11. package/dist/domain/types.d.ts.map +1 -1
  12. package/dist/domain/validate.d.ts.map +1 -1
  13. package/dist/domain/validate.js +5 -1
  14. package/dist/domain/validate.js.map +1 -1
  15. package/dist/initAgents.d.ts.map +1 -1
  16. package/dist/initAgents.js +18 -11
  17. package/dist/initAgents.js.map +1 -1
  18. package/dist/server.d.ts.map +1 -1
  19. package/dist/server.js +6 -1
  20. package/dist/server.js.map +1 -1
  21. package/dist/tools/recording.tools.d.ts.map +1 -1
  22. package/dist/tools/recording.tools.js +12 -1
  23. package/dist/tools/recording.tools.js.map +1 -1
  24. package/dist/tools/run.tools.d.ts +4 -0
  25. package/dist/tools/run.tools.d.ts.map +1 -1
  26. package/dist/tools/run.tools.js +228 -116
  27. package/dist/tools/run.tools.js.map +1 -1
  28. package/dist/tools/schemas.d.ts +41 -49
  29. package/dist/tools/schemas.d.ts.map +1 -1
  30. package/dist/tools/schemas.js +19 -1
  31. package/dist/tools/schemas.js.map +1 -1
  32. package/dist/tools/tcEditPublisher.d.ts +20 -0
  33. package/dist/tools/tcEditPublisher.d.ts.map +1 -0
  34. package/dist/tools/tcEditPublisher.js +46 -0
  35. package/dist/tools/tcEditPublisher.js.map +1 -0
  36. package/dist/tools/testcase.tools.d.ts.map +1 -1
  37. package/dist/tools/testcase.tools.js +314 -12
  38. package/dist/tools/testcase.tools.js.map +1 -1
  39. package/package.json +1 -1
@@ -38,7 +38,7 @@ export class RemoteMcpAdapter {
38
38
  async client() {
39
39
  if (!this.clientPromise) {
40
40
  this.clientPromise = (async () => {
41
- const client = new Client({ name: 'common-qa-mcp', version: '0.7.1' });
41
+ const client = new Client({ name: 'common-qa-mcp', version: '0.8.1' });
42
42
  // The `as Transport` cast bridges exactOptionalPropertyTypes: StreamableHTTPClientTransport
43
43
  // implements Transport, but the SDK's own .d.ts (built without EOPT) leaves its optional
44
44
  // callbacks (onclose?/onerror?/onmessage?) without `| undefined`, which this project's EOPT
@@ -25,6 +25,15 @@ export declare class SimplifyQaAdapter {
25
25
  private backlogDefaultsCache;
26
26
  constructor(cfg: ConnectedQaConfig, transport?: SimplifyQaTransport);
27
27
  private headers;
28
+ /** Public session context for MCP viewer/recorder windows that need to authenticate the sqa-ui
29
+ * they load. cfg itself stays private; this getter is the one seam through which tc_edit_open
30
+ * and record tools can forward token + baseUrl + projectId to Electron without asking the LLM. */
31
+ getSessionContext(): {
32
+ token: string;
33
+ baseUrl: string;
34
+ projectId?: string;
35
+ userId?: string;
36
+ };
28
37
  private requireProjectId;
29
38
  private searchBody;
30
39
  /** Validates baseUrl + token + (optional) project by running the same list_projects search the
@@ -320,6 +329,9 @@ export declare class SimplifyQaAdapter {
320
329
  * Keyed by `${technologyType}::${lowerCaseName}` so the same action name across two techs
321
330
  * (e.g. "click" for WEB + ANDROID) resolves to the right numeric id. */
322
331
  private actionCatalogCache;
332
+ /** Populated by actionCatalog() on each fetch. Surfaced in resolveAutomationSteps error messages
333
+ * so a user hitting "no SQA action named X" can see what the fetch actually returned. */
334
+ private actionCatalogFetchDiag;
323
335
  private actionCatalog;
324
336
  private resolveObjectId;
325
337
  /** For every automation step, resolve `actionId` (from action name + technology) and
@@ -330,6 +342,10 @@ export declare class SimplifyQaAdapter {
330
342
  * collation strength:2, so a case-sensitive search here misses params stored under different
331
343
  * casing — the next POST then trips "Duplicate Name Error". Returns null when not found. */
332
344
  private findParameterId;
345
+ /** Case-insensitive project-scoped lookup of an existing object by `disname` (the UI's Name).
346
+ * Lets tc_draft_update pass `objectRef:{name}` for an already-defined object without also
347
+ * supplying locators — mirrors what a user picking from the Object Repository dropdown does. */
348
+ private findObjectIdByName;
333
349
  private getOrCreateParameter;
334
350
  createSuite(s: Suite): Promise<SavedRef>;
335
351
  /** Fetch raw suite, apply add/remove/reorder ops in memory, then PUT the whole doc back with a
@@ -469,6 +485,14 @@ export declare class SimplifyQaAdapter {
469
485
  private lookupProjectName;
470
486
  startRun(target: RunTarget, opts: RunOptions): Promise<RunRef>;
471
487
  stopRun(runId: string): Promise<void>;
488
+ /** SUITE dispatch. Mirrors `startRun` above (which handles TC) — same `/exec/execution` endpoint,
489
+ * same LOCAL-agent fast-fail, same project-name / environment resolution. What differs is on the
490
+ * wire: `type: 'SUITE'`, `executionType` sourced from `suite.suiteType`, `mode` defaulting to
491
+ * `suite.executionType`, a populated `globalConfiguration` block, and one `executionItems` entry
492
+ * PER member — each carrying the suite row's persisted `versionId` / `stepId` / `platform` / `seq`
493
+ * (NOT a re-derived random step id). See sqa-ui execution-popup-modal.component.ts:621-1105 SU
494
+ * branch for the authoritative UI builder; every field below traces back to a line there. */
495
+ private startSuiteRun;
472
496
  /** GET the agent /mcp with a 1s timeout. Any HTTP response (incl. 4xx from an MCP server rejecting
473
497
  * a naked GET) proves the process is up; connect/DNS/timeout errors mean it is down. Replaces
474
498
  * the customer-wide `machineRegistration` round trip when all we needed was "is LOCAL possible?". */
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/simplifyqa/adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/simplifyqa/adapter.ts"],"names":[],"mappings":"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"}
@@ -7,12 +7,15 @@ function mapRunState(s) {
7
7
  switch (s.toUpperCase()) {
8
8
  case 'PASSED': return 'passed';
9
9
  case 'FAILED': return 'failed';
10
+ case 'SKIPPED': return 'skipped';
11
+ case 'NOTEXECUTED': return 'notExecuted';
10
12
  case 'STOPPED': return 'stopped';
13
+ case 'ERROR': return 'error';
11
14
  case 'RUNNING':
12
15
  case 'INPROGRESS': return 'running';
13
- case 'QUEUED':
14
- case 'NOTEXECUTED': return 'queued';
15
- default: return 'queued';
16
+ case 'QUEUED': return 'queued';
17
+ case '': return 'queued'; // no status yet assigned — genuinely not started
18
+ default: return 'error';
16
19
  }
17
20
  }
18
21
  /** Formula names round-trip with parens on ("FIRST_NAME()") from the backend and sometimes with a full
@@ -224,6 +227,9 @@ export class SimplifyQaAdapter {
224
227
  * Keyed by `${technologyType}::${lowerCaseName}` so the same action name across two techs
225
228
  * (e.g. "click" for WEB + ANDROID) resolves to the right numeric id. */
226
229
  this.actionCatalogCache = null;
230
+ /** Populated by actionCatalog() on each fetch. Surfaced in resolveAutomationSteps error messages
231
+ * so a user hitting "no SQA action named X" can see what the fetch actually returned. */
232
+ this.actionCatalogFetchDiag = 'never fetched';
227
233
  // ---------------------------------------------------------------------- Objects (read + delete)
228
234
  // list/create/delete now go direct REST (same /tm/object base getObject already uses), mirroring
229
235
  // the testcase/suite search + soft-delete convention.
@@ -251,6 +257,18 @@ export class SimplifyQaAdapter {
251
257
  ...(this.cfg.projectId ? { 'x-project-id': this.cfg.projectId } : {}),
252
258
  };
253
259
  }
260
+ /** Public session context for MCP viewer/recorder windows that need to authenticate the sqa-ui
261
+ * they load. cfg itself stays private; this getter is the one seam through which tc_edit_open
262
+ * and record tools can forward token + baseUrl + projectId to Electron without asking the LLM. */
263
+ getSessionContext() {
264
+ // Constructor already rejected missing baseUrl (~line 265), so `!` is safe here.
265
+ return {
266
+ token: this.cfg.token,
267
+ baseUrl: this.cfg.baseUrl,
268
+ ...(this.cfg.projectId ? { projectId: this.cfg.projectId } : {}),
269
+ ...(this.cfg.userId ? { userId: this.cfg.userId } : {}),
270
+ };
271
+ }
254
272
  requireProjectId() {
255
273
  if (!this.cfg.projectId)
256
274
  throw new Error(NEEDS_PROJECT);
@@ -467,7 +485,11 @@ export class SimplifyQaAdapter {
467
485
  // Overlay currentVersionId to the resolved one and flip isCurrent flags on versions[]. Apply
468
486
  // even when rows are empty — a caller who pinned versionId still expects the header + versions[]
469
487
  // to reflect that choice (a legitimately-empty version shouldn't fall back to the TC's default).
470
- const resolvedVer = versionId ?? tc.currentVersionId;
488
+ // ponytail: mirror fetchStepsCollection's resolution ladder — the raw doc from /tm/testcase/getById
489
+ // does NOT include a top-level versionId, only a `versions[]` array. Without the versions[0] fallback,
490
+ // tc.currentVersionId stays undefined → tc_save emits versionsDetails.id:"" → backend mints a
491
+ // phantom version and orphans the saved steps.
492
+ const resolvedVer = versionId ?? tc.currentVersionId ?? (Array.isArray(tc.versions) ? tc.versions[0]?.id : undefined);
471
493
  const patched = { ...withSteps, ...(resolvedVer ? { currentVersionId: resolvedVer } : {}) };
472
494
  if (resolvedVer && patched.versions?.length) {
473
495
  patched.versions = patched.versions.map((v) => ({ ...v, isCurrent: v.id === resolvedVer }));
@@ -2314,8 +2336,10 @@ export class SimplifyQaAdapter {
2314
2336
  return this.actionCatalogCache;
2315
2337
  const projectId = this.requireProjectId();
2316
2338
  this.actionCatalogCache = (async () => {
2317
- // `projectId in [0, projectId]` — 0 is the customer-wide default catalog, projectId is the
2318
- // per-project overrides layered on top. Same filter the SQA UI uses (steps.model.ts:59).
2339
+ // Use the SAME filter the SQA UI uses (mobile-app/angular/.../steps.model.ts:59):
2340
+ // {projectId: {$in:[0, projectId]}}. Removing it caused /tm/action/search to return 0 rows in
2341
+ // practice — the backend endpoint apparently requires it as-is despite server-side resolvers
2342
+ // using only {customerId, deleted:false}. Keep the UI's filter to stay compatible.
2319
2343
  const body = {
2320
2344
  searchFields: [
2321
2345
  { column: 'deleted', value: false },
@@ -2327,12 +2351,25 @@ export class SimplifyQaAdapter {
2327
2351
  };
2328
2352
  const raw = await this.http.postJson('/tm/action/search', body);
2329
2353
  const rows = pickArray(raw, 'data', 'content', 'actions');
2354
+ // Capture diagnostic snapshot so downstream errors can surface WHY the fetch returned 0 rows.
2355
+ try {
2356
+ const topKeys = raw && typeof raw === 'object' ? Object.keys(raw).slice(0, 10).join(',') : typeof raw;
2357
+ const totalCount = raw?.totalCount ?? raw?.total ?? 'n/a';
2358
+ const firstRowKeys = rows[0] && typeof rows[0] === 'object' ? Object.keys(rows[0]).slice(0, 12).join(',') : 'no-rows';
2359
+ this.actionCatalogFetchDiag = `rows.length=${rows.length} totalCount=${totalCount} raw.keys=[${topKeys}] firstRowKeys=[${firstRowKeys}] projectId=${projectId}`;
2360
+ }
2361
+ catch { /* diagnostic must not throw */ }
2330
2362
  const map = new Map();
2331
2363
  for (const row of rows) {
2332
2364
  const idStr = str(row, 'id', '_id', 'actionId');
2333
2365
  const name = str(row, 'name');
2334
- const tech = str(row, 'technology');
2335
- if (!idStr || !name || !tech)
2366
+ // Diagnostic proved action rows have NO top-level `technology` field
2367
+ // (firstRowKeys=[id,name,objectRequired,objectTemplate]). SQA UI derives tech by looking up
2368
+ // objectTemplate → object_templates.name — we don't (would need a second fetch). Just require
2369
+ // id; drop the tech-in-key and let names collide across techs. Round-trip lookups (by numeric
2370
+ // id) are unaffected. Model-authored by-name lookups get whichever action registered last for
2371
+ // that name — good enough until cross-tech name collisions actually bite.
2372
+ if (!idStr)
2336
2373
  continue;
2337
2374
  const id = Number.parseInt(idStr, 10);
2338
2375
  if (!Number.isFinite(id))
@@ -2342,14 +2379,17 @@ export class SimplifyQaAdapter {
2342
2379
  const objectTemplate = typeof otRaw === 'number' ? otRaw
2343
2380
  : typeof otRaw === 'string' && /^\d+$/.test(otRaw) ? Number.parseInt(otRaw, 10)
2344
2381
  : undefined;
2345
- // Prefer the higher-priority project override when the same (tech, name) has both a
2346
- // default and a project row: last write wins if we sort defaults first. Backend returns
2347
- // whichever ordering; we resolve determinism by preferring a non-zero projectId row.
2348
- const key = `${tech.toUpperCase()}::${name.toLowerCase()}`;
2349
- const prev = map.get(key);
2350
- const isProjectOverride = typeof row?.projectId === 'number' && row.projectId !== 0;
2351
- if (!prev || isProjectOverride)
2352
- map.set(key, { id, objectRequired, objectTemplate });
2382
+ const entry = { id, objectRequired, ...(objectTemplate !== undefined ? { objectTemplate } : {}) };
2383
+ // Name-only key for by-name lookups (may collide across techs — see comment above).
2384
+ if (name) {
2385
+ const key = name.toLowerCase();
2386
+ const prev = map.get(key);
2387
+ const isProjectOverride = typeof row?.projectId === 'number' && row.projectId !== 0;
2388
+ if (!prev || isProjectOverride)
2389
+ map.set(key, entry);
2390
+ }
2391
+ // Id-keyed entry so numeric-actionType round-trip lookups are O(1) instead of a scan.
2392
+ map.set(`id::${id}`, entry);
2353
2393
  }
2354
2394
  return map;
2355
2395
  })().catch((e) => { this.actionCatalogCache = null; throw e; });
@@ -2406,27 +2446,106 @@ export class SimplifyQaAdapter {
2406
2446
  async resolveAutomationSteps(projectId, moduleId, tc) {
2407
2447
  const catalog = await this.actionCatalog();
2408
2448
  const steps = Array.isArray(tc.steps) ? tc.steps : [];
2449
+ // ponytail: objectId can be `undefined` here to mean "don't emit — preserve the backend value".
2450
+ // Used when an existing step (sourceId set) has no round-trip objectRef.id, e.g. because it was
2451
+ // recorded before objectRequired was flipped on the action. Emitting null would $set-clobber the DB.
2452
+ // actionId also nullable for control-flow / function / switch / function_end — those steps don't
2453
+ // have an action; buildAutomationPayload omits action/object emit when actionId is null.
2409
2454
  const out = [];
2410
2455
  for (let i = 0; i < steps.length; i++) {
2411
2456
  const s = steps[i];
2457
+ // ponytail: control-flow / function / switch / function_end steps have no action to resolve.
2458
+ // Push a null-actionId slot so index alignment survives; mapper checks and skips action/object
2459
+ // emit for these. Without this, IF/FOR/WHILE/FUNCTION steps throw "missing actionType" on save.
2460
+ if (s.stepType === 'control_flow' || s.stepType === 'function' || s.stepType === 'function_end' || s.stepType === 'switch' || s.stepType === 'manual') {
2461
+ out.push({ actionId: null, objectId: null });
2462
+ continue;
2463
+ }
2412
2464
  const tech = (TECH_BY_STEPTYPE[s.stepType] ?? deriveTcType(tc)).toUpperCase();
2413
2465
  const name = (s.actionType ?? '').trim();
2414
2466
  if (!name) {
2415
2467
  throw new Error(`Automation step ${i + 1} ("${s.description}"): missing actionType — the neutral Step.actionType must name an SQA action (e.g. "Click", "Type Text", "Launch Application").`);
2416
2468
  }
2417
- const meta = catalog.get(`${tech}::${name.toLowerCase()}`);
2469
+ // Round-trip support: a TC hydrated via getTestCase carries actionType = String(actionId), so
2470
+ // on save we may see a numeric string here. Catalog is dual-keyed: `id::N` for round-trip,
2471
+ // `<lowercase name>` for model-authored by-name lookups. Tech is not in the key because
2472
+ // action rows have no top-level `technology` field (SQA UI resolves via objectTemplate lookup).
2473
+ const isNumericId = /^\d+$/.test(name);
2474
+ let meta = isNumericId
2475
+ ? catalog.get(`id::${Number.parseInt(name, 10)}`)
2476
+ : catalog.get(name.toLowerCase());
2477
+ // Fallback: if the by-id scan misses (action created in a different project and thus not in
2478
+ // the UI's projectId-filtered catalog), fetch it directly via GET /tm/action/:id. Only tries
2479
+ // for numeric-id lookups — model-authored name lookups have no id to fetch.
2480
+ let fallbackDiag = '';
2481
+ if (!meta && isNumericId) {
2482
+ try {
2483
+ const raw = await this.http.getJson(`/tm/action/${Number.parseInt(name, 10)}`);
2484
+ const row = raw?.data && typeof raw.data === 'object' ? raw.data
2485
+ : Array.isArray(raw?.data) ? raw.data[0]
2486
+ : Array.isArray(raw) ? raw[0]
2487
+ : raw;
2488
+ const idStr = str(row, 'id', '_id', 'actionId');
2489
+ // ponytail: no `technology` gate. Catalog builder proved action rows have no top-level
2490
+ // technology field (see comment at ~line 2357); requiring it here made the fallback
2491
+ // never succeed — every cross-project action id threw "no SQA action named X".
2492
+ if (idStr) {
2493
+ const otRaw = row?.objectTemplate;
2494
+ const objectTemplate = typeof otRaw === 'number' ? otRaw
2495
+ : typeof otRaw === 'string' && /^\d+$/.test(otRaw) ? Number.parseInt(otRaw, 10)
2496
+ : undefined;
2497
+ meta = {
2498
+ id: Number.parseInt(idStr, 10),
2499
+ objectRequired: row?.objectRequired === true,
2500
+ ...(objectTemplate !== undefined ? { objectTemplate } : {}),
2501
+ };
2502
+ }
2503
+ else {
2504
+ fallbackDiag = ` [GET /tm/action/${name} returned no usable row (idStr=null). Raw keys: ${row && typeof row === 'object' ? Object.keys(row).join(',') : typeof row}]`;
2505
+ }
2506
+ }
2507
+ catch (e) {
2508
+ fallbackDiag = ` [GET /tm/action/${name} failed: ${e.message}]`;
2509
+ }
2510
+ }
2418
2511
  if (!meta) {
2419
- throw new Error(`Automation step ${i + 1}: no SQA action named "${name}" for technology ${tech}. Check the action catalog in the SQA UI.`);
2512
+ throw new Error(`Automation step ${i + 1}: no SQA action named "${name}" for technology ${tech}. Catalog size=${catalog.size}, numericId=${isNumericId}. FetchDiag: ${this.actionCatalogFetchDiag}.${fallbackDiag}`);
2420
2513
  }
2421
2514
  let objectId = null;
2422
2515
  if (meta.objectRequired) {
2423
- if (!s.objectRef || !s.objectRef.name || !(s.objectRef.locators?.length)) {
2424
- throw new Error(`Automation step ${i + 1} ("${name}"): action requires an object but Step.objectRef is missing name/locators. Provide objectRef:{name, locators:[{name, value}]}.`);
2516
+ // Resolution ladder (first match wins):
2517
+ // 1. objectRef.id set → use directly (round-trip OR LLM referencing a known object)
2518
+ // 2. sourceId set but no objectRef.id → preserve DB value (existing step, backend may
2519
+ // have null historically; emitting anything would $set-clobber)
2520
+ // 3. objectRef.name only (no locators) → project-scoped name lookup (LLM added a step
2521
+ // referencing an existing Object Repository entry by name — mirrors UI dropdown)
2522
+ // 4. objectRef.name + locators → get-or-create via createObjectSeq (recorder path)
2523
+ // 5. nothing usable → throw with the three-option error so the caller can pick
2524
+ const roundTripId = s.objectRef?.id ? Number.parseInt(String(s.objectRef.id), 10) : NaN;
2525
+ if (Number.isFinite(roundTripId)) {
2526
+ objectId = roundTripId;
2527
+ }
2528
+ else if (s.sourceId) {
2529
+ objectId = undefined;
2530
+ }
2531
+ else if (s.objectRef?.name && !(s.objectRef.locators?.length)) {
2532
+ const found = await this.findObjectIdByName(projectId, s.objectRef.name);
2533
+ if (found != null) {
2534
+ objectId = found;
2535
+ }
2536
+ else {
2537
+ throw new Error(`Automation step ${i + 1} ("${name}"): no object named "${s.objectRef.name}" found in this project. Either pass objectRef.id to reuse an existing one, or add objectRef.locators:[{name, value}, ...] to create a new object with that name.`);
2538
+ }
2539
+ }
2540
+ else if (s.objectRef?.name && s.objectRef.locators?.length) {
2541
+ if (meta.objectTemplate == null) {
2542
+ throw new Error(`Automation step ${i + 1} ("${name}"): action ${meta.id} has no objectTemplate — cannot create/reuse an object without knowing which template it belongs to.`);
2543
+ }
2544
+ objectId = await this.resolveObjectId(s.objectRef, projectId, moduleId, tech, meta.objectTemplate);
2425
2545
  }
2426
- if (meta.objectTemplate == null) {
2427
- throw new Error(`Automation step ${i + 1} ("${name}"): action ${meta.id} has no objectTemplate — cannot create/reuse an object without knowing which template it belongs to.`);
2546
+ else {
2547
+ throw new Error(`Automation step ${i + 1} ("${name}"): action requires an object but Step.objectRef is missing. Provide objectRef:{id} to reuse a known one, objectRef:{name} to look one up by name in the project, or objectRef:{name, locators:[{name, value}]} to create a new one.`);
2428
2548
  }
2429
- objectId = await this.resolveObjectId(s.objectRef, projectId, moduleId, tech, meta.objectTemplate);
2430
2549
  }
2431
2550
  out.push({ actionId: meta.id, objectId });
2432
2551
  }
@@ -2455,6 +2574,28 @@ export class SimplifyQaAdapter {
2455
2574
  }
2456
2575
  return null;
2457
2576
  }
2577
+ /** Case-insensitive project-scoped lookup of an existing object by `disname` (the UI's Name).
2578
+ * Lets tc_draft_update pass `objectRef:{name}` for an already-defined object without also
2579
+ * supplying locators — mirrors what a user picking from the Object Repository dropdown does. */
2580
+ async findObjectIdByName(projectId, name) {
2581
+ const body = this.searchBody([
2582
+ { column: 'disname', value: name },
2583
+ { column: 'projectId', value: projectId },
2584
+ { column: 'deleted', value: false },
2585
+ ], { startIndex: 0, limit: 10 });
2586
+ body['searchFields'][0]['ignorecase'] = true;
2587
+ const raw = await this.http.postJson('/tm/object/search', body);
2588
+ const rows = pickArray(raw, 'data', 'content', 'objects');
2589
+ for (const row of rows) {
2590
+ const rowName = str(row, 'disname');
2591
+ if (rowName?.toLowerCase() === name.toLowerCase()) {
2592
+ const id = str(row, 'id', '_id');
2593
+ if (id)
2594
+ return Number.parseInt(id, 10);
2595
+ }
2596
+ }
2597
+ return null;
2598
+ }
2458
2599
  async getOrCreateParameter(projectId, moduleId, name, defaultValue) {
2459
2600
  const existing = await this.findParameterId(projectId, name);
2460
2601
  if (existing != null)
@@ -2885,7 +3026,19 @@ export class SimplifyQaAdapter {
2885
3026
  }
2886
3027
  // ---------------------------------------------------------------------- Actions catalog
2887
3028
  async actionsCatalog(platform) {
2888
- return this.requireHop('actions_catalog').actionsCatalog(platform);
3029
+ // Build from the live backend catalog (already cached per-connection). Each entry gets its
3030
+ // numeric id + objectRequired flag so callers can round-trip actionType ↔ actionId. Ignores
3031
+ // `platform` — action rows carry no top-level technology; tech disambiguation is a follow-up
3032
+ // (would need an object_templates lookup). Skips the `id::N` reverse-lookup keys.
3033
+ void platform;
3034
+ const catalog = await this.actionCatalog();
3035
+ const defs = [];
3036
+ for (const [key, meta] of catalog) {
3037
+ if (key.startsWith('id::'))
3038
+ continue; // reverse-lookup entry — already covered by name key
3039
+ defs.push({ actionType: key, platform: 'unknown', id: meta.id, objectRequired: meta.objectRequired });
3040
+ }
3041
+ return defs;
2889
3042
  }
2890
3043
  // ---------------------------------------------------------------------- Testdata generation [Step 3]
2891
3044
  /** Fetch the default (template) iteration row for a TC. Fills gaps from the raw TC:
@@ -3138,10 +3291,14 @@ export class SimplifyQaAdapter {
3138
3291
  const total = children.length;
3139
3292
  const done = children.filter((c) => c.state !== 'queued' && c.state !== 'running').length;
3140
3293
  const suiteNum = Number(execDoc.executionTypeId ?? 0);
3294
+ const startedAt = str(execDoc, 'startTime', 'createdAt');
3295
+ const endedAt = str(execDoc, 'endTime');
3141
3296
  return {
3142
3297
  runId,
3143
3298
  state: mapRunState(str(execDoc, 'status') ?? ''),
3144
3299
  ...(total > 0 ? { progress: { done, total }, children } : {}),
3300
+ ...(startedAt ? { startedAt } : {}),
3301
+ ...(endedAt ? { endedAt } : {}),
3145
3302
  reportUrl: `${base}/user/reports/reports-page?type=SUITE&parentId=${suiteNum}&id=${runIdNum}&projectId=${projectId}`,
3146
3303
  };
3147
3304
  }
@@ -3307,11 +3464,10 @@ export class SimplifyQaAdapter {
3307
3464
  // SUITE runs are not yet ported and still hop (or error clearly).
3308
3465
  async startRun(target, opts) {
3309
3466
  const projectId = this.requireProjectId();
3467
+ if (target.suiteId && !target.tcId) {
3468
+ return this.startSuiteRun(target.suiteId, opts);
3469
+ }
3310
3470
  if (!target.tcId) {
3311
- if (target.suiteId) {
3312
- throw new Error('startRun: SUITE runs are not yet ported to direct REST — set QA_MCP_URL so common-mcp ' +
3313
- 'can hop to the SimplifyQA agent for suite dispatch, or run a single TC.');
3314
- }
3315
3471
  throw new Error('startRun: target.tcId (or target.suiteId) is required.');
3316
3472
  }
3317
3473
  const tcId = target.tcId;
@@ -3485,6 +3641,192 @@ export class SimplifyQaAdapter {
3485
3641
  killType: 'STOP_EXECUTION',
3486
3642
  });
3487
3643
  }
3644
+ /** SUITE dispatch. Mirrors `startRun` above (which handles TC) — same `/exec/execution` endpoint,
3645
+ * same LOCAL-agent fast-fail, same project-name / environment resolution. What differs is on the
3646
+ * wire: `type: 'SUITE'`, `executionType` sourced from `suite.suiteType`, `mode` defaulting to
3647
+ * `suite.executionType`, a populated `globalConfiguration` block, and one `executionItems` entry
3648
+ * PER member — each carrying the suite row's persisted `versionId` / `stepId` / `platform` / `seq`
3649
+ * (NOT a re-derived random step id). See sqa-ui execution-popup-modal.component.ts:621-1105 SU
3650
+ * branch for the authoritative UI builder; every field below traces back to a line there. */
3651
+ async startSuiteRun(suiteId, opts) {
3652
+ const projectId = this.requireProjectId();
3653
+ const suiteNum = Number.parseInt(numericId(suiteId), 10);
3654
+ if (!Number.isFinite(suiteNum))
3655
+ throw new Error(`startRun: could not resolve numeric id for ${suiteId}.`);
3656
+ const rawSuite = await this.fetchRawSuite(suiteId);
3657
+ if (!rawSuite || Object.keys(rawSuite).length === 0) {
3658
+ throw new Error(`startRun: suite ${suiteId} not found.`);
3659
+ }
3660
+ // Effective mode: caller pick wins (matches our tool's cascade UX); fall back to the suite doc's
3661
+ // stored `executionType`, which the UI reads unconditionally (execution-popup-modal.ts:668).
3662
+ const mode = (opts.mode ?? String(rawSuite.executionType ?? 'LOCAL')).toUpperCase();
3663
+ if (mode === 'LOCAL' && !(await this.probeLocalAgent())) {
3664
+ throw new Error(`startRun (LOCAL): SimplifyQA desktop agent is not reachable at ` +
3665
+ `${this.cfg.url ?? '(no agent URL configured — set QA_MCP_URL)'}. Start the desktop ` +
3666
+ `agent, then try again. Use mode:'cloud' to run on a cloud runner instead — it does not ` +
3667
+ `need the desktop agent.`);
3668
+ }
3669
+ const projectName = await this.lookupProjectName(projectId);
3670
+ if (!projectName) {
3671
+ throw new Error(`startRun: could not resolve project name for projectId=${projectId}. ` +
3672
+ `The token may not have read access to this project.`);
3673
+ }
3674
+ const env = await this.resolveEnvironment(projectId, opts.environment);
3675
+ const suiteType = String(rawSuite.suiteType ?? 'AUTOMATION').toUpperCase();
3676
+ // Build one executionItems entry per suite row, in suite order. Silently skip rows whose TC no
3677
+ // longer exists (matches UI :880 `if (!data) return;`). Every item uses the suite row's stored
3678
+ // versionId + stepId + per-mode platform — regenerating any of those splits step correlation
3679
+ // and breaks the agent's iteration join. Missing platform for a row is not an error here (UI
3680
+ // sends `[]`) — the agent tolerates it for MANUAL suites; AUTOMATION suites without a saved
3681
+ // platform were misconfigured upstream and would fail regardless.
3682
+ const members = Array.isArray(rawSuite.testCases) ? rawSuite.testCases : [];
3683
+ const executionItems = [];
3684
+ let seqCounter = 0;
3685
+ for (const row of members) {
3686
+ seqCounter++;
3687
+ const memberTcId = row?.testcaseId;
3688
+ if (memberTcId === undefined || memberTcId === null)
3689
+ continue;
3690
+ let rawTc;
3691
+ try {
3692
+ rawTc = await this.fetchRawTestcase(String(memberTcId));
3693
+ }
3694
+ catch {
3695
+ continue;
3696
+ }
3697
+ if (!rawTc || Object.keys(rawTc).length === 0)
3698
+ continue;
3699
+ const tcType = String(str(rawTc, 'tcType') ?? 'WEB').toUpperCase();
3700
+ const versions = Array.isArray(rawTc?.versions) ? rawTc.versions : [];
3701
+ const rowVersionId = row?.versionId ?? row?.version;
3702
+ const versionMatch = rowVersionId
3703
+ ? versions.find((v) => str(v, 'id', '_id') === String(rowVersionId) || str(v, 'name') === String(rowVersionId))
3704
+ : undefined;
3705
+ const versionId = str(versionMatch, 'id', '_id') ?? (rowVersionId !== undefined ? String(rowVersionId) : '');
3706
+ const versionName = str(versionMatch, 'name') ?? str(rawTc, 'versionName', 'selectedVersionName') ?? 'v1.0';
3707
+ // Per-mode platform from the suite row. UI reads `data1.executionPlatform[mode]` (:882-965);
3708
+ // when saved, it's a single object → wrap in `[obj]`; if the row didn't save one for this
3709
+ // mode, send `[]` and let the backend reject/accept per its own rules.
3710
+ const savedPlatform = row?.executionPlatform?.[mode];
3711
+ let platform = [];
3712
+ if (savedPlatform && typeof savedPlatform === 'object') {
3713
+ const p = {
3714
+ name: savedPlatform.name,
3715
+ id: savedPlatform.id ?? savedPlatform.name,
3716
+ technologyType: String(savedPlatform.technologyType ?? tcType).toUpperCase(),
3717
+ type: savedPlatform.type ?? 'NONE',
3718
+ };
3719
+ if (savedPlatform.cloudDeviceType)
3720
+ p['cloudDeviceType'] = savedPlatform.cloudDeviceType;
3721
+ if (savedPlatform.osVersion)
3722
+ p['osVersion'] = savedPlatform.osVersion;
3723
+ platform = [p];
3724
+ }
3725
+ else if (['API', 'MAINFRAME', 'SAP', 'DESKTOP', 'DATABASE'].includes(tcType)) {
3726
+ platform = [{ name: tcType, id: tcType, technologyType: tcType, type: 'NONE' }];
3727
+ }
3728
+ const moduleIdNum = typeof rawTc?.moduleId === 'number' ? rawTc.moduleId : 0;
3729
+ let moduleName = '';
3730
+ if (moduleIdNum > 0) {
3731
+ try {
3732
+ const body = this.searchBody([{ column: 'id', value: moduleIdNum }, { column: 'deleted', value: false }], { selectFields: ['id', 'name'], limit: 1 });
3733
+ const raw = await this.http.postJson('/pm/module/search', body);
3734
+ const rows = pickArray(raw, 'data', 'content', 'modules');
3735
+ moduleName = str(rows[0], 'name') ?? '';
3736
+ }
3737
+ catch { /* leave empty */ }
3738
+ }
3739
+ executionItems.push({
3740
+ id: typeof rawTc?.id === 'number' ? rawTc.id : Number.parseInt(numericId(String(memberTcId)), 10),
3741
+ name: str(rawTc, 'name', 'title') ?? '',
3742
+ description: str(rawTc, 'description') ?? '',
3743
+ versionId,
3744
+ versionName,
3745
+ seq: typeof row?.seq === 'number' ? row.seq : seqCounter,
3746
+ stepId: row?.stepId ?? '', // MUST come from the suite row, never regenerated
3747
+ stepCount: -1, // suite items send -1 (TC sends 0)
3748
+ technologyType: tcType,
3749
+ type: 'TC', // every item is 'TC'; suite-ness lives at top-level type
3750
+ platform,
3751
+ projectId,
3752
+ projectName,
3753
+ configuration: {},
3754
+ iterationsSelected: [],
3755
+ moduleId: moduleIdNum,
3756
+ userstoryId: typeof rawTc?.userstoryId === 'number' ? rawTc.userstoryId : 0,
3757
+ tags: Array.isArray(rawTc?.tags) ? rawTc.tags : [],
3758
+ code: str(rawTc, 'code') ?? '',
3759
+ prerequisite: str(rawTc, 'prerequisite', 'preconditions') ?? '',
3760
+ moduleName,
3761
+ userstoryName: '',
3762
+ });
3763
+ }
3764
+ if (executionItems.length === 0) {
3765
+ throw new Error(`startRun: suite ${suiteId} has no runnable test cases (all members were deleted, ` +
3766
+ `unreadable, or filtered out).`);
3767
+ }
3768
+ // agentId derivation (mirrors UI :677). LOCAL always uses this machine's agent; REMOTE/CLOUD
3769
+ // pin the suite doc's saved `agentId` (or null when the suite wasn't pinned). CLOUD_AGENT
3770
+ // fallback (:771-774) promotes `cloudType` to 'SQA'.
3771
+ let agentId;
3772
+ if (mode === 'LOCAL') {
3773
+ agentId = await this.resolveLocalAgentId(opts.agentId);
3774
+ }
3775
+ else if (mode === 'REMOTE') {
3776
+ const preferred = opts.agentId ?? (typeof rawSuite.agentId === 'string' ? rawSuite.agentId : undefined);
3777
+ agentId = preferred ? await this.resolveRemoteAgentId(preferred) : null;
3778
+ }
3779
+ else {
3780
+ agentId = typeof rawSuite.agentId === 'string' && rawSuite.agentId.length > 0 ? rawSuite.agentId : null;
3781
+ }
3782
+ let cloudType = mode === 'CLOUD' ? 'VM' : 'NONE';
3783
+ if (!agentId && typeof rawSuite.cloudAgentId === 'string' && rawSuite.cloudAgentId.length > 0) {
3784
+ agentId = rawSuite.cloudAgentId;
3785
+ cloudType = 'SQA';
3786
+ }
3787
+ const gc = rawSuite.globalConfiguration ?? {};
3788
+ const body = {
3789
+ projectId,
3790
+ environmentType: env,
3791
+ executionStyle: (opts.strategy ?? 'serial').toUpperCase(),
3792
+ executionOS: this.detectExecutionOS(),
3793
+ executionTypeId: suiteNum,
3794
+ executionTypeName: str(rawSuite, 'name') ?? '',
3795
+ executionTypeCode: str(rawSuite, 'code') ?? '',
3796
+ mailersList: rawSuite.mailersList ?? {},
3797
+ cloudType,
3798
+ mode,
3799
+ executionCategory: 'EXECUTION',
3800
+ releaseId: opts.releaseId ? Number.parseInt(opts.releaseId, 10) || 0 : 0,
3801
+ iterationId: opts.sprintId ? Number.parseInt(opts.sprintId, 10) || 0 : 0,
3802
+ executionTime: '',
3803
+ status: 'INPROGRESS',
3804
+ iterationsSelected: [],
3805
+ result: '',
3806
+ globalConfiguration: {
3807
+ TERMINATE_ON_FAIL: opts.terminateOnFailure ?? gc.TERMINATE_ON_FAIL ?? false,
3808
+ NEW_BROWSER_SESSION: gc.NEW_BROWSER_SESSION ?? false,
3809
+ RE_EXECUTION_COUNT: gc.RE_EXECUTION_COUNT ?? 0,
3810
+ RE_EXECUTION_TYPE: gc.RE_EXECUTION_TYPE ?? 'AFTER_TESTCASE',
3811
+ MINIMUM_CONTAINER_COUNT: gc.MINIMUM_CONTAINER_COUNT ?? 1,
3812
+ MAXIMUM_CONTAINER_COUNT: opts.maxConcurrent ?? gc.MAXIMUM_CONTAINER_COUNT ?? 5,
3813
+ },
3814
+ isRecordingEnabled: false,
3815
+ offset: -(new Date().getTimezoneOffset()),
3816
+ type: 'SUITE',
3817
+ executionType: suiteType,
3818
+ agentId,
3819
+ executionItems,
3820
+ };
3821
+ const resp = await this.http.postJson('/exec/execution', body);
3822
+ const d = resp?.data ?? resp;
3823
+ const runId = str(d, 'id', 'executionId', '_id') ??
3824
+ (typeof d?.id === 'number' ? String(d.id) : undefined) ??
3825
+ (typeof d?.executionId === 'number' ? String(d.executionId) : undefined);
3826
+ if (!runId)
3827
+ throw new Error('startRun: backend accepted suite trigger but returned no run id.');
3828
+ return { runId };
3829
+ }
3488
3830
  /** GET the agent /mcp with a 1s timeout. Any HTTP response (incl. 4xx from an MCP server rejecting
3489
3831
  * a naked GET) proves the process is up; connect/DNS/timeout errors mean it is down. Replaces
3490
3832
  * the customer-wide `machineRegistration` round trip when all we needed was "is LOCAL possible?". */