qagentic-reporter 0.1.4 → 0.1.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.
@@ -0,0 +1,655 @@
1
+ import { v4 } from 'uuid';
2
+ import * as fs2 from 'fs';
3
+ import * as path2 from 'path';
4
+ import axios from 'axios';
5
+
6
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
7
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
8
+ }) : x)(function(x) {
9
+ if (typeof require !== "undefined") return require.apply(this, arguments);
10
+ throw Error('Dynamic require of "' + x + '" is not supported');
11
+ });
12
+ var defaultConfig = {
13
+ projectName: "default",
14
+ environment: "local",
15
+ api: {
16
+ enabled: true,
17
+ url: "http://localhost:8080",
18
+ timeout: 3e4,
19
+ retryCount: 3,
20
+ batchSize: 100
21
+ },
22
+ local: {
23
+ enabled: true,
24
+ outputDir: "./qagentic-results",
25
+ formats: ["json", "html"],
26
+ cleanOnStart: true
27
+ },
28
+ features: {
29
+ aiAnalysis: true,
30
+ failureClustering: true,
31
+ flakyDetection: true,
32
+ screenshots: "on_failure",
33
+ videos: "on_failure",
34
+ consoleOutput: true
35
+ },
36
+ labels: {
37
+ custom: {}
38
+ }
39
+ };
40
+ var globalConfig = { ...defaultConfig };
41
+ function loadFromEnv(config) {
42
+ const env = process.env;
43
+ if (env.QAGENTIC_PROJECT_NAME) {
44
+ config.projectName = env.QAGENTIC_PROJECT_NAME;
45
+ }
46
+ if (env.QAGENTIC_ENVIRONMENT) {
47
+ config.environment = env.QAGENTIC_ENVIRONMENT;
48
+ }
49
+ if (env.QAGENTIC_API_ENABLED !== void 0) {
50
+ config.api.enabled = env.QAGENTIC_API_ENABLED.toLowerCase() === "true";
51
+ }
52
+ if (env.QAGENTIC_API_URL) {
53
+ config.api.url = env.QAGENTIC_API_URL;
54
+ }
55
+ if (env.QAGENTIC_API_KEY) {
56
+ config.api.key = env.QAGENTIC_API_KEY;
57
+ }
58
+ if (env.QAGENTIC_LOCAL_ENABLED !== void 0) {
59
+ config.local.enabled = env.QAGENTIC_LOCAL_ENABLED.toLowerCase() === "true";
60
+ }
61
+ if (env.QAGENTIC_OUTPUT_DIR) {
62
+ config.local.outputDir = env.QAGENTIC_OUTPUT_DIR;
63
+ }
64
+ if (env.QAGENTIC_OUTPUT_FORMAT) {
65
+ config.local.formats = env.QAGENTIC_OUTPUT_FORMAT.split(",").map(
66
+ (f) => f.trim()
67
+ );
68
+ }
69
+ if (env.QAGENTIC_AI_ANALYSIS !== void 0) {
70
+ config.features.aiAnalysis = env.QAGENTIC_AI_ANALYSIS.toLowerCase() === "true";
71
+ }
72
+ if (env.QAGENTIC_SCREENSHOTS) {
73
+ config.features.screenshots = env.QAGENTIC_SCREENSHOTS;
74
+ }
75
+ if (env.QAGENTIC_VIDEOS) {
76
+ config.features.videos = env.QAGENTIC_VIDEOS;
77
+ }
78
+ if (env.QAGENTIC_TEAM) {
79
+ config.labels.team = env.QAGENTIC_TEAM;
80
+ }
81
+ if (env.QAGENTIC_COMPONENT) {
82
+ config.labels.component = env.QAGENTIC_COMPONENT;
83
+ }
84
+ return config;
85
+ }
86
+ function loadFromFile(filePath, config) {
87
+ try {
88
+ if (!fs2.existsSync(filePath)) {
89
+ return config;
90
+ }
91
+ const content = fs2.readFileSync(filePath, "utf-8");
92
+ const yaml = __require("yaml");
93
+ const data = yaml.parse(content);
94
+ if (data.project) {
95
+ if (data.project.name) config.projectName = data.project.name;
96
+ if (data.project.environment) config.environment = data.project.environment;
97
+ }
98
+ if (data.reporting?.api) {
99
+ if (data.reporting.api.enabled !== void 0) config.api.enabled = data.reporting.api.enabled;
100
+ if (data.reporting.api.url) config.api.url = data.reporting.api.url;
101
+ if (data.reporting.api.key) config.api.key = data.reporting.api.key;
102
+ }
103
+ if (data.reporting?.local) {
104
+ if (data.reporting.local.enabled !== void 0)
105
+ config.local.enabled = data.reporting.local.enabled;
106
+ if (data.reporting.local.output_dir) config.local.outputDir = data.reporting.local.output_dir;
107
+ if (data.reporting.local.formats) config.local.formats = data.reporting.local.formats;
108
+ }
109
+ if (data.features) {
110
+ if (data.features.ai_analysis !== void 0)
111
+ config.features.aiAnalysis = data.features.ai_analysis;
112
+ if (data.features.failure_clustering !== void 0)
113
+ config.features.failureClustering = data.features.failure_clustering;
114
+ if (data.features.flaky_detection !== void 0)
115
+ config.features.flakyDetection = data.features.flaky_detection;
116
+ if (data.features.screenshots) config.features.screenshots = data.features.screenshots;
117
+ if (data.features.videos) config.features.videos = data.features.videos;
118
+ }
119
+ if (data.labels) {
120
+ if (data.labels.team) config.labels.team = data.labels.team;
121
+ if (data.labels.component) config.labels.component = data.labels.component;
122
+ config.labels.custom = { ...config.labels.custom, ...data.labels };
123
+ }
124
+ } catch (error) {
125
+ console.warn(`Failed to load config from ${filePath}:`, error);
126
+ }
127
+ return config;
128
+ }
129
+ function autoDiscover() {
130
+ const config = { ...defaultConfig };
131
+ const cwd = process.cwd();
132
+ const searchPaths = [
133
+ path2.join(cwd, "qagentic.yaml"),
134
+ path2.join(cwd, "qagentic.yml"),
135
+ path2.join(cwd, ".qagentic.yaml"),
136
+ path2.join(cwd, ".qagentic.yml")
137
+ ];
138
+ for (const filePath of searchPaths) {
139
+ if (fs2.existsSync(filePath)) {
140
+ loadFromFile(filePath, config);
141
+ break;
142
+ }
143
+ }
144
+ return loadFromEnv(config);
145
+ }
146
+ function configure(options = {}) {
147
+ globalConfig = autoDiscover();
148
+ if (options.projectName) {
149
+ globalConfig.projectName = options.projectName;
150
+ }
151
+ if (options.environment) {
152
+ globalConfig.environment = options.environment;
153
+ }
154
+ if (options.apiUrl) {
155
+ globalConfig.api.url = options.apiUrl;
156
+ }
157
+ if (options.apiKey) {
158
+ globalConfig.api.key = options.apiKey;
159
+ }
160
+ if (options.outputDir) {
161
+ globalConfig.local.outputDir = options.outputDir;
162
+ }
163
+ if (options.api) {
164
+ globalConfig.api = { ...globalConfig.api, ...options.api };
165
+ }
166
+ if (options.local) {
167
+ globalConfig.local = { ...globalConfig.local, ...options.local };
168
+ }
169
+ if (options.features) {
170
+ globalConfig.features = { ...globalConfig.features, ...options.features };
171
+ }
172
+ if (options.labels) {
173
+ globalConfig.labels = { ...globalConfig.labels, ...options.labels };
174
+ }
175
+ return globalConfig;
176
+ }
177
+ function getConfig() {
178
+ return globalConfig;
179
+ }
180
+
181
+ // src/core/status.ts
182
+ function parseStatus(value) {
183
+ const normalized = value.toLowerCase();
184
+ switch (normalized) {
185
+ case "passed":
186
+ case "pass":
187
+ case "success":
188
+ return "passed" /* PASSED */;
189
+ case "failed":
190
+ case "fail":
191
+ case "failure":
192
+ return "failed" /* FAILED */;
193
+ case "broken":
194
+ case "error":
195
+ return "broken" /* BROKEN */;
196
+ case "skipped":
197
+ case "skip":
198
+ case "pending":
199
+ return "skipped" /* SKIPPED */;
200
+ case "running":
201
+ return "running" /* RUNNING */;
202
+ default:
203
+ return "unknown" /* UNKNOWN */;
204
+ }
205
+ }
206
+
207
+ // src/core/reporter.ts
208
+ var ConsoleReporter = class {
209
+ constructor(config) {
210
+ this.config = config || getConfig();
211
+ }
212
+ startRun(run) {
213
+ console.log("\n" + "=".repeat(60));
214
+ console.log(`\u{1F680} QAagentic Test Run - ${run.projectName}`);
215
+ console.log(`Environment: ${run.environment}`);
216
+ console.log("=".repeat(60) + "\n");
217
+ }
218
+ endRun(run) {
219
+ const icon = run.failed === 0 ? "\u2705" : "\u274C";
220
+ console.log("\n" + "=".repeat(60));
221
+ console.log(`${icon} Test Run Complete - ${run.passRate.toFixed(1)}% Pass Rate`);
222
+ console.log(`Passed: ${run.passed} | Failed: ${run.failed} | Skipped: ${run.skipped}`);
223
+ console.log("=".repeat(60) + "\n");
224
+ }
225
+ reportTest(test) {
226
+ if (!this.config.features.consoleOutput) return;
227
+ const symbols = {
228
+ ["passed" /* PASSED */]: "\u2713",
229
+ ["failed" /* FAILED */]: "\u2717",
230
+ ["broken" /* BROKEN */]: "!",
231
+ ["skipped" /* SKIPPED */]: "\u25CB",
232
+ ["pending" /* PENDING */]: "\u2026",
233
+ ["running" /* RUNNING */]: "\u2192",
234
+ ["unknown" /* UNKNOWN */]: "?"
235
+ };
236
+ const symbol = symbols[test.status] || "?";
237
+ console.log(` ${symbol} ${test.name}`);
238
+ if (test.errorMessage) {
239
+ console.log(` Error: ${test.errorMessage.slice(0, 100)}...`);
240
+ }
241
+ }
242
+ };
243
+ var JSONReporter = class {
244
+ constructor(config) {
245
+ this.config = config || getConfig();
246
+ this.outputDir = this.config.local.outputDir;
247
+ }
248
+ startRun(run) {
249
+ if (!fs2.existsSync(this.outputDir)) {
250
+ fs2.mkdirSync(this.outputDir, { recursive: true });
251
+ }
252
+ if (this.config.local.cleanOnStart) {
253
+ const files = fs2.readdirSync(this.outputDir);
254
+ for (const file of files) {
255
+ if (file.endsWith(".json")) {
256
+ fs2.unlinkSync(path2.join(this.outputDir, file));
257
+ }
258
+ }
259
+ }
260
+ }
261
+ endRun(run) {
262
+ if (!this.config.local.enabled || !this.config.local.formats.includes("json")) {
263
+ return;
264
+ }
265
+ const runFile = path2.join(this.outputDir, "run.json");
266
+ fs2.writeFileSync(runFile, JSON.stringify(this.serializeRun(run), null, 2));
267
+ const testsDir = path2.join(this.outputDir, "tests");
268
+ if (!fs2.existsSync(testsDir)) {
269
+ fs2.mkdirSync(testsDir, { recursive: true });
270
+ }
271
+ for (const test of run.tests) {
272
+ const testFile = path2.join(testsDir, `${test.id}.json`);
273
+ fs2.writeFileSync(testFile, JSON.stringify(this.serializeTest(test), null, 2));
274
+ }
275
+ }
276
+ reportTest(_test) {
277
+ }
278
+ serializeRun(run) {
279
+ return {
280
+ ...run,
281
+ startTime: run.startTime?.toISOString(),
282
+ endTime: run.endTime?.toISOString(),
283
+ tests: run.tests.map((t) => this.serializeTest(t))
284
+ };
285
+ }
286
+ serializeTest(test) {
287
+ return {
288
+ ...test,
289
+ startTime: test.startTime?.toISOString(),
290
+ endTime: test.endTime?.toISOString(),
291
+ steps: test.steps.map((s) => this.serializeStep(s))
292
+ };
293
+ }
294
+ serializeStep(step) {
295
+ return {
296
+ ...step,
297
+ startTime: step.startTime?.toISOString(),
298
+ endTime: step.endTime?.toISOString(),
299
+ children: step.children.map((c) => this.serializeStep(c))
300
+ };
301
+ }
302
+ };
303
+ var JUnitReporter = class {
304
+ constructor(config) {
305
+ this.config = config || getConfig();
306
+ this.outputDir = this.config.local.outputDir;
307
+ }
308
+ startRun(_run) {
309
+ if (!fs2.existsSync(this.outputDir)) {
310
+ fs2.mkdirSync(this.outputDir, { recursive: true });
311
+ }
312
+ }
313
+ endRun(run) {
314
+ if (!this.config.local.enabled || !this.config.local.formats.includes("junit")) {
315
+ return;
316
+ }
317
+ const xml = this.generateXml(run);
318
+ const junitFile = path2.join(this.outputDir, "junit.xml");
319
+ fs2.writeFileSync(junitFile, xml);
320
+ }
321
+ reportTest(_test) {
322
+ }
323
+ generateXml(run) {
324
+ const escape = (str) => str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
325
+ let xml = '<?xml version="1.0" encoding="UTF-8"?>\n';
326
+ xml += `<testsuite name="${escape(run.projectName)}" `;
327
+ xml += `tests="${run.total}" `;
328
+ xml += `failures="${run.failed}" `;
329
+ xml += `errors="${run.broken}" `;
330
+ xml += `skipped="${run.skipped}" `;
331
+ xml += `time="${(run.durationMs / 1e3).toFixed(3)}" `;
332
+ xml += `timestamp="${run.startTime?.toISOString() || ""}">
333
+ `;
334
+ for (const test of run.tests) {
335
+ xml += ` <testcase name="${escape(test.name)}" `;
336
+ xml += `classname="${escape(test.fullName)}" `;
337
+ xml += `time="${(test.durationMs / 1e3).toFixed(3)}"`;
338
+ if (test.status === "passed" /* PASSED */) {
339
+ xml += "/>\n";
340
+ } else if (test.status === "failed" /* FAILED */) {
341
+ xml += ">\n";
342
+ xml += ` <failure message="${escape(test.errorMessage || "Test failed")}" `;
343
+ xml += `type="${escape(test.errorType || "AssertionError")}">`;
344
+ if (test.stackTrace) {
345
+ xml += escape(test.stackTrace);
346
+ }
347
+ xml += "</failure>\n";
348
+ xml += " </testcase>\n";
349
+ } else if (test.status === "broken" /* BROKEN */) {
350
+ xml += ">\n";
351
+ xml += ` <error message="${escape(test.errorMessage || "Test error")}" `;
352
+ xml += `type="${escape(test.errorType || "Error")}">`;
353
+ if (test.stackTrace) {
354
+ xml += escape(test.stackTrace);
355
+ }
356
+ xml += "</error>\n";
357
+ xml += " </testcase>\n";
358
+ } else if (test.status === "skipped" /* SKIPPED */) {
359
+ xml += ">\n";
360
+ xml += ` <skipped${test.errorMessage ? ` message="${escape(test.errorMessage)}"` : ""}/>
361
+ `;
362
+ xml += " </testcase>\n";
363
+ } else {
364
+ xml += "/>\n";
365
+ }
366
+ }
367
+ xml += "</testsuite>\n";
368
+ return xml;
369
+ }
370
+ };
371
+ var APIReporter = class {
372
+ constructor(config) {
373
+ this.batch = [];
374
+ this.config = config || getConfig();
375
+ }
376
+ async startRun(run) {
377
+ if (!this.config.api.enabled) return;
378
+ this.currentRun = run;
379
+ this.batch = [];
380
+ try {
381
+ await axios.post(
382
+ `${this.config.api.url}/api/v1/runs`,
383
+ {
384
+ id: run.id,
385
+ name: run.name,
386
+ project_name: run.projectName,
387
+ environment: run.environment,
388
+ start_time: run.startTime?.toISOString(),
389
+ labels: run.labels,
390
+ ci_build_id: run.ciBuildId,
391
+ branch: run.branch,
392
+ commit_hash: run.commitHash
393
+ },
394
+ {
395
+ headers: {
396
+ "Content-Type": "application/json",
397
+ "X-API-Key": this.config.api.key || "",
398
+ "X-Project": this.config.projectName
399
+ },
400
+ timeout: this.config.api.timeout
401
+ }
402
+ );
403
+ } catch (error) {
404
+ console.warn("Warning: Failed to register run with API:", error);
405
+ }
406
+ }
407
+ async endRun(run) {
408
+ if (!this.config.api.enabled) return;
409
+ await this.flushBatch();
410
+ try {
411
+ await axios.patch(
412
+ `${this.config.api.url}/api/v1/runs/${run.id}`,
413
+ {
414
+ end_time: run.endTime?.toISOString(),
415
+ duration_ms: run.durationMs,
416
+ total: run.total,
417
+ passed: run.passed,
418
+ failed: run.failed,
419
+ broken: run.broken,
420
+ skipped: run.skipped,
421
+ status: "completed"
422
+ },
423
+ {
424
+ headers: {
425
+ "Content-Type": "application/json",
426
+ "X-API-Key": this.config.api.key || ""
427
+ },
428
+ timeout: this.config.api.timeout
429
+ }
430
+ );
431
+ } catch (error) {
432
+ console.warn("Warning: Failed to finalize run with API:", error);
433
+ }
434
+ }
435
+ async reportTest(test) {
436
+ if (!this.config.api.enabled) return;
437
+ this.batch.push(test);
438
+ if (this.batch.length >= this.config.api.batchSize) {
439
+ await this.flushBatch();
440
+ }
441
+ }
442
+ async flushBatch() {
443
+ if (this.batch.length === 0 || !this.currentRun) return;
444
+ try {
445
+ await axios.post(
446
+ `${this.config.api.url}/api/v1/runs/${this.currentRun.id}/results`,
447
+ this.batch.map((t) => ({
448
+ ...t,
449
+ startTime: t.startTime?.toISOString(),
450
+ endTime: t.endTime?.toISOString()
451
+ })),
452
+ {
453
+ headers: {
454
+ "Content-Type": "application/json",
455
+ "X-API-Key": this.config.api.key || ""
456
+ },
457
+ timeout: this.config.api.timeout
458
+ }
459
+ );
460
+ } catch (error) {
461
+ console.warn("Warning: Failed to send test results to API:", error);
462
+ } finally {
463
+ this.batch = [];
464
+ }
465
+ }
466
+ };
467
+ var _QAgenticReporter = class _QAgenticReporter {
468
+ constructor(config) {
469
+ this.reporters = [];
470
+ this.currentRun = null;
471
+ this.config = config || getConfig();
472
+ if (this.config.features.consoleOutput) {
473
+ this.reporters.push(new ConsoleReporter(this.config));
474
+ }
475
+ if (this.config.local.enabled) {
476
+ this.reporters.push(new JSONReporter(this.config));
477
+ if (this.config.local.formats.includes("junit")) {
478
+ this.reporters.push(new JUnitReporter(this.config));
479
+ }
480
+ }
481
+ if (this.config.api.enabled) {
482
+ this.reporters.push(new APIReporter(this.config));
483
+ }
484
+ }
485
+ /**
486
+ * Get singleton instance.
487
+ */
488
+ static getInstance(config) {
489
+ if (!_QAgenticReporter.instance) {
490
+ _QAgenticReporter.instance = new _QAgenticReporter(config);
491
+ }
492
+ return _QAgenticReporter.instance;
493
+ }
494
+ /**
495
+ * Reset singleton instance.
496
+ */
497
+ static reset() {
498
+ _QAgenticReporter.instance = null;
499
+ }
500
+ /**
501
+ * Start a new test run.
502
+ */
503
+ async startRun(options = {}) {
504
+ this.currentRun = {
505
+ id: options.id || v4(),
506
+ name: options.name || `run_${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "")}`,
507
+ projectName: options.projectName || this.config.projectName,
508
+ environment: options.environment || this.config.environment,
509
+ startTime: /* @__PURE__ */ new Date(),
510
+ durationMs: 0,
511
+ tests: [],
512
+ total: 0,
513
+ passed: 0,
514
+ failed: 0,
515
+ broken: 0,
516
+ skipped: 0,
517
+ passRate: 0,
518
+ labels: { ...this.config.labels.custom, ...options.labels },
519
+ parameters: options.parameters || {},
520
+ ciBuildId: options.ciBuildId,
521
+ ciBuildUrl: options.ciBuildUrl,
522
+ branch: options.branch,
523
+ commitHash: options.commitHash
524
+ };
525
+ for (const reporter of this.reporters) {
526
+ await reporter.startRun(this.currentRun);
527
+ }
528
+ return this.currentRun;
529
+ }
530
+ /**
531
+ * End the current test run.
532
+ */
533
+ async endRun() {
534
+ if (!this.currentRun) return null;
535
+ this.currentRun.endTime = /* @__PURE__ */ new Date();
536
+ this.currentRun.durationMs = this.currentRun.endTime.getTime() - (this.currentRun.startTime?.getTime() || 0);
537
+ this.currentRun.passRate = this.currentRun.total > 0 ? this.currentRun.passed / this.currentRun.total * 100 : 0;
538
+ for (const reporter of this.reporters) {
539
+ await reporter.endRun(this.currentRun);
540
+ }
541
+ const run = this.currentRun;
542
+ this.currentRun = null;
543
+ return run;
544
+ }
545
+ /**
546
+ * Report a test result.
547
+ */
548
+ async reportTest(test) {
549
+ if (this.currentRun) {
550
+ this.currentRun.tests.push(test);
551
+ this.currentRun.total++;
552
+ switch (test.status) {
553
+ case "passed" /* PASSED */:
554
+ this.currentRun.passed++;
555
+ break;
556
+ case "failed" /* FAILED */:
557
+ this.currentRun.failed++;
558
+ break;
559
+ case "broken" /* BROKEN */:
560
+ this.currentRun.broken++;
561
+ break;
562
+ case "skipped" /* SKIPPED */:
563
+ this.currentRun.skipped++;
564
+ break;
565
+ }
566
+ }
567
+ for (const reporter of this.reporters) {
568
+ await reporter.reportTest(test);
569
+ }
570
+ }
571
+ /**
572
+ * Get the current test run.
573
+ */
574
+ getCurrentRun() {
575
+ return this.currentRun;
576
+ }
577
+ };
578
+ _QAgenticReporter.instance = null;
579
+ var QAgenticReporter = _QAgenticReporter;
580
+
581
+ // src/cypress/simple-setup.ts
582
+ function setupQAgentic(on, config) {
583
+ const projectName = process.env.QAGENTIC_PROJECT_NAME || config.projectId || "Cypress E2E Tests";
584
+ const environment = process.env.QAGENTIC_ENVIRONMENT || process.env.NODE_ENV || "e2e";
585
+ const apiUrl = process.env.QAGENTIC_API_URL || "http://localhost:8080";
586
+ configure({
587
+ projectName,
588
+ environment,
589
+ apiUrl,
590
+ outputDir: "./qagentic-results"
591
+ });
592
+ const reporter = QAgenticReporter.getInstance();
593
+ let currentRun = null;
594
+ on("before:run", async () => {
595
+ try {
596
+ currentRun = await reporter.startRun({
597
+ name: `cypress_${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "")}`,
598
+ projectName,
599
+ environment
600
+ });
601
+ console.log("[QAagentic] Test run started successfully");
602
+ } catch (error) {
603
+ console.warn("[QAagentic] Failed to start run:", error);
604
+ }
605
+ });
606
+ on("after:spec", async (_spec, results) => {
607
+ if (!results?.tests) return;
608
+ for (const test of results.tests) {
609
+ try {
610
+ const testResult = {
611
+ id: v4(),
612
+ name: test.title[test.title.length - 1],
613
+ fullName: test.title.join(" > "),
614
+ status: parseStatus(test.state),
615
+ durationMs: test.duration,
616
+ startTime: new Date(Date.now() - test.duration),
617
+ endTime: /* @__PURE__ */ new Date(),
618
+ labels: {
619
+ suite: test.title.slice(0, -1).join(" > "),
620
+ feature: test.title[0]
621
+ },
622
+ links: [],
623
+ parameters: {},
624
+ steps: [],
625
+ attachments: [],
626
+ filePath: results.spec.relative,
627
+ retryCount: 0,
628
+ isRetry: false,
629
+ isFlaky: false
630
+ };
631
+ if (test.err) {
632
+ testResult.errorMessage = test.err.message;
633
+ testResult.stackTrace = test.err.stack;
634
+ testResult.errorType = "AssertionError";
635
+ }
636
+ await reporter.reportTest(testResult);
637
+ } catch (error) {
638
+ console.warn("[QAagentic] Failed to report test:", error);
639
+ }
640
+ }
641
+ });
642
+ on("after:run", async () => {
643
+ try {
644
+ await reporter.endRun();
645
+ console.log("[QAagentic] Test run completed");
646
+ } catch (error) {
647
+ console.warn("[QAagentic] Failed to end run:", error);
648
+ }
649
+ });
650
+ }
651
+ var simple_setup_default = setupQAgentic;
652
+
653
+ export { simple_setup_default as default, setupQAgentic };
654
+ //# sourceMappingURL=simple-setup.mjs.map
655
+ //# sourceMappingURL=simple-setup.mjs.map