@cqa-lib/cqa-ui 1.1.223 → 1.1.225
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/esm2020/lib/execution-screen/ai-logs-with-reasoning/ai-logs-with-reasoning.component.mjs +37 -0
- package/esm2020/lib/execution-screen/api-step/api-step.component.mjs +246 -8
- package/esm2020/lib/execution-screen/basic-step/basic-step.component.mjs +257 -9
- package/esm2020/lib/execution-screen/execution-step.models.mjs +1 -1
- package/esm2020/lib/execution-screen/live-execution-step/live-execution-step.component.mjs +194 -6
- package/esm2020/lib/execution-screen/loop-step/loop-step.component.mjs +344 -10
- package/esm2020/lib/execution-screen/main-step-collapse/main-step-collapse.component.mjs +10 -6
- package/esm2020/lib/execution-screen/visual-comparison/visual-comparison.component.mjs +8 -4
- package/esm2020/lib/ui-kit.module.mjs +10 -1
- package/esm2020/public-api.mjs +2 -1
- package/fesm2015/cqa-lib-cqa-ui.mjs +894 -15
- package/fesm2015/cqa-lib-cqa-ui.mjs.map +1 -1
- package/fesm2020/cqa-lib-cqa-ui.mjs +1067 -15
- package/fesm2020/cqa-lib-cqa-ui.mjs.map +1 -1
- package/lib/execution-screen/ai-logs-with-reasoning/ai-logs-with-reasoning.component.d.ts +17 -0
- package/lib/execution-screen/api-step/api-step.component.d.ts +13 -2
- package/lib/execution-screen/basic-step/basic-step.component.d.ts +14 -2
- package/lib/execution-screen/execution-step.models.d.ts +2 -0
- package/lib/execution-screen/live-execution-step/live-execution-step.component.d.ts +12 -2
- package/lib/execution-screen/loop-step/loop-step.component.d.ts +14 -2
- package/lib/execution-screen/main-step-collapse/main-step-collapse.component.d.ts +2 -1
- package/lib/execution-screen/visual-comparison/visual-comparison.component.d.ts +1 -0
- package/lib/ui-kit.module.d.ts +95 -93
- package/package.json +1 -1
- package/public-api.d.ts +1 -0
- package/styles.css +1 -1
|
@@ -38,7 +38,9 @@ import * as i1$5 from '@angular/cdk/overlay';
|
|
|
38
38
|
import { OverlayContainer, OverlayConfig, OverlayModule } from '@angular/cdk/overlay';
|
|
39
39
|
import * as i3 from '@angular/cdk/portal';
|
|
40
40
|
import { TemplatePortal, CdkPortalOutlet, ComponentPortal, PortalModule } from '@angular/cdk/portal';
|
|
41
|
-
import * as
|
|
41
|
+
import * as i2$3 from '@angular/cdk/scrolling';
|
|
42
|
+
import { ScrollingModule } from '@angular/cdk/scrolling';
|
|
43
|
+
import * as i4$2 from 'ngx-typed-js';
|
|
42
44
|
import { NgxTypedJsModule } from 'ngx-typed-js';
|
|
43
45
|
import { __awaiter } from 'tslib';
|
|
44
46
|
import * as i1$2 from '@angular/platform-browser';
|
|
@@ -6595,6 +6597,41 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
6595
6597
|
type: Output
|
|
6596
6598
|
}] } });
|
|
6597
6599
|
|
|
6600
|
+
class AiLogsWithReasoningComponent extends BaseStepComponent {
|
|
6601
|
+
ngOnInit() { }
|
|
6602
|
+
get displayText() {
|
|
6603
|
+
return this.text || this.description || '';
|
|
6604
|
+
}
|
|
6605
|
+
get hasReasoning() {
|
|
6606
|
+
return !!this.reasoning;
|
|
6607
|
+
}
|
|
6608
|
+
get isSuccess() {
|
|
6609
|
+
var _a;
|
|
6610
|
+
const statusLower = (_a = this.status) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
6611
|
+
return statusLower === 'success' || statusLower === 'passed';
|
|
6612
|
+
}
|
|
6613
|
+
get isFailed() {
|
|
6614
|
+
var _a;
|
|
6615
|
+
return ((_a = this.status) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === 'failed';
|
|
6616
|
+
}
|
|
6617
|
+
}
|
|
6618
|
+
AiLogsWithReasoningComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AiLogsWithReasoningComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
6619
|
+
AiLogsWithReasoningComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: AiLogsWithReasoningComponent, selector: "cqa-ai-logs-with-reasoning", inputs: { status: "status", text: "text", description: "description", reasoning: "reasoning", duration: "duration" }, host: { classAttribute: "cqa-ui-root" }, usesInheritance: true, ngImport: i0, template: "<div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-py-[5.5px] cqa-px-3\">\n <!-- Status Icon -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-3 cqa-h-3\">\n <svg *ngIf=\"isSuccess\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#00A63E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M4.5 6L5.5 7L7.5 5\" stroke=\"#00A63E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <svg *ngIf=\"isFailed\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4 4L8 8M8 4L4 8\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n <!-- AI-Agent style container -->\n <div\n class=\"cqa-font-inter cqa-rounded-md cqa-flex cqa-items-center cqa-gap-2 cqa-px-2 cqa-py-1 cqa-flex-1\"\n [ngStyle]=\"{\n 'background-color': hasReasoning ? '#EEF2FF' : '#F7FAFC',\n 'border': hasReasoning ? '1px solid #C4B5FD' : '1px solid #BEDBFF'\n }\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <svg *ngIf=\"!hasReasoning\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"16\" height=\"16\" rx=\"8\" fill=\"#DBEAFE\"/><path d=\"M5.08337 8.41675L6.75004 10.0834L10.9167 5.91675\" stroke=\"#155DFC\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <svg *ngIf=\"hasReasoning\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"16\" height=\"16\" rx=\"8\" fill=\"#ddd7f5\"/><path d=\"M5.08337 8.41675L6.75004 10.0834L10.9167 5.91675\" stroke=\"#7C3AED\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <svg *ngIf=\"!hasReasoning\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"20\" height=\"20\" rx=\"4\" fill=\"#FEF3C6\"/><path d=\"M10.5 9V5.5L6 11H9.5V14.5L14 9H10.5Z\" stroke=\"#E17100\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <svg *ngIf=\"hasReasoning\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect width=\"20\" height=\"20\" rx=\"4\" fill=\"#ddd7f5\"/>\n <path d=\"M8.8315 10.5H11.168M10 3.5V4M13.182 4.818L12.8285 5.1715M14.5 8H14M6 8H5.5M7.1715 5.1715L6.818 4.818M8.232 9.768C7.88243 9.41834 7.6444 8.97288 7.54799 8.48795C7.45158 8.00301 7.50113 7.50038 7.69036 7.04361C7.8796 6.58683 8.20003 6.19642 8.61114 5.92175C9.02225 5.64707 9.50557 5.50047 10 5.50047C10.4944 5.50047 10.9777 5.64707 11.3889 5.92175C11.8 6.19642 12.1204 6.58683 12.3096 7.04361C12.4989 7.50038 12.5484 8.00301 12.452 8.48795C12.3556 8.97288 12.1176 9.41834 11.768 9.768L11.494 10.0415C11.3374 10.1982 11.2131 10.3842 11.1283 10.5889C11.0436 10.7936 11 11.0129 11 11.2345V11.5C11 11.7652 10.8946 12.0196 10.7071 12.2071C10.5196 12.3946 10.2652 12.5 10 12.5C9.73478 12.5 9.48043 12.3946 9.29289 12.2071C9.10536 12.0196 9 11.7652 9 11.5V11.2345C9 10.787 8.822 10.3575 8.506 10.0415L8.232 9.768Z\" stroke=\"#7C3AED\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n <span\n class=\"cqa-flex-1 cqa-text-[12px] cqa-leading-[15px] cqa-font-semibold\" style=\"word-break: break-word;\"\n [ngStyle]=\"{ color: hasReasoning ? '#4C1D95' : '#0B0B0B' }\">\n {{ displayText }}\n </span>\n <span *ngIf=\"!hasReasoning\" class=\"cqa-text-[10px] cqa-font-inter cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\">\n {{ formatDuration(duration || 0) }}\n </span>\n </div>\n</div>\n", directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
|
|
6620
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AiLogsWithReasoningComponent, decorators: [{
|
|
6621
|
+
type: Component,
|
|
6622
|
+
args: [{ selector: 'cqa-ai-logs-with-reasoning', host: { class: 'cqa-ui-root' }, template: "<div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-py-[5.5px] cqa-px-3\">\n <!-- Status Icon -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-3 cqa-h-3\">\n <svg *ngIf=\"isSuccess\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#00A63E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M4.5 6L5.5 7L7.5 5\" stroke=\"#00A63E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <svg *ngIf=\"isFailed\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4 4L8 8M8 4L4 8\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n <!-- AI-Agent style container -->\n <div\n class=\"cqa-font-inter cqa-rounded-md cqa-flex cqa-items-center cqa-gap-2 cqa-px-2 cqa-py-1 cqa-flex-1\"\n [ngStyle]=\"{\n 'background-color': hasReasoning ? '#EEF2FF' : '#F7FAFC',\n 'border': hasReasoning ? '1px solid #C4B5FD' : '1px solid #BEDBFF'\n }\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <svg *ngIf=\"!hasReasoning\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"16\" height=\"16\" rx=\"8\" fill=\"#DBEAFE\"/><path d=\"M5.08337 8.41675L6.75004 10.0834L10.9167 5.91675\" stroke=\"#155DFC\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <svg *ngIf=\"hasReasoning\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"16\" height=\"16\" rx=\"8\" fill=\"#ddd7f5\"/><path d=\"M5.08337 8.41675L6.75004 10.0834L10.9167 5.91675\" stroke=\"#7C3AED\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <svg *ngIf=\"!hasReasoning\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"20\" height=\"20\" rx=\"4\" fill=\"#FEF3C6\"/><path d=\"M10.5 9V5.5L6 11H9.5V14.5L14 9H10.5Z\" stroke=\"#E17100\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <svg *ngIf=\"hasReasoning\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect width=\"20\" height=\"20\" rx=\"4\" fill=\"#ddd7f5\"/>\n <path d=\"M8.8315 10.5H11.168M10 3.5V4M13.182 4.818L12.8285 5.1715M14.5 8H14M6 8H5.5M7.1715 5.1715L6.818 4.818M8.232 9.768C7.88243 9.41834 7.6444 8.97288 7.54799 8.48795C7.45158 8.00301 7.50113 7.50038 7.69036 7.04361C7.8796 6.58683 8.20003 6.19642 8.61114 5.92175C9.02225 5.64707 9.50557 5.50047 10 5.50047C10.4944 5.50047 10.9777 5.64707 11.3889 5.92175C11.8 6.19642 12.1204 6.58683 12.3096 7.04361C12.4989 7.50038 12.5484 8.00301 12.452 8.48795C12.3556 8.97288 12.1176 9.41834 11.768 9.768L11.494 10.0415C11.3374 10.1982 11.2131 10.3842 11.1283 10.5889C11.0436 10.7936 11 11.0129 11 11.2345V11.5C11 11.7652 10.8946 12.0196 10.7071 12.2071C10.5196 12.3946 10.2652 12.5 10 12.5C9.73478 12.5 9.48043 12.3946 9.29289 12.2071C9.10536 12.0196 9 11.7652 9 11.5V11.2345C9 10.787 8.822 10.3575 8.506 10.0415L8.232 9.768Z\" stroke=\"#7C3AED\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n <span\n class=\"cqa-flex-1 cqa-text-[12px] cqa-leading-[15px] cqa-font-semibold\" style=\"word-break: break-word;\"\n [ngStyle]=\"{ color: hasReasoning ? '#4C1D95' : '#0B0B0B' }\">\n {{ displayText }}\n </span>\n <span *ngIf=\"!hasReasoning\" class=\"cqa-text-[10px] cqa-font-inter cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\">\n {{ formatDuration(duration || 0) }}\n </span>\n </div>\n</div>\n", styles: [] }]
|
|
6623
|
+
}], propDecorators: { status: [{
|
|
6624
|
+
type: Input
|
|
6625
|
+
}], text: [{
|
|
6626
|
+
type: Input
|
|
6627
|
+
}], description: [{
|
|
6628
|
+
type: Input
|
|
6629
|
+
}], reasoning: [{
|
|
6630
|
+
type: Input
|
|
6631
|
+
}], duration: [{
|
|
6632
|
+
type: Input
|
|
6633
|
+
}] } });
|
|
6634
|
+
|
|
6598
6635
|
/**
|
|
6599
6636
|
* Component that renders the appropriate step component based on the step type.
|
|
6600
6637
|
* Uses dynamic component loading and an injection token to break circular dependencies
|
|
@@ -8557,6 +8594,9 @@ class VisualComparisonComponent {
|
|
|
8557
8594
|
return 'cqa-text-[#9CA3AF] cqa-bg-[#f8f8f8]';
|
|
8558
8595
|
}
|
|
8559
8596
|
}
|
|
8597
|
+
trackByLogIndex(index) {
|
|
8598
|
+
return index;
|
|
8599
|
+
}
|
|
8560
8600
|
onImageClick(type) {
|
|
8561
8601
|
var _a, _b, _c;
|
|
8562
8602
|
const dialogData = {
|
|
@@ -8580,10 +8620,10 @@ class VisualComparisonComponent {
|
|
|
8580
8620
|
}
|
|
8581
8621
|
}
|
|
8582
8622
|
VisualComparisonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: VisualComparisonComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1$4.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
|
|
8583
|
-
VisualComparisonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: VisualComparisonComponent, selector: "cqa-visual-comparison", inputs: { screenshots: "screenshots", logs: "logs", showFullLogsLink: "showFullLogsLink", isUploadingBaseline: "isUploadingBaseline", isMakingCurrentBaseline: "isMakingCurrentBaseline", isLive: "isLive", testStepResultId: "testStepResultId" }, outputs: { makeCurrentBaseline: "makeCurrentBaseline", uploadBaseline: "uploadBaseline", analyze: "analyze", viewFullLogs: "viewFullLogs" }, host: { classAttribute: "cqa-ui-root" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }, { propertyName: "baselineImage", first: true, predicate: ["baselineImage"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-grid cqa-grid-cols-12 cqa-gap-x-4 cqa-w-full cqa-max-h-[200px] cqa-h-full cqa-overflow-hidden\">\n <!-- Left Panel: Screenshots & Visual Comparison -->\n <div class=\"cqa-col-span-9 cqa-border cqa-border-solid cqa-border-[##E5E5E5] cqa-rounded-[10px] cqa-pt-2 cqa-px-3 cqa-pb-1 cqa-h-full cqa-max-h-[200px] cqa-overflow-auto cqa-font-inter\"\n style=\"scrollbar-width: thin;\">\n <div class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-medium cqa-text-[#0A0A0A] cqa-flex cqa-items-center cqa-gap-2 cqa-mb-2\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M12.6667 2H3.33333C2.59695 2 2 2.59695 2 3.33333V12.6667C2 13.403 2.59695 14 3.33333 14H12.6667C13.403 14 14 13.403 14 12.6667V3.33333C14 2.59695 13.403 2 12.6667 2Z\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6.00033 7.33268C6.73671 7.33268 7.33366 6.73573 7.33366 5.99935C7.33366 5.26297 6.73671 4.66602 6.00033 4.66602C5.26395 4.66602 4.66699 5.26297 4.66699 5.99935C4.66699 6.73573 5.26395 7.33268 6.00033 7.33268Z\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M14 10.0004L11.9427 7.94312C11.6926 7.69315 11.3536 7.55273 11 7.55273C10.6464 7.55273 10.3074 7.69315 10.0573 7.94312L4 14.0004\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n Screenshots & Visual Comparison\n </div>\n \n <!-- Screenshot Comparison Grid -->\n <div class=\"cqa-grid cqa-grid-cols-3 cqa-gap-3 cqa-mb-2\">\n <!-- Baseline -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <div class=\"cqa-text-[11px] cqa-leading-[100%] cqa-text-[#737373]\">Baseline</div>\n <div class=\"cqa-bg-[#F5F5F5] cqa-rounded-[10px] cqa-border cqa-border-solid cqa-border-[#E5E5E5] cqa-flex cqa-items-center cqa-justify-center cqa-h-[112px] cqa-cursor-pointer\" (click)=\"onImageClick('baseline')\">\n <div *ngIf=\"!screenshots?.baseline\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M25.3333 4H6.66667C5.19391 4 4 5.19391 4 6.66667V25.3333C4 26.8061 5.19391 28 6.66667 28H25.3333C26.8061 28 28 26.8061 28 25.3333V6.66667C28 5.19391 26.8061 4 25.3333 4Z\" stroke=\"#737373\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M11.9997 14.6673C13.4724 14.6673 14.6663 13.4734 14.6663 12.0007C14.6663 10.5279 13.4724 9.33398 11.9997 9.33398C10.5269 9.33398 9.33301 10.5279 9.33301 12.0007C9.33301 13.4734 10.5269 14.6673 11.9997 14.6673Z\" stroke=\"#737373\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M28 20.0009L23.8853 15.8862C23.3853 15.3863 22.7071 15.1055 22 15.1055C21.2929 15.1055 20.6147 15.3863 20.1147 15.8862L8 28.0009\" stroke=\"#737373\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <img #baselineImage *ngIf=\"baselineImageUrl\" [src]=\"baselineImageUrl\" alt=\"Baseline\" class=\"cqa-w-full cqa-h-full cqa-object-cover cqa-rounded-lg\" />\n </div>\n </div>\n\n <!-- Current -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <div class=\"cqa-text-[11px] cqa-leading-[100%] cqa-text-[#737373]\">Current</div>\n <div class=\"cqa-bg-[#FEF2F3] cqa-rounded-[10px] cqa-border cqa-border-solid cqa-border-[#F9C2C5] cqa-flex cqa-items-center cqa-justify-center cqa-h-[112px] cqa-cursor-pointer\" (click)=\"onImageClick('current')\">\n <div *ngIf=\"!screenshots?.current\" class=\"cqa-flex cqa-flex-col cqa-items-center cqa-gap-2 cqa-text-[#EF4444]\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M25.3333 4H6.66667C5.19391 4 4 5.19391 4 6.66667V25.3333C4 26.8061 5.19391 28 6.66667 28H25.3333C26.8061 28 28 26.8061 28 25.3333V6.66667C28 5.19391 26.8061 4 25.3333 4Z\" stroke=\"#E7000B\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M11.9997 14.6673C13.4724 14.6673 14.6663 13.4734 14.6663 12.0007C14.6663 10.5279 13.4724 9.33398 11.9997 9.33398C10.5269 9.33398 9.33301 10.5279 9.33301 12.0007C9.33301 13.4734 10.5269 14.6673 11.9997 14.6673Z\" stroke=\"#E7000B\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M28 20.0009L23.8853 15.8862C23.3853 15.3863 22.7071 15.1055 22 15.1055C21.2929 15.1055 20.6147 15.3863 20.1147 15.8862L8 28.0009\" stroke=\"#E7000B\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <img *ngIf=\"screenshots?.current\" [src]=\"screenshots.current\" alt=\"Current\" class=\"cqa-w-full cqa-h-full cqa-object-cover cqa-rounded-lg\" />\n </div>\n </div>\n\n <!-- Difference -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <div class=\"cqa-text-[11px] cqa-leading-[100%] cqa-text-[#737373]\">Difference</div>\n <div class=\"cqa-bg-[#FEF2F3] cqa-rounded-[10px] cqa-border cqa-border-solid cqa-border-[#F9C2C5] cqa-flex cqa-items-center cqa-justify-center cqa-h-[112px] cqa-cursor-pointer\" (click)=\"onImageClick('difference')\">\n <div *ngIf=\"!screenshots?.difference\" class=\"cqa-flex cqa-flex-col cqa-items-center cqa-gap-2 cqa-text-[#EF4444]\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M25.3333 4H6.66667C5.19391 4 4 5.19391 4 6.66667V25.3333C4 26.8061 5.19391 28 6.66667 28H25.3333C26.8061 28 28 26.8061 28 25.3333V6.66667C28 5.19391 26.8061 4 25.3333 4Z\" stroke=\"#E7000B\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M11.9997 14.6673C13.4724 14.6673 14.6663 13.4734 14.6663 12.0007C14.6663 10.5279 13.4724 9.33398 11.9997 9.33398C10.5269 9.33398 9.33301 10.5279 9.33301 12.0007C9.33301 13.4734 10.5269 14.6673 11.9997 14.6673Z\" stroke=\"#E7000B\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M28 20.0009L23.8853 15.8862C23.3853 15.3863 22.7071 15.1055 22 15.1055C21.2929 15.1055 20.6147 15.3863 20.1147 15.8862L8 28.0009\" stroke=\"#E7000B\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <img *ngIf=\"screenshots?.difference\" [src]=\"screenshots.difference\" alt=\"Difference\" class=\"cqa-w-full cqa-h-full cqa-object-cover cqa-rounded-lg\" />\n </div>\n </div>\n </div>\n\n <!-- Action Buttons -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-end cqa-gap-2 cqa-flex-wrap\">\n <button \n (click)=\"onMakeCurrentBaseline()\"\n [disabled]=\"!isCurrentImageAvailable || isMakingCurrentBaseline?.[testStepResultId] === true\"\n [class.cqa-opacity-50]=\"!isCurrentImageAvailable || isMakingCurrentBaseline?.[testStepResultId] === true\"\n [class.cqa-cursor-not-allowed]=\"!isCurrentImageAvailable || isMakingCurrentBaseline?.[testStepResultId] === true\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-pl-2 cqa-pr-4 cqa-py-[2px] cqa-rounded-lg cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-transparent cqa-text-[#212122] cqa-border cqa-border-solid cqa-border-[#212122] disabled:cqa-cursor-not-allowed\">\n <svg *ngIf=\"!isMakingCurrentBaseline?.[testStepResultId]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4.39754 7.93752L2.31254 5.85252L1.60254 6.55752L4.39754 9.35252L10.3975 3.35252L9.69254 2.64752L4.39754 7.93752Z\" fill=\"black\"/></svg>\n <svg *ngIf=\"isMakingCurrentBaseline?.[testStepResultId] === true\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" opacity=\"0.3\"/>\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" stroke-dashoffset=\"2\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" values=\"0 6 6;360 6 6\" dur=\"1s\" repeatCount=\"indefinite\"/>\n </circle>\n </svg>\n <span>{{ isMakingCurrentBaseline?.[testStepResultId] === true ? 'Loading...' : 'Make current baseline' }}</span>\n </button>\n <button \n (click)=\"onUploadBaseline()\"\n [disabled]=\"isUploadingBaseline?.[testStepResultId] === true\"\n [class.cqa-opacity-50]=\"isUploadingBaseline?.[testStepResultId] === true\"\n [class.cqa-cursor-not-allowed]=\"isUploadingBaseline?.[testStepResultId] === true\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-pl-2 cqa-pr-4 cqa-py-[2px] cqa-rounded-lg cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-transparent cqa-text-[#212122] cqa-border cqa-border-solid cqa-border-[#212122] disabled:cqa-cursor-not-allowed\">\n <svg *ngIf=\"!isUploadingBaseline?.[testStepResultId]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M9 7.5V9H3V7.5H2V9C2 9.55 2.45 10 3 10H9C9.55 10 10 9.55 10 9V7.5H9ZM3.5 4.5L4.205 5.205L5.5 3.915V8H6.5V3.915L7.795 5.205L8.5 4.5L6 2L3.5 4.5Z\" fill=\"black\"/></svg>\n <svg *ngIf=\"isUploadingBaseline?.[testStepResultId] === true\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" style=\"animation: spin 1s linear infinite;\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" opacity=\"0.3\"/>\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" stroke-dashoffset=\"2\"/>\n </svg>\n <span>{{ isUploadingBaseline?.[testStepResultId] === true ? 'Uploading...' : 'Upload baseline' }}</span>\n </button>\n <!-- Hidden file input -->\n <input \n #fileInput\n type=\"file\" \n accept=\"image/png,image/jpeg,image/jpg,image/webp\"\n (change)=\"onFileSelected($event)\"\n style=\"display: none;\" \n />\n <!-- <button \n (click)=\"onAnalyze()\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-pl-2 cqa-pr-4 cqa-py-[2px] cqa-rounded-lg cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-transparent cqa-text-[#212122] cqa-border cqa-border-solid cqa-border-[#212122]\">\n <svg width=\"11\" height=\"12\" viewBox=\"0 0 11 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M5.5115 0C5.57931 0.0303178 5.60828 0.104354 5.63604 0.173128C5.64996 0.2132 5.66273 0.253489 5.67513 0.2941C5.67998 0.309662 5.68484 0.325224 5.68984 0.341258C5.7543 0.550673 5.81172 0.762331 5.86946 0.97384C5.88251 1.02159 5.89563 1.06932 5.90874 1.11704C5.97551 1.36005 6.04177 1.6032 6.10767 1.84646C6.11693 1.88062 6.12619 1.91479 6.13545 1.94895C6.16156 2.04527 6.18764 2.14159 6.21357 2.23796C6.26837 2.44159 6.32467 2.64463 6.38463 2.84668C6.38986 2.86435 6.3951 2.88203 6.4005 2.90024C6.55624 3.42 6.77701 3.88583 7.13888 4.28262C7.14784 4.29294 7.1568 4.30325 7.16603 4.31388C7.3205 4.48583 7.51873 4.62361 7.71687 4.73481C7.72696 4.74057 7.73705 4.74632 7.74745 4.75225C8.33051 5.079 9.03162 5.22272 9.66313 5.414C9.93984 5.49787 10.2157 5.58438 10.4905 5.6747C10.5099 5.68105 10.5292 5.68738 10.5485 5.6937C10.6062 5.7126 10.6639 5.73182 10.7215 5.7513C10.7349 5.75572 10.7483 5.76015 10.7621 5.76471C10.8415 5.79208 10.9174 5.82439 10.9825 5.88036C11.0023 5.92558 11.0023 5.92558 10.9969 5.9708C10.9336 6.03648 10.8707 6.06728 10.7871 6.09733C10.7751 6.10176 10.7632 6.1062 10.7508 6.11077C10.6096 6.16244 10.4665 6.20766 10.3232 6.25247C10.2938 6.26174 10.2644 6.27101 10.235 6.28028C10.0537 6.33735 9.87199 6.3932 9.69014 6.44842C9.45061 6.52117 9.21143 6.59512 8.97249 6.66991C8.93334 6.68216 8.89418 6.69437 8.85501 6.70654C8.64931 6.77048 8.44462 6.83671 8.24162 6.90944C8.22478 6.91545 8.20794 6.92147 8.19059 6.92766C7.51069 7.17443 6.99245 7.63478 6.66809 8.30799C6.49321 8.68634 6.39006 9.09548 6.28483 9.49929C6.25637 9.60825 6.22611 9.7166 6.1955 9.82492C6.17149 9.91015 6.14803 9.99551 6.12515 10.0811C6.12243 10.0913 6.1197 10.1014 6.1169 10.1119C6.1037 10.1612 6.09056 10.2106 6.07752 10.2599C6.04413 10.3851 6.00817 10.5092 5.97123 10.6332C5.90567 10.8536 5.84601 11.0757 5.78672 11.298C5.69732 11.6328 5.69732 11.6328 5.64662 11.7937C5.64326 11.8045 5.6399 11.8153 5.63644 11.8264C5.61793 11.8837 5.5989 11.9364 5.56388 11.9849C5.5106 11.9972 5.5106 11.9972 5.46273 12C5.40801 11.9168 5.37177 11.8361 5.34273 11.7401C5.33851 11.7265 5.33428 11.7129 5.32993 11.6989C5.27614 11.5233 5.22807 11.3459 5.17999 11.1686C5.16898 11.1281 5.15791 11.0875 5.14685 11.047C5.0644 10.7448 4.98331 10.4423 4.90234 10.1397C4.56509 8.64299 4.56509 8.64299 3.71433 7.43288C3.7007 7.42128 3.68706 7.40968 3.67302 7.39773C3.1156 6.93203 2.3813 6.75959 1.70885 6.55751C1.54254 6.50749 1.37628 6.45724 1.21004 6.40697C1.1955 6.40258 1.1955 6.40258 1.18067 6.39809C0.940881 6.32556 0.701157 6.25283 0.462274 6.17711C0.452168 6.17393 0.442063 6.17075 0.431651 6.16747C0.0646543 6.05178 0.0646543 6.05178 0.000790211 5.9708C-0.00101599 5.93406 -0.00101599 5.93406 0.0152398 5.89543C0.0819909 5.8272 0.14676 5.79797 0.234862 5.76825C0.247618 5.76378 0.260375 5.75931 0.273518 5.75471C0.312587 5.7411 0.351741 5.72779 0.390929 5.71455C0.402112 5.71073 0.413295 5.7069 0.424817 5.70296C0.503904 5.6759 0.583275 5.64986 0.662762 5.62412C0.682294 5.61777 0.682294 5.61777 0.70222 5.61129C1.04166 5.50116 1.38332 5.39867 1.72487 5.29595C1.97939 5.21939 2.23347 5.14157 2.48674 5.06065C2.49838 5.05694 2.51001 5.05324 2.52201 5.04943C3.10872 4.86262 3.68229 4.59755 4.06112 4.0716C4.06679 4.0638 4.07247 4.05599 4.07831 4.04796C4.50019 3.4642 4.6647 2.7543 4.8485 2.06161C4.90896 1.83379 4.97015 1.60619 5.03155 1.37865C5.04856 1.31564 5.06553 1.25263 5.08244 1.18959C5.15037 0.936385 5.21932 0.683523 5.29222 0.431818C5.29904 0.408248 5.30583 0.384667 5.31259 0.361076C5.41466 0.00531681 5.41466 0.00531681 5.5115 0Z\" fill=\"#161617\"/><path d=\"M8.84391 0.740443C8.91024 0.818762 8.92349 0.910806 8.94415 1.01081C9.01305 1.32499 9.09241 1.61388 9.36787 1.79638C9.53782 1.89443 9.74037 1.93904 9.92867 1.98118C10.0082 1.99933 10.0753 2.02341 10.1435 2.07158C10.1588 2.09701 10.1588 2.09701 10.1579 2.14129C10.1421 2.19513 10.1282 2.2125 10.0866 2.24774C10.041 2.26364 10.041 2.26364 9.98633 2.27601C9.96564 2.28096 9.94496 2.28597 9.9243 2.29102C9.91322 2.2937 9.90215 2.29638 9.89075 2.29914C9.55401 2.38039 9.55401 2.38039 9.26295 2.56428C9.25348 2.57222 9.24402 2.58017 9.23427 2.58836C9.02625 2.7797 8.98226 3.098 8.91963 3.36464C8.91605 3.37928 8.91246 3.39393 8.90876 3.40901C8.90566 3.42198 8.90255 3.43494 8.89935 3.4483C8.88584 3.48788 8.87183 3.51369 8.84391 3.54402C8.76614 3.55432 8.76614 3.55432 8.72831 3.54402C8.66814 3.49537 8.65468 3.43996 8.63896 3.3655C8.63633 3.35397 8.63369 3.34244 8.63098 3.33056C8.62259 3.29374 8.61447 3.25686 8.60639 3.21995C8.54302 2.93259 8.47148 2.65064 8.21879 2.4822C8.02131 2.36732 7.78118 2.31298 7.56045 2.26911C7.49996 2.25597 7.4653 2.23944 7.42785 2.18745C7.41972 2.1347 7.41972 2.1347 7.42785 2.08194C7.48541 2.01979 7.54597 2.00462 7.62382 1.98585C7.64835 1.97952 7.67286 1.97314 7.69737 1.96671C7.71003 1.96342 7.72269 1.96012 7.73574 1.95673C7.80032 1.93939 7.86425 1.91995 7.92817 1.90012C7.93978 1.89661 7.95139 1.89309 7.96336 1.88947C8.09329 1.84895 8.20541 1.79712 8.30927 1.70512C8.31896 1.6968 8.32864 1.68848 8.33862 1.67992C8.50026 1.52817 8.55518 1.3002 8.60504 1.08748C8.60884 1.07133 8.61264 1.05518 8.61655 1.03854C8.62411 1.0061 8.63154 0.973622 8.63882 0.94111C8.64403 0.918489 8.64403 0.918489 8.64935 0.895412C8.65238 0.881899 8.65542 0.868385 8.65855 0.854462C8.67186 0.811441 8.68935 0.77766 8.71386 0.740443C8.76096 0.715878 8.79401 0.726983 8.84391 0.740443Z\" fill=\"#414146\"/><path d=\"M2.19446 8.32962C2.21166 8.32975 2.21166 8.32975 2.22919 8.32988C2.35253 8.3338 2.43597 8.37503 2.5268 8.46151C2.6325 8.58061 2.6813 8.71497 2.67852 8.87549C2.66666 9.00565 2.59307 9.11929 2.50282 9.20727C2.39658 9.29672 2.28941 9.32628 2.15366 9.32215C2.03919 9.30825 1.93151 9.25153 1.85038 9.16618C1.7495 9.02258 1.72 8.89087 1.73479 8.71398C1.76533 8.57472 1.85337 8.46167 1.96598 8.38238C2.04421 8.34101 2.10713 8.32886 2.19446 8.32962Z\" fill=\"#4C4C51\"/></svg>\n Analyze\n </button> -->\n </div>\n </div>\n\n <!-- Right Panel: Logs -->\n <div class=\"cqa-col-span-3 cqa-border cqa-border-solid cqa-border-[##E5E5E5] cqa-rounded-[10px] cqa-py-2 cqa-px-3 cqa-h-full cqa-max-h-[200px] cqa-overflow-auto\"\n style=\"scrollbar-width: thin;\">\n <div class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-medium cqa-text-[#0A0A0A] cqa-flex cqa-items-center cqa-gap-2 cqa-mb-2\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.6666 12L14.6666 8L10.6666 4\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M5.33337 4L1.33337 8L5.33337 12\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n Logs\n </div>\n \n <div class=\"cqa-flex cqa-flex-col cqa-gap-2 \">\n <div class=\"cqa-text-[11px] cqa-leading-[100%] cqa-text-[#737373]\">Console</div>\n \n <div *ngFor=\"let log of logs\" class=\"cqa-px-2 cqa-py-[2px] cqa-rounded cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-break-words\" [ngClass]=\"getLogClass(log.level)\">\n {{ log.message }}\n </div>\n \n <div *ngIf=\"!logs || logs.length === 0\" class=\"cqa-px-2 cqa-py-[2px] cqa-rounded cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF] cqa-bg-[#f8f8f8] cqa-text-center\">\n No logs available\n </div>\n </div>\n\n <!-- <a \n *ngIf=\"showFullLogsLink && logs?.length\"\n (click)=\"onViewFullLogs()\"\n class=\"cqa-text-[10px] cqa-leading-[15px] cqa-text-[#3F43EE] cqa-font-medium cqa-flex cqa-items-center cqa-justify-end cqa-gap-[2px] cqa-cursor-pointer hover:cqa-underline cqa-mt-4\">\n View full logs Iterations\n <div><svg width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M2.03833 6.74335L2.62833 7.33335L5.96166 4.00002L2.62833 0.666687L2.03833 1.25669L4.78166 4.00002L2.03833 6.74335Z\" fill=\"#3F43EE\"/></svg></div>\n </a> -->\n </div>\n</div>\n\n<style>\n @keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n</style>", styles: ["\n @keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n"], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
|
|
8623
|
+
VisualComparisonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: VisualComparisonComponent, selector: "cqa-visual-comparison", inputs: { screenshots: "screenshots", logs: "logs", showFullLogsLink: "showFullLogsLink", isUploadingBaseline: "isUploadingBaseline", isMakingCurrentBaseline: "isMakingCurrentBaseline", isLive: "isLive", testStepResultId: "testStepResultId" }, outputs: { makeCurrentBaseline: "makeCurrentBaseline", uploadBaseline: "uploadBaseline", analyze: "analyze", viewFullLogs: "viewFullLogs" }, host: { classAttribute: "cqa-ui-root" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }, { propertyName: "baselineImage", first: true, predicate: ["baselineImage"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-grid cqa-grid-cols-12 cqa-gap-x-4 cqa-w-full cqa-max-h-[200px] cqa-h-full cqa-overflow-hidden\">\n <!-- Left Panel: Screenshots & Visual Comparison -->\n <div class=\"cqa-col-span-9 cqa-border cqa-border-solid cqa-border-[##E5E5E5] cqa-rounded-[10px] cqa-pt-2 cqa-px-3 cqa-pb-1 cqa-h-full cqa-max-h-[200px] cqa-overflow-auto cqa-font-inter\"\n style=\"scrollbar-width: thin;\">\n <div class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-medium cqa-text-[#0A0A0A] cqa-flex cqa-items-center cqa-gap-2 cqa-mb-2\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M12.6667 2H3.33333C2.59695 2 2 2.59695 2 3.33333V12.6667C2 13.403 2.59695 14 3.33333 14H12.6667C13.403 14 14 13.403 14 12.6667V3.33333C14 2.59695 13.403 2 12.6667 2Z\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6.00033 7.33268C6.73671 7.33268 7.33366 6.73573 7.33366 5.99935C7.33366 5.26297 6.73671 4.66602 6.00033 4.66602C5.26395 4.66602 4.66699 5.26297 4.66699 5.99935C4.66699 6.73573 5.26395 7.33268 6.00033 7.33268Z\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M14 10.0004L11.9427 7.94312C11.6926 7.69315 11.3536 7.55273 11 7.55273C10.6464 7.55273 10.3074 7.69315 10.0573 7.94312L4 14.0004\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n Screenshots & Visual Comparison\n </div>\n \n <!-- Screenshot Comparison Grid -->\n <div class=\"cqa-grid cqa-grid-cols-3 cqa-gap-3 cqa-mb-2\">\n <!-- Baseline -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <div class=\"cqa-text-[11px] cqa-leading-[100%] cqa-text-[#737373]\">Baseline</div>\n <div class=\"cqa-bg-[#F5F5F5] cqa-rounded-[10px] cqa-border cqa-border-solid cqa-border-[#E5E5E5] cqa-flex cqa-items-center cqa-justify-center cqa-h-[112px] cqa-cursor-pointer\" (click)=\"onImageClick('baseline')\">\n <div *ngIf=\"!screenshots?.baseline\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M25.3333 4H6.66667C5.19391 4 4 5.19391 4 6.66667V25.3333C4 26.8061 5.19391 28 6.66667 28H25.3333C26.8061 28 28 26.8061 28 25.3333V6.66667C28 5.19391 26.8061 4 25.3333 4Z\" stroke=\"#737373\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M11.9997 14.6673C13.4724 14.6673 14.6663 13.4734 14.6663 12.0007C14.6663 10.5279 13.4724 9.33398 11.9997 9.33398C10.5269 9.33398 9.33301 10.5279 9.33301 12.0007C9.33301 13.4734 10.5269 14.6673 11.9997 14.6673Z\" stroke=\"#737373\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M28 20.0009L23.8853 15.8862C23.3853 15.3863 22.7071 15.1055 22 15.1055C21.2929 15.1055 20.6147 15.3863 20.1147 15.8862L8 28.0009\" stroke=\"#737373\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <img #baselineImage *ngIf=\"baselineImageUrl\" [src]=\"baselineImageUrl\" alt=\"Baseline\" class=\"cqa-w-full cqa-h-full cqa-object-cover cqa-rounded-lg\" />\n </div>\n </div>\n\n <!-- Current -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <div class=\"cqa-text-[11px] cqa-leading-[100%] cqa-text-[#737373]\">Current</div>\n <div class=\"cqa-bg-[#FEF2F3] cqa-rounded-[10px] cqa-border cqa-border-solid cqa-border-[#F9C2C5] cqa-flex cqa-items-center cqa-justify-center cqa-h-[112px] cqa-cursor-pointer\" (click)=\"onImageClick('current')\">\n <div *ngIf=\"!screenshots?.current\" class=\"cqa-flex cqa-flex-col cqa-items-center cqa-gap-2 cqa-text-[#EF4444]\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M25.3333 4H6.66667C5.19391 4 4 5.19391 4 6.66667V25.3333C4 26.8061 5.19391 28 6.66667 28H25.3333C26.8061 28 28 26.8061 28 25.3333V6.66667C28 5.19391 26.8061 4 25.3333 4Z\" stroke=\"#E7000B\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M11.9997 14.6673C13.4724 14.6673 14.6663 13.4734 14.6663 12.0007C14.6663 10.5279 13.4724 9.33398 11.9997 9.33398C10.5269 9.33398 9.33301 10.5279 9.33301 12.0007C9.33301 13.4734 10.5269 14.6673 11.9997 14.6673Z\" stroke=\"#E7000B\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M28 20.0009L23.8853 15.8862C23.3853 15.3863 22.7071 15.1055 22 15.1055C21.2929 15.1055 20.6147 15.3863 20.1147 15.8862L8 28.0009\" stroke=\"#E7000B\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <img *ngIf=\"screenshots?.current\" [src]=\"screenshots.current\" alt=\"Current\" class=\"cqa-w-full cqa-h-full cqa-object-cover cqa-rounded-lg\" />\n </div>\n </div>\n\n <!-- Difference -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <div class=\"cqa-text-[11px] cqa-leading-[100%] cqa-text-[#737373]\">Difference</div>\n <div class=\"cqa-bg-[#FEF2F3] cqa-rounded-[10px] cqa-border cqa-border-solid cqa-border-[#F9C2C5] cqa-flex cqa-items-center cqa-justify-center cqa-h-[112px] cqa-cursor-pointer\" (click)=\"onImageClick('difference')\">\n <div *ngIf=\"!screenshots?.difference\" class=\"cqa-flex cqa-flex-col cqa-items-center cqa-gap-2 cqa-text-[#EF4444]\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M25.3333 4H6.66667C5.19391 4 4 5.19391 4 6.66667V25.3333C4 26.8061 5.19391 28 6.66667 28H25.3333C26.8061 28 28 26.8061 28 25.3333V6.66667C28 5.19391 26.8061 4 25.3333 4Z\" stroke=\"#E7000B\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M11.9997 14.6673C13.4724 14.6673 14.6663 13.4734 14.6663 12.0007C14.6663 10.5279 13.4724 9.33398 11.9997 9.33398C10.5269 9.33398 9.33301 10.5279 9.33301 12.0007C9.33301 13.4734 10.5269 14.6673 11.9997 14.6673Z\" stroke=\"#E7000B\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M28 20.0009L23.8853 15.8862C23.3853 15.3863 22.7071 15.1055 22 15.1055C21.2929 15.1055 20.6147 15.3863 20.1147 15.8862L8 28.0009\" stroke=\"#E7000B\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <img *ngIf=\"screenshots?.difference\" [src]=\"screenshots.difference\" alt=\"Difference\" class=\"cqa-w-full cqa-h-full cqa-object-cover cqa-rounded-lg\" />\n </div>\n </div>\n </div>\n\n <!-- Action Buttons -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-end cqa-gap-2 cqa-flex-wrap\">\n <button \n (click)=\"onMakeCurrentBaseline()\"\n [disabled]=\"!isCurrentImageAvailable || isMakingCurrentBaseline?.[testStepResultId] === true\"\n [class.cqa-opacity-50]=\"!isCurrentImageAvailable || isMakingCurrentBaseline?.[testStepResultId] === true\"\n [class.cqa-cursor-not-allowed]=\"!isCurrentImageAvailable || isMakingCurrentBaseline?.[testStepResultId] === true\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-pl-2 cqa-pr-4 cqa-py-[2px] cqa-rounded-lg cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-transparent cqa-text-[#212122] cqa-border cqa-border-solid cqa-border-[#212122] disabled:cqa-cursor-not-allowed\">\n <svg *ngIf=\"!isMakingCurrentBaseline?.[testStepResultId]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4.39754 7.93752L2.31254 5.85252L1.60254 6.55752L4.39754 9.35252L10.3975 3.35252L9.69254 2.64752L4.39754 7.93752Z\" fill=\"black\"/></svg>\n <svg *ngIf=\"isMakingCurrentBaseline?.[testStepResultId] === true\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" opacity=\"0.3\"/>\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" stroke-dashoffset=\"2\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" values=\"0 6 6;360 6 6\" dur=\"1s\" repeatCount=\"indefinite\"/>\n </circle>\n </svg>\n <span>{{ isMakingCurrentBaseline?.[testStepResultId] === true ? 'Loading...' : 'Make current baseline' }}</span>\n </button>\n <button \n (click)=\"onUploadBaseline()\"\n [disabled]=\"isUploadingBaseline?.[testStepResultId] === true\"\n [class.cqa-opacity-50]=\"isUploadingBaseline?.[testStepResultId] === true\"\n [class.cqa-cursor-not-allowed]=\"isUploadingBaseline?.[testStepResultId] === true\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-pl-2 cqa-pr-4 cqa-py-[2px] cqa-rounded-lg cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-transparent cqa-text-[#212122] cqa-border cqa-border-solid cqa-border-[#212122] disabled:cqa-cursor-not-allowed\">\n <svg *ngIf=\"!isUploadingBaseline?.[testStepResultId]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M9 7.5V9H3V7.5H2V9C2 9.55 2.45 10 3 10H9C9.55 10 10 9.55 10 9V7.5H9ZM3.5 4.5L4.205 5.205L5.5 3.915V8H6.5V3.915L7.795 5.205L8.5 4.5L6 2L3.5 4.5Z\" fill=\"black\"/></svg>\n <svg *ngIf=\"isUploadingBaseline?.[testStepResultId] === true\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" style=\"animation: spin 1s linear infinite;\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" opacity=\"0.3\"/>\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" stroke-dashoffset=\"2\"/>\n </svg>\n <span>{{ isUploadingBaseline?.[testStepResultId] === true ? 'Uploading...' : 'Upload baseline' }}</span>\n </button>\n <!-- Hidden file input -->\n <input \n #fileInput\n type=\"file\" \n accept=\"image/png,image/jpeg,image/jpg,image/webp\"\n (change)=\"onFileSelected($event)\"\n style=\"display: none;\" \n />\n <!-- <button \n (click)=\"onAnalyze()\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-pl-2 cqa-pr-4 cqa-py-[2px] cqa-rounded-lg cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-transparent cqa-text-[#212122] cqa-border cqa-border-solid cqa-border-[#212122]\">\n <svg width=\"11\" height=\"12\" viewBox=\"0 0 11 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M5.5115 0C5.57931 0.0303178 5.60828 0.104354 5.63604 0.173128C5.64996 0.2132 5.66273 0.253489 5.67513 0.2941C5.67998 0.309662 5.68484 0.325224 5.68984 0.341258C5.7543 0.550673 5.81172 0.762331 5.86946 0.97384C5.88251 1.02159 5.89563 1.06932 5.90874 1.11704C5.97551 1.36005 6.04177 1.6032 6.10767 1.84646C6.11693 1.88062 6.12619 1.91479 6.13545 1.94895C6.16156 2.04527 6.18764 2.14159 6.21357 2.23796C6.26837 2.44159 6.32467 2.64463 6.38463 2.84668C6.38986 2.86435 6.3951 2.88203 6.4005 2.90024C6.55624 3.42 6.77701 3.88583 7.13888 4.28262C7.14784 4.29294 7.1568 4.30325 7.16603 4.31388C7.3205 4.48583 7.51873 4.62361 7.71687 4.73481C7.72696 4.74057 7.73705 4.74632 7.74745 4.75225C8.33051 5.079 9.03162 5.22272 9.66313 5.414C9.93984 5.49787 10.2157 5.58438 10.4905 5.6747C10.5099 5.68105 10.5292 5.68738 10.5485 5.6937C10.6062 5.7126 10.6639 5.73182 10.7215 5.7513C10.7349 5.75572 10.7483 5.76015 10.7621 5.76471C10.8415 5.79208 10.9174 5.82439 10.9825 5.88036C11.0023 5.92558 11.0023 5.92558 10.9969 5.9708C10.9336 6.03648 10.8707 6.06728 10.7871 6.09733C10.7751 6.10176 10.7632 6.1062 10.7508 6.11077C10.6096 6.16244 10.4665 6.20766 10.3232 6.25247C10.2938 6.26174 10.2644 6.27101 10.235 6.28028C10.0537 6.33735 9.87199 6.3932 9.69014 6.44842C9.45061 6.52117 9.21143 6.59512 8.97249 6.66991C8.93334 6.68216 8.89418 6.69437 8.85501 6.70654C8.64931 6.77048 8.44462 6.83671 8.24162 6.90944C8.22478 6.91545 8.20794 6.92147 8.19059 6.92766C7.51069 7.17443 6.99245 7.63478 6.66809 8.30799C6.49321 8.68634 6.39006 9.09548 6.28483 9.49929C6.25637 9.60825 6.22611 9.7166 6.1955 9.82492C6.17149 9.91015 6.14803 9.99551 6.12515 10.0811C6.12243 10.0913 6.1197 10.1014 6.1169 10.1119C6.1037 10.1612 6.09056 10.2106 6.07752 10.2599C6.04413 10.3851 6.00817 10.5092 5.97123 10.6332C5.90567 10.8536 5.84601 11.0757 5.78672 11.298C5.69732 11.6328 5.69732 11.6328 5.64662 11.7937C5.64326 11.8045 5.6399 11.8153 5.63644 11.8264C5.61793 11.8837 5.5989 11.9364 5.56388 11.9849C5.5106 11.9972 5.5106 11.9972 5.46273 12C5.40801 11.9168 5.37177 11.8361 5.34273 11.7401C5.33851 11.7265 5.33428 11.7129 5.32993 11.6989C5.27614 11.5233 5.22807 11.3459 5.17999 11.1686C5.16898 11.1281 5.15791 11.0875 5.14685 11.047C5.0644 10.7448 4.98331 10.4423 4.90234 10.1397C4.56509 8.64299 4.56509 8.64299 3.71433 7.43288C3.7007 7.42128 3.68706 7.40968 3.67302 7.39773C3.1156 6.93203 2.3813 6.75959 1.70885 6.55751C1.54254 6.50749 1.37628 6.45724 1.21004 6.40697C1.1955 6.40258 1.1955 6.40258 1.18067 6.39809C0.940881 6.32556 0.701157 6.25283 0.462274 6.17711C0.452168 6.17393 0.442063 6.17075 0.431651 6.16747C0.0646543 6.05178 0.0646543 6.05178 0.000790211 5.9708C-0.00101599 5.93406 -0.00101599 5.93406 0.0152398 5.89543C0.0819909 5.8272 0.14676 5.79797 0.234862 5.76825C0.247618 5.76378 0.260375 5.75931 0.273518 5.75471C0.312587 5.7411 0.351741 5.72779 0.390929 5.71455C0.402112 5.71073 0.413295 5.7069 0.424817 5.70296C0.503904 5.6759 0.583275 5.64986 0.662762 5.62412C0.682294 5.61777 0.682294 5.61777 0.70222 5.61129C1.04166 5.50116 1.38332 5.39867 1.72487 5.29595C1.97939 5.21939 2.23347 5.14157 2.48674 5.06065C2.49838 5.05694 2.51001 5.05324 2.52201 5.04943C3.10872 4.86262 3.68229 4.59755 4.06112 4.0716C4.06679 4.0638 4.07247 4.05599 4.07831 4.04796C4.50019 3.4642 4.6647 2.7543 4.8485 2.06161C4.90896 1.83379 4.97015 1.60619 5.03155 1.37865C5.04856 1.31564 5.06553 1.25263 5.08244 1.18959C5.15037 0.936385 5.21932 0.683523 5.29222 0.431818C5.29904 0.408248 5.30583 0.384667 5.31259 0.361076C5.41466 0.00531681 5.41466 0.00531681 5.5115 0Z\" fill=\"#161617\"/><path d=\"M8.84391 0.740443C8.91024 0.818762 8.92349 0.910806 8.94415 1.01081C9.01305 1.32499 9.09241 1.61388 9.36787 1.79638C9.53782 1.89443 9.74037 1.93904 9.92867 1.98118C10.0082 1.99933 10.0753 2.02341 10.1435 2.07158C10.1588 2.09701 10.1588 2.09701 10.1579 2.14129C10.1421 2.19513 10.1282 2.2125 10.0866 2.24774C10.041 2.26364 10.041 2.26364 9.98633 2.27601C9.96564 2.28096 9.94496 2.28597 9.9243 2.29102C9.91322 2.2937 9.90215 2.29638 9.89075 2.29914C9.55401 2.38039 9.55401 2.38039 9.26295 2.56428C9.25348 2.57222 9.24402 2.58017 9.23427 2.58836C9.02625 2.7797 8.98226 3.098 8.91963 3.36464C8.91605 3.37928 8.91246 3.39393 8.90876 3.40901C8.90566 3.42198 8.90255 3.43494 8.89935 3.4483C8.88584 3.48788 8.87183 3.51369 8.84391 3.54402C8.76614 3.55432 8.76614 3.55432 8.72831 3.54402C8.66814 3.49537 8.65468 3.43996 8.63896 3.3655C8.63633 3.35397 8.63369 3.34244 8.63098 3.33056C8.62259 3.29374 8.61447 3.25686 8.60639 3.21995C8.54302 2.93259 8.47148 2.65064 8.21879 2.4822C8.02131 2.36732 7.78118 2.31298 7.56045 2.26911C7.49996 2.25597 7.4653 2.23944 7.42785 2.18745C7.41972 2.1347 7.41972 2.1347 7.42785 2.08194C7.48541 2.01979 7.54597 2.00462 7.62382 1.98585C7.64835 1.97952 7.67286 1.97314 7.69737 1.96671C7.71003 1.96342 7.72269 1.96012 7.73574 1.95673C7.80032 1.93939 7.86425 1.91995 7.92817 1.90012C7.93978 1.89661 7.95139 1.89309 7.96336 1.88947C8.09329 1.84895 8.20541 1.79712 8.30927 1.70512C8.31896 1.6968 8.32864 1.68848 8.33862 1.67992C8.50026 1.52817 8.55518 1.3002 8.60504 1.08748C8.60884 1.07133 8.61264 1.05518 8.61655 1.03854C8.62411 1.0061 8.63154 0.973622 8.63882 0.94111C8.64403 0.918489 8.64403 0.918489 8.64935 0.895412C8.65238 0.881899 8.65542 0.868385 8.65855 0.854462C8.67186 0.811441 8.68935 0.77766 8.71386 0.740443C8.76096 0.715878 8.79401 0.726983 8.84391 0.740443Z\" fill=\"#414146\"/><path d=\"M2.19446 8.32962C2.21166 8.32975 2.21166 8.32975 2.22919 8.32988C2.35253 8.3338 2.43597 8.37503 2.5268 8.46151C2.6325 8.58061 2.6813 8.71497 2.67852 8.87549C2.66666 9.00565 2.59307 9.11929 2.50282 9.20727C2.39658 9.29672 2.28941 9.32628 2.15366 9.32215C2.03919 9.30825 1.93151 9.25153 1.85038 9.16618C1.7495 9.02258 1.72 8.89087 1.73479 8.71398C1.76533 8.57472 1.85337 8.46167 1.96598 8.38238C2.04421 8.34101 2.10713 8.32886 2.19446 8.32962Z\" fill=\"#4C4C51\"/></svg>\n Analyze\n </button> -->\n </div>\n </div>\n\n <!-- Right Panel: Logs -->\n <div class=\"cqa-col-span-3 cqa-border cqa-border-solid cqa-border-[##E5E5E5] cqa-rounded-[10px] cqa-py-2 cqa-px-3 cqa-h-full cqa-max-h-[200px] cqa-overflow-auto\"\n style=\"scrollbar-width: thin;\">\n <div class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-medium cqa-text-[#0A0A0A] cqa-flex cqa-items-center cqa-gap-2 cqa-mb-2\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.6666 12L14.6666 8L10.6666 4\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M5.33337 4L1.33337 8L5.33337 12\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n Logs\n </div>\n \n <div class=\"cqa-flex cqa-flex-col cqa-gap-2 cqa-flex-1 cqa-min-h-0 cqa-h-[calc(100%-24px)]\">\n <div class=\"cqa-text-[11px] cqa-leading-[100%] cqa-text-[#737373] cqa-shrink-0\">Console</div>\n \n <div *ngIf=\"!logs || logs.length === 0\" class=\"cqa-px-2 cqa-py-[2px] cqa-rounded cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF] cqa-bg-[#f8f8f8] cqa-text-center\">\n No logs available\n </div>\n \n <cdk-virtual-scroll-viewport\n *ngIf=\"logs?.length\"\n itemSize=\"28\"\n minBufferPx=\"200\"\n maxBufferPx=\"300\"\n class=\"cqa-h-full cqa-w-full cqa-overflow-x-hidden\" style=\"scrollbar-width: thin;\">\n <div *cdkVirtualFor=\"let log of logs; trackBy: trackByLogIndex\" \n class=\"cqa-px-2 cqa-py-[2px] cqa-rounded cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-break-words cqa-overflow-hidden\" \n [ngClass]=\"getLogClass(log.level)\">\n {{ log.message }}\n </div>\n </cdk-virtual-scroll-viewport>\n </div>\n\n <!-- <a \n *ngIf=\"showFullLogsLink && logs?.length\"\n (click)=\"onViewFullLogs()\"\n class=\"cqa-text-[10px] cqa-leading-[15px] cqa-text-[#3F43EE] cqa-font-medium cqa-flex cqa-items-center cqa-justify-end cqa-gap-[2px] cqa-cursor-pointer hover:cqa-underline cqa-mt-4\">\n View full logs Iterations\n <div><svg width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M2.03833 6.74335L2.62833 7.33335L5.96166 4.00002L2.62833 0.666687L2.03833 1.25669L4.78166 4.00002L2.03833 6.74335Z\" fill=\"#3F43EE\"/></svg></div>\n </a> -->\n </div>\n</div>\n\n<style>\n @keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n</style>", styles: ["\n @keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n"], components: [{ type: i2$3.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2$3.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { type: i2$3.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
|
|
8584
8624
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: VisualComparisonComponent, decorators: [{
|
|
8585
8625
|
type: Component,
|
|
8586
|
-
args: [{ selector: 'cqa-visual-comparison', host: { class: 'cqa-ui-root' }, template: "<div class=\"cqa-grid cqa-grid-cols-12 cqa-gap-x-4 cqa-w-full cqa-max-h-[200px] cqa-h-full cqa-overflow-hidden\">\n <!-- Left Panel: Screenshots & Visual Comparison -->\n <div class=\"cqa-col-span-9 cqa-border cqa-border-solid cqa-border-[##E5E5E5] cqa-rounded-[10px] cqa-pt-2 cqa-px-3 cqa-pb-1 cqa-h-full cqa-max-h-[200px] cqa-overflow-auto cqa-font-inter\"\n style=\"scrollbar-width: thin;\">\n <div class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-medium cqa-text-[#0A0A0A] cqa-flex cqa-items-center cqa-gap-2 cqa-mb-2\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M12.6667 2H3.33333C2.59695 2 2 2.59695 2 3.33333V12.6667C2 13.403 2.59695 14 3.33333 14H12.6667C13.403 14 14 13.403 14 12.6667V3.33333C14 2.59695 13.403 2 12.6667 2Z\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6.00033 7.33268C6.73671 7.33268 7.33366 6.73573 7.33366 5.99935C7.33366 5.26297 6.73671 4.66602 6.00033 4.66602C5.26395 4.66602 4.66699 5.26297 4.66699 5.99935C4.66699 6.73573 5.26395 7.33268 6.00033 7.33268Z\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M14 10.0004L11.9427 7.94312C11.6926 7.69315 11.3536 7.55273 11 7.55273C10.6464 7.55273 10.3074 7.69315 10.0573 7.94312L4 14.0004\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n Screenshots & Visual Comparison\n </div>\n \n <!-- Screenshot Comparison Grid -->\n <div class=\"cqa-grid cqa-grid-cols-3 cqa-gap-3 cqa-mb-2\">\n <!-- Baseline -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <div class=\"cqa-text-[11px] cqa-leading-[100%] cqa-text-[#737373]\">Baseline</div>\n <div class=\"cqa-bg-[#F5F5F5] cqa-rounded-[10px] cqa-border cqa-border-solid cqa-border-[#E5E5E5] cqa-flex cqa-items-center cqa-justify-center cqa-h-[112px] cqa-cursor-pointer\" (click)=\"onImageClick('baseline')\">\n <div *ngIf=\"!screenshots?.baseline\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M25.3333 4H6.66667C5.19391 4 4 5.19391 4 6.66667V25.3333C4 26.8061 5.19391 28 6.66667 28H25.3333C26.8061 28 28 26.8061 28 25.3333V6.66667C28 5.19391 26.8061 4 25.3333 4Z\" stroke=\"#737373\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M11.9997 14.6673C13.4724 14.6673 14.6663 13.4734 14.6663 12.0007C14.6663 10.5279 13.4724 9.33398 11.9997 9.33398C10.5269 9.33398 9.33301 10.5279 9.33301 12.0007C9.33301 13.4734 10.5269 14.6673 11.9997 14.6673Z\" stroke=\"#737373\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M28 20.0009L23.8853 15.8862C23.3853 15.3863 22.7071 15.1055 22 15.1055C21.2929 15.1055 20.6147 15.3863 20.1147 15.8862L8 28.0009\" stroke=\"#737373\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <img #baselineImage *ngIf=\"baselineImageUrl\" [src]=\"baselineImageUrl\" alt=\"Baseline\" class=\"cqa-w-full cqa-h-full cqa-object-cover cqa-rounded-lg\" />\n </div>\n </div>\n\n <!-- Current -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <div class=\"cqa-text-[11px] cqa-leading-[100%] cqa-text-[#737373]\">Current</div>\n <div class=\"cqa-bg-[#FEF2F3] cqa-rounded-[10px] cqa-border cqa-border-solid cqa-border-[#F9C2C5] cqa-flex cqa-items-center cqa-justify-center cqa-h-[112px] cqa-cursor-pointer\" (click)=\"onImageClick('current')\">\n <div *ngIf=\"!screenshots?.current\" class=\"cqa-flex cqa-flex-col cqa-items-center cqa-gap-2 cqa-text-[#EF4444]\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M25.3333 4H6.66667C5.19391 4 4 5.19391 4 6.66667V25.3333C4 26.8061 5.19391 28 6.66667 28H25.3333C26.8061 28 28 26.8061 28 25.3333V6.66667C28 5.19391 26.8061 4 25.3333 4Z\" stroke=\"#E7000B\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M11.9997 14.6673C13.4724 14.6673 14.6663 13.4734 14.6663 12.0007C14.6663 10.5279 13.4724 9.33398 11.9997 9.33398C10.5269 9.33398 9.33301 10.5279 9.33301 12.0007C9.33301 13.4734 10.5269 14.6673 11.9997 14.6673Z\" stroke=\"#E7000B\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M28 20.0009L23.8853 15.8862C23.3853 15.3863 22.7071 15.1055 22 15.1055C21.2929 15.1055 20.6147 15.3863 20.1147 15.8862L8 28.0009\" stroke=\"#E7000B\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <img *ngIf=\"screenshots?.current\" [src]=\"screenshots.current\" alt=\"Current\" class=\"cqa-w-full cqa-h-full cqa-object-cover cqa-rounded-lg\" />\n </div>\n </div>\n\n <!-- Difference -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <div class=\"cqa-text-[11px] cqa-leading-[100%] cqa-text-[#737373]\">Difference</div>\n <div class=\"cqa-bg-[#FEF2F3] cqa-rounded-[10px] cqa-border cqa-border-solid cqa-border-[#F9C2C5] cqa-flex cqa-items-center cqa-justify-center cqa-h-[112px] cqa-cursor-pointer\" (click)=\"onImageClick('difference')\">\n <div *ngIf=\"!screenshots?.difference\" class=\"cqa-flex cqa-flex-col cqa-items-center cqa-gap-2 cqa-text-[#EF4444]\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M25.3333 4H6.66667C5.19391 4 4 5.19391 4 6.66667V25.3333C4 26.8061 5.19391 28 6.66667 28H25.3333C26.8061 28 28 26.8061 28 25.3333V6.66667C28 5.19391 26.8061 4 25.3333 4Z\" stroke=\"#E7000B\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M11.9997 14.6673C13.4724 14.6673 14.6663 13.4734 14.6663 12.0007C14.6663 10.5279 13.4724 9.33398 11.9997 9.33398C10.5269 9.33398 9.33301 10.5279 9.33301 12.0007C9.33301 13.4734 10.5269 14.6673 11.9997 14.6673Z\" stroke=\"#E7000B\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M28 20.0009L23.8853 15.8862C23.3853 15.3863 22.7071 15.1055 22 15.1055C21.2929 15.1055 20.6147 15.3863 20.1147 15.8862L8 28.0009\" stroke=\"#E7000B\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <img *ngIf=\"screenshots?.difference\" [src]=\"screenshots.difference\" alt=\"Difference\" class=\"cqa-w-full cqa-h-full cqa-object-cover cqa-rounded-lg\" />\n </div>\n </div>\n </div>\n\n <!-- Action Buttons -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-end cqa-gap-2 cqa-flex-wrap\">\n <button \n (click)=\"onMakeCurrentBaseline()\"\n [disabled]=\"!isCurrentImageAvailable || isMakingCurrentBaseline?.[testStepResultId] === true\"\n [class.cqa-opacity-50]=\"!isCurrentImageAvailable || isMakingCurrentBaseline?.[testStepResultId] === true\"\n [class.cqa-cursor-not-allowed]=\"!isCurrentImageAvailable || isMakingCurrentBaseline?.[testStepResultId] === true\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-pl-2 cqa-pr-4 cqa-py-[2px] cqa-rounded-lg cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-transparent cqa-text-[#212122] cqa-border cqa-border-solid cqa-border-[#212122] disabled:cqa-cursor-not-allowed\">\n <svg *ngIf=\"!isMakingCurrentBaseline?.[testStepResultId]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4.39754 7.93752L2.31254 5.85252L1.60254 6.55752L4.39754 9.35252L10.3975 3.35252L9.69254 2.64752L4.39754 7.93752Z\" fill=\"black\"/></svg>\n <svg *ngIf=\"isMakingCurrentBaseline?.[testStepResultId] === true\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" opacity=\"0.3\"/>\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" stroke-dashoffset=\"2\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" values=\"0 6 6;360 6 6\" dur=\"1s\" repeatCount=\"indefinite\"/>\n </circle>\n </svg>\n <span>{{ isMakingCurrentBaseline?.[testStepResultId] === true ? 'Loading...' : 'Make current baseline' }}</span>\n </button>\n <button \n (click)=\"onUploadBaseline()\"\n [disabled]=\"isUploadingBaseline?.[testStepResultId] === true\"\n [class.cqa-opacity-50]=\"isUploadingBaseline?.[testStepResultId] === true\"\n [class.cqa-cursor-not-allowed]=\"isUploadingBaseline?.[testStepResultId] === true\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-pl-2 cqa-pr-4 cqa-py-[2px] cqa-rounded-lg cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-transparent cqa-text-[#212122] cqa-border cqa-border-solid cqa-border-[#212122] disabled:cqa-cursor-not-allowed\">\n <svg *ngIf=\"!isUploadingBaseline?.[testStepResultId]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M9 7.5V9H3V7.5H2V9C2 9.55 2.45 10 3 10H9C9.55 10 10 9.55 10 9V7.5H9ZM3.5 4.5L4.205 5.205L5.5 3.915V8H6.5V3.915L7.795 5.205L8.5 4.5L6 2L3.5 4.5Z\" fill=\"black\"/></svg>\n <svg *ngIf=\"isUploadingBaseline?.[testStepResultId] === true\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" style=\"animation: spin 1s linear infinite;\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" opacity=\"0.3\"/>\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" stroke-dashoffset=\"2\"/>\n </svg>\n <span>{{ isUploadingBaseline?.[testStepResultId] === true ? 'Uploading...' : 'Upload baseline' }}</span>\n </button>\n <!-- Hidden file input -->\n <input \n #fileInput\n type=\"file\" \n accept=\"image/png,image/jpeg,image/jpg,image/webp\"\n (change)=\"onFileSelected($event)\"\n style=\"display: none;\" \n />\n <!-- <button \n (click)=\"onAnalyze()\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-pl-2 cqa-pr-4 cqa-py-[2px] cqa-rounded-lg cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-transparent cqa-text-[#212122] cqa-border cqa-border-solid cqa-border-[#212122]\">\n <svg width=\"11\" height=\"12\" viewBox=\"0 0 11 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M5.5115 0C5.57931 0.0303178 5.60828 0.104354 5.63604 0.173128C5.64996 0.2132 5.66273 0.253489 5.67513 0.2941C5.67998 0.309662 5.68484 0.325224 5.68984 0.341258C5.7543 0.550673 5.81172 0.762331 5.86946 0.97384C5.88251 1.02159 5.89563 1.06932 5.90874 1.11704C5.97551 1.36005 6.04177 1.6032 6.10767 1.84646C6.11693 1.88062 6.12619 1.91479 6.13545 1.94895C6.16156 2.04527 6.18764 2.14159 6.21357 2.23796C6.26837 2.44159 6.32467 2.64463 6.38463 2.84668C6.38986 2.86435 6.3951 2.88203 6.4005 2.90024C6.55624 3.42 6.77701 3.88583 7.13888 4.28262C7.14784 4.29294 7.1568 4.30325 7.16603 4.31388C7.3205 4.48583 7.51873 4.62361 7.71687 4.73481C7.72696 4.74057 7.73705 4.74632 7.74745 4.75225C8.33051 5.079 9.03162 5.22272 9.66313 5.414C9.93984 5.49787 10.2157 5.58438 10.4905 5.6747C10.5099 5.68105 10.5292 5.68738 10.5485 5.6937C10.6062 5.7126 10.6639 5.73182 10.7215 5.7513C10.7349 5.75572 10.7483 5.76015 10.7621 5.76471C10.8415 5.79208 10.9174 5.82439 10.9825 5.88036C11.0023 5.92558 11.0023 5.92558 10.9969 5.9708C10.9336 6.03648 10.8707 6.06728 10.7871 6.09733C10.7751 6.10176 10.7632 6.1062 10.7508 6.11077C10.6096 6.16244 10.4665 6.20766 10.3232 6.25247C10.2938 6.26174 10.2644 6.27101 10.235 6.28028C10.0537 6.33735 9.87199 6.3932 9.69014 6.44842C9.45061 6.52117 9.21143 6.59512 8.97249 6.66991C8.93334 6.68216 8.89418 6.69437 8.85501 6.70654C8.64931 6.77048 8.44462 6.83671 8.24162 6.90944C8.22478 6.91545 8.20794 6.92147 8.19059 6.92766C7.51069 7.17443 6.99245 7.63478 6.66809 8.30799C6.49321 8.68634 6.39006 9.09548 6.28483 9.49929C6.25637 9.60825 6.22611 9.7166 6.1955 9.82492C6.17149 9.91015 6.14803 9.99551 6.12515 10.0811C6.12243 10.0913 6.1197 10.1014 6.1169 10.1119C6.1037 10.1612 6.09056 10.2106 6.07752 10.2599C6.04413 10.3851 6.00817 10.5092 5.97123 10.6332C5.90567 10.8536 5.84601 11.0757 5.78672 11.298C5.69732 11.6328 5.69732 11.6328 5.64662 11.7937C5.64326 11.8045 5.6399 11.8153 5.63644 11.8264C5.61793 11.8837 5.5989 11.9364 5.56388 11.9849C5.5106 11.9972 5.5106 11.9972 5.46273 12C5.40801 11.9168 5.37177 11.8361 5.34273 11.7401C5.33851 11.7265 5.33428 11.7129 5.32993 11.6989C5.27614 11.5233 5.22807 11.3459 5.17999 11.1686C5.16898 11.1281 5.15791 11.0875 5.14685 11.047C5.0644 10.7448 4.98331 10.4423 4.90234 10.1397C4.56509 8.64299 4.56509 8.64299 3.71433 7.43288C3.7007 7.42128 3.68706 7.40968 3.67302 7.39773C3.1156 6.93203 2.3813 6.75959 1.70885 6.55751C1.54254 6.50749 1.37628 6.45724 1.21004 6.40697C1.1955 6.40258 1.1955 6.40258 1.18067 6.39809C0.940881 6.32556 0.701157 6.25283 0.462274 6.17711C0.452168 6.17393 0.442063 6.17075 0.431651 6.16747C0.0646543 6.05178 0.0646543 6.05178 0.000790211 5.9708C-0.00101599 5.93406 -0.00101599 5.93406 0.0152398 5.89543C0.0819909 5.8272 0.14676 5.79797 0.234862 5.76825C0.247618 5.76378 0.260375 5.75931 0.273518 5.75471C0.312587 5.7411 0.351741 5.72779 0.390929 5.71455C0.402112 5.71073 0.413295 5.7069 0.424817 5.70296C0.503904 5.6759 0.583275 5.64986 0.662762 5.62412C0.682294 5.61777 0.682294 5.61777 0.70222 5.61129C1.04166 5.50116 1.38332 5.39867 1.72487 5.29595C1.97939 5.21939 2.23347 5.14157 2.48674 5.06065C2.49838 5.05694 2.51001 5.05324 2.52201 5.04943C3.10872 4.86262 3.68229 4.59755 4.06112 4.0716C4.06679 4.0638 4.07247 4.05599 4.07831 4.04796C4.50019 3.4642 4.6647 2.7543 4.8485 2.06161C4.90896 1.83379 4.97015 1.60619 5.03155 1.37865C5.04856 1.31564 5.06553 1.25263 5.08244 1.18959C5.15037 0.936385 5.21932 0.683523 5.29222 0.431818C5.29904 0.408248 5.30583 0.384667 5.31259 0.361076C5.41466 0.00531681 5.41466 0.00531681 5.5115 0Z\" fill=\"#161617\"/><path d=\"M8.84391 0.740443C8.91024 0.818762 8.92349 0.910806 8.94415 1.01081C9.01305 1.32499 9.09241 1.61388 9.36787 1.79638C9.53782 1.89443 9.74037 1.93904 9.92867 1.98118C10.0082 1.99933 10.0753 2.02341 10.1435 2.07158C10.1588 2.09701 10.1588 2.09701 10.1579 2.14129C10.1421 2.19513 10.1282 2.2125 10.0866 2.24774C10.041 2.26364 10.041 2.26364 9.98633 2.27601C9.96564 2.28096 9.94496 2.28597 9.9243 2.29102C9.91322 2.2937 9.90215 2.29638 9.89075 2.29914C9.55401 2.38039 9.55401 2.38039 9.26295 2.56428C9.25348 2.57222 9.24402 2.58017 9.23427 2.58836C9.02625 2.7797 8.98226 3.098 8.91963 3.36464C8.91605 3.37928 8.91246 3.39393 8.90876 3.40901C8.90566 3.42198 8.90255 3.43494 8.89935 3.4483C8.88584 3.48788 8.87183 3.51369 8.84391 3.54402C8.76614 3.55432 8.76614 3.55432 8.72831 3.54402C8.66814 3.49537 8.65468 3.43996 8.63896 3.3655C8.63633 3.35397 8.63369 3.34244 8.63098 3.33056C8.62259 3.29374 8.61447 3.25686 8.60639 3.21995C8.54302 2.93259 8.47148 2.65064 8.21879 2.4822C8.02131 2.36732 7.78118 2.31298 7.56045 2.26911C7.49996 2.25597 7.4653 2.23944 7.42785 2.18745C7.41972 2.1347 7.41972 2.1347 7.42785 2.08194C7.48541 2.01979 7.54597 2.00462 7.62382 1.98585C7.64835 1.97952 7.67286 1.97314 7.69737 1.96671C7.71003 1.96342 7.72269 1.96012 7.73574 1.95673C7.80032 1.93939 7.86425 1.91995 7.92817 1.90012C7.93978 1.89661 7.95139 1.89309 7.96336 1.88947C8.09329 1.84895 8.20541 1.79712 8.30927 1.70512C8.31896 1.6968 8.32864 1.68848 8.33862 1.67992C8.50026 1.52817 8.55518 1.3002 8.60504 1.08748C8.60884 1.07133 8.61264 1.05518 8.61655 1.03854C8.62411 1.0061 8.63154 0.973622 8.63882 0.94111C8.64403 0.918489 8.64403 0.918489 8.64935 0.895412C8.65238 0.881899 8.65542 0.868385 8.65855 0.854462C8.67186 0.811441 8.68935 0.77766 8.71386 0.740443C8.76096 0.715878 8.79401 0.726983 8.84391 0.740443Z\" fill=\"#414146\"/><path d=\"M2.19446 8.32962C2.21166 8.32975 2.21166 8.32975 2.22919 8.32988C2.35253 8.3338 2.43597 8.37503 2.5268 8.46151C2.6325 8.58061 2.6813 8.71497 2.67852 8.87549C2.66666 9.00565 2.59307 9.11929 2.50282 9.20727C2.39658 9.29672 2.28941 9.32628 2.15366 9.32215C2.03919 9.30825 1.93151 9.25153 1.85038 9.16618C1.7495 9.02258 1.72 8.89087 1.73479 8.71398C1.76533 8.57472 1.85337 8.46167 1.96598 8.38238C2.04421 8.34101 2.10713 8.32886 2.19446 8.32962Z\" fill=\"#4C4C51\"/></svg>\n Analyze\n </button> -->\n </div>\n </div>\n\n <!-- Right Panel: Logs -->\n <div class=\"cqa-col-span-3 cqa-border cqa-border-solid cqa-border-[##E5E5E5] cqa-rounded-[10px] cqa-py-2 cqa-px-3 cqa-h-full cqa-max-h-[200px] cqa-overflow-auto\"\n style=\"scrollbar-width: thin;\">\n <div class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-medium cqa-text-[#0A0A0A] cqa-flex cqa-items-center cqa-gap-2 cqa-mb-2\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.6666 12L14.6666 8L10.6666 4\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M5.33337 4L1.33337 8L5.33337 12\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n Logs\n </div>\n \n <div class=\"cqa-flex cqa-flex-col cqa-gap-2 \">\n <div class=\"cqa-text-[11px] cqa-leading-[100%] cqa-text-[#737373]\">Console</div>\n \n <div *ngFor=\"let log of logs\" class=\"cqa-px-2 cqa-py-[2px] cqa-rounded cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-break-words\" [ngClass]=\"getLogClass(log.level)\">\n {{ log.message }}\n </div>\n \n <div *ngIf=\"!logs || logs.length === 0\" class=\"cqa-px-2 cqa-py-[2px] cqa-rounded cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF] cqa-bg-[#f8f8f8] cqa-text-center\">\n No logs available\n </div>\n </div>\n\n <!-- <a \n *ngIf=\"showFullLogsLink && logs?.length\"\n (click)=\"onViewFullLogs()\"\n class=\"cqa-text-[10px] cqa-leading-[15px] cqa-text-[#3F43EE] cqa-font-medium cqa-flex cqa-items-center cqa-justify-end cqa-gap-[2px] cqa-cursor-pointer hover:cqa-underline cqa-mt-4\">\n View full logs Iterations\n <div><svg width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M2.03833 6.74335L2.62833 7.33335L5.96166 4.00002L2.62833 0.666687L2.03833 1.25669L4.78166 4.00002L2.03833 6.74335Z\" fill=\"#3F43EE\"/></svg></div>\n </a> -->\n </div>\n</div>\n\n<style>\n @keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n</style>", styles: ["\n @keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n"] }]
|
|
8626
|
+
args: [{ selector: 'cqa-visual-comparison', host: { class: 'cqa-ui-root' }, template: "<div class=\"cqa-grid cqa-grid-cols-12 cqa-gap-x-4 cqa-w-full cqa-max-h-[200px] cqa-h-full cqa-overflow-hidden\">\n <!-- Left Panel: Screenshots & Visual Comparison -->\n <div class=\"cqa-col-span-9 cqa-border cqa-border-solid cqa-border-[##E5E5E5] cqa-rounded-[10px] cqa-pt-2 cqa-px-3 cqa-pb-1 cqa-h-full cqa-max-h-[200px] cqa-overflow-auto cqa-font-inter\"\n style=\"scrollbar-width: thin;\">\n <div class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-medium cqa-text-[#0A0A0A] cqa-flex cqa-items-center cqa-gap-2 cqa-mb-2\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M12.6667 2H3.33333C2.59695 2 2 2.59695 2 3.33333V12.6667C2 13.403 2.59695 14 3.33333 14H12.6667C13.403 14 14 13.403 14 12.6667V3.33333C14 2.59695 13.403 2 12.6667 2Z\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6.00033 7.33268C6.73671 7.33268 7.33366 6.73573 7.33366 5.99935C7.33366 5.26297 6.73671 4.66602 6.00033 4.66602C5.26395 4.66602 4.66699 5.26297 4.66699 5.99935C4.66699 6.73573 5.26395 7.33268 6.00033 7.33268Z\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M14 10.0004L11.9427 7.94312C11.6926 7.69315 11.3536 7.55273 11 7.55273C10.6464 7.55273 10.3074 7.69315 10.0573 7.94312L4 14.0004\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n Screenshots & Visual Comparison\n </div>\n \n <!-- Screenshot Comparison Grid -->\n <div class=\"cqa-grid cqa-grid-cols-3 cqa-gap-3 cqa-mb-2\">\n <!-- Baseline -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <div class=\"cqa-text-[11px] cqa-leading-[100%] cqa-text-[#737373]\">Baseline</div>\n <div class=\"cqa-bg-[#F5F5F5] cqa-rounded-[10px] cqa-border cqa-border-solid cqa-border-[#E5E5E5] cqa-flex cqa-items-center cqa-justify-center cqa-h-[112px] cqa-cursor-pointer\" (click)=\"onImageClick('baseline')\">\n <div *ngIf=\"!screenshots?.baseline\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M25.3333 4H6.66667C5.19391 4 4 5.19391 4 6.66667V25.3333C4 26.8061 5.19391 28 6.66667 28H25.3333C26.8061 28 28 26.8061 28 25.3333V6.66667C28 5.19391 26.8061 4 25.3333 4Z\" stroke=\"#737373\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M11.9997 14.6673C13.4724 14.6673 14.6663 13.4734 14.6663 12.0007C14.6663 10.5279 13.4724 9.33398 11.9997 9.33398C10.5269 9.33398 9.33301 10.5279 9.33301 12.0007C9.33301 13.4734 10.5269 14.6673 11.9997 14.6673Z\" stroke=\"#737373\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M28 20.0009L23.8853 15.8862C23.3853 15.3863 22.7071 15.1055 22 15.1055C21.2929 15.1055 20.6147 15.3863 20.1147 15.8862L8 28.0009\" stroke=\"#737373\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <img #baselineImage *ngIf=\"baselineImageUrl\" [src]=\"baselineImageUrl\" alt=\"Baseline\" class=\"cqa-w-full cqa-h-full cqa-object-cover cqa-rounded-lg\" />\n </div>\n </div>\n\n <!-- Current -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <div class=\"cqa-text-[11px] cqa-leading-[100%] cqa-text-[#737373]\">Current</div>\n <div class=\"cqa-bg-[#FEF2F3] cqa-rounded-[10px] cqa-border cqa-border-solid cqa-border-[#F9C2C5] cqa-flex cqa-items-center cqa-justify-center cqa-h-[112px] cqa-cursor-pointer\" (click)=\"onImageClick('current')\">\n <div *ngIf=\"!screenshots?.current\" class=\"cqa-flex cqa-flex-col cqa-items-center cqa-gap-2 cqa-text-[#EF4444]\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M25.3333 4H6.66667C5.19391 4 4 5.19391 4 6.66667V25.3333C4 26.8061 5.19391 28 6.66667 28H25.3333C26.8061 28 28 26.8061 28 25.3333V6.66667C28 5.19391 26.8061 4 25.3333 4Z\" stroke=\"#E7000B\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M11.9997 14.6673C13.4724 14.6673 14.6663 13.4734 14.6663 12.0007C14.6663 10.5279 13.4724 9.33398 11.9997 9.33398C10.5269 9.33398 9.33301 10.5279 9.33301 12.0007C9.33301 13.4734 10.5269 14.6673 11.9997 14.6673Z\" stroke=\"#E7000B\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M28 20.0009L23.8853 15.8862C23.3853 15.3863 22.7071 15.1055 22 15.1055C21.2929 15.1055 20.6147 15.3863 20.1147 15.8862L8 28.0009\" stroke=\"#E7000B\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <img *ngIf=\"screenshots?.current\" [src]=\"screenshots.current\" alt=\"Current\" class=\"cqa-w-full cqa-h-full cqa-object-cover cqa-rounded-lg\" />\n </div>\n </div>\n\n <!-- Difference -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <div class=\"cqa-text-[11px] cqa-leading-[100%] cqa-text-[#737373]\">Difference</div>\n <div class=\"cqa-bg-[#FEF2F3] cqa-rounded-[10px] cqa-border cqa-border-solid cqa-border-[#F9C2C5] cqa-flex cqa-items-center cqa-justify-center cqa-h-[112px] cqa-cursor-pointer\" (click)=\"onImageClick('difference')\">\n <div *ngIf=\"!screenshots?.difference\" class=\"cqa-flex cqa-flex-col cqa-items-center cqa-gap-2 cqa-text-[#EF4444]\">\n <svg width=\"32\" height=\"32\" viewBox=\"0 0 32 32\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M25.3333 4H6.66667C5.19391 4 4 5.19391 4 6.66667V25.3333C4 26.8061 5.19391 28 6.66667 28H25.3333C26.8061 28 28 26.8061 28 25.3333V6.66667C28 5.19391 26.8061 4 25.3333 4Z\" stroke=\"#E7000B\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M11.9997 14.6673C13.4724 14.6673 14.6663 13.4734 14.6663 12.0007C14.6663 10.5279 13.4724 9.33398 11.9997 9.33398C10.5269 9.33398 9.33301 10.5279 9.33301 12.0007C9.33301 13.4734 10.5269 14.6673 11.9997 14.6673Z\" stroke=\"#E7000B\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M28 20.0009L23.8853 15.8862C23.3853 15.3863 22.7071 15.1055 22 15.1055C21.2929 15.1055 20.6147 15.3863 20.1147 15.8862L8 28.0009\" stroke=\"#E7000B\" stroke-opacity=\"0.5\" stroke-width=\"2.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <img *ngIf=\"screenshots?.difference\" [src]=\"screenshots.difference\" alt=\"Difference\" class=\"cqa-w-full cqa-h-full cqa-object-cover cqa-rounded-lg\" />\n </div>\n </div>\n </div>\n\n <!-- Action Buttons -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-end cqa-gap-2 cqa-flex-wrap\">\n <button \n (click)=\"onMakeCurrentBaseline()\"\n [disabled]=\"!isCurrentImageAvailable || isMakingCurrentBaseline?.[testStepResultId] === true\"\n [class.cqa-opacity-50]=\"!isCurrentImageAvailable || isMakingCurrentBaseline?.[testStepResultId] === true\"\n [class.cqa-cursor-not-allowed]=\"!isCurrentImageAvailable || isMakingCurrentBaseline?.[testStepResultId] === true\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-pl-2 cqa-pr-4 cqa-py-[2px] cqa-rounded-lg cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-transparent cqa-text-[#212122] cqa-border cqa-border-solid cqa-border-[#212122] disabled:cqa-cursor-not-allowed\">\n <svg *ngIf=\"!isMakingCurrentBaseline?.[testStepResultId]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M4.39754 7.93752L2.31254 5.85252L1.60254 6.55752L4.39754 9.35252L10.3975 3.35252L9.69254 2.64752L4.39754 7.93752Z\" fill=\"black\"/></svg>\n <svg *ngIf=\"isMakingCurrentBaseline?.[testStepResultId] === true\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" opacity=\"0.3\"/>\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" stroke-dashoffset=\"2\">\n <animateTransform attributeName=\"transform\" type=\"rotate\" values=\"0 6 6;360 6 6\" dur=\"1s\" repeatCount=\"indefinite\"/>\n </circle>\n </svg>\n <span>{{ isMakingCurrentBaseline?.[testStepResultId] === true ? 'Loading...' : 'Make current baseline' }}</span>\n </button>\n <button \n (click)=\"onUploadBaseline()\"\n [disabled]=\"isUploadingBaseline?.[testStepResultId] === true\"\n [class.cqa-opacity-50]=\"isUploadingBaseline?.[testStepResultId] === true\"\n [class.cqa-cursor-not-allowed]=\"isUploadingBaseline?.[testStepResultId] === true\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-pl-2 cqa-pr-4 cqa-py-[2px] cqa-rounded-lg cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-transparent cqa-text-[#212122] cqa-border cqa-border-solid cqa-border-[#212122] disabled:cqa-cursor-not-allowed\">\n <svg *ngIf=\"!isUploadingBaseline?.[testStepResultId]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M9 7.5V9H3V7.5H2V9C2 9.55 2.45 10 3 10H9C9.55 10 10 9.55 10 9V7.5H9ZM3.5 4.5L4.205 5.205L5.5 3.915V8H6.5V3.915L7.795 5.205L8.5 4.5L6 2L3.5 4.5Z\" fill=\"black\"/></svg>\n <svg *ngIf=\"isUploadingBaseline?.[testStepResultId] === true\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" style=\"animation: spin 1s linear infinite;\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" opacity=\"0.3\"/>\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-dasharray=\"8 4\" stroke-dashoffset=\"2\"/>\n </svg>\n <span>{{ isUploadingBaseline?.[testStepResultId] === true ? 'Uploading...' : 'Upload baseline' }}</span>\n </button>\n <!-- Hidden file input -->\n <input \n #fileInput\n type=\"file\" \n accept=\"image/png,image/jpeg,image/jpg,image/webp\"\n (change)=\"onFileSelected($event)\"\n style=\"display: none;\" \n />\n <!-- <button \n (click)=\"onAnalyze()\"\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-pl-2 cqa-pr-4 cqa-py-[2px] cqa-rounded-lg cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-transparent cqa-text-[#212122] cqa-border cqa-border-solid cqa-border-[#212122]\">\n <svg width=\"11\" height=\"12\" viewBox=\"0 0 11 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M5.5115 0C5.57931 0.0303178 5.60828 0.104354 5.63604 0.173128C5.64996 0.2132 5.66273 0.253489 5.67513 0.2941C5.67998 0.309662 5.68484 0.325224 5.68984 0.341258C5.7543 0.550673 5.81172 0.762331 5.86946 0.97384C5.88251 1.02159 5.89563 1.06932 5.90874 1.11704C5.97551 1.36005 6.04177 1.6032 6.10767 1.84646C6.11693 1.88062 6.12619 1.91479 6.13545 1.94895C6.16156 2.04527 6.18764 2.14159 6.21357 2.23796C6.26837 2.44159 6.32467 2.64463 6.38463 2.84668C6.38986 2.86435 6.3951 2.88203 6.4005 2.90024C6.55624 3.42 6.77701 3.88583 7.13888 4.28262C7.14784 4.29294 7.1568 4.30325 7.16603 4.31388C7.3205 4.48583 7.51873 4.62361 7.71687 4.73481C7.72696 4.74057 7.73705 4.74632 7.74745 4.75225C8.33051 5.079 9.03162 5.22272 9.66313 5.414C9.93984 5.49787 10.2157 5.58438 10.4905 5.6747C10.5099 5.68105 10.5292 5.68738 10.5485 5.6937C10.6062 5.7126 10.6639 5.73182 10.7215 5.7513C10.7349 5.75572 10.7483 5.76015 10.7621 5.76471C10.8415 5.79208 10.9174 5.82439 10.9825 5.88036C11.0023 5.92558 11.0023 5.92558 10.9969 5.9708C10.9336 6.03648 10.8707 6.06728 10.7871 6.09733C10.7751 6.10176 10.7632 6.1062 10.7508 6.11077C10.6096 6.16244 10.4665 6.20766 10.3232 6.25247C10.2938 6.26174 10.2644 6.27101 10.235 6.28028C10.0537 6.33735 9.87199 6.3932 9.69014 6.44842C9.45061 6.52117 9.21143 6.59512 8.97249 6.66991C8.93334 6.68216 8.89418 6.69437 8.85501 6.70654C8.64931 6.77048 8.44462 6.83671 8.24162 6.90944C8.22478 6.91545 8.20794 6.92147 8.19059 6.92766C7.51069 7.17443 6.99245 7.63478 6.66809 8.30799C6.49321 8.68634 6.39006 9.09548 6.28483 9.49929C6.25637 9.60825 6.22611 9.7166 6.1955 9.82492C6.17149 9.91015 6.14803 9.99551 6.12515 10.0811C6.12243 10.0913 6.1197 10.1014 6.1169 10.1119C6.1037 10.1612 6.09056 10.2106 6.07752 10.2599C6.04413 10.3851 6.00817 10.5092 5.97123 10.6332C5.90567 10.8536 5.84601 11.0757 5.78672 11.298C5.69732 11.6328 5.69732 11.6328 5.64662 11.7937C5.64326 11.8045 5.6399 11.8153 5.63644 11.8264C5.61793 11.8837 5.5989 11.9364 5.56388 11.9849C5.5106 11.9972 5.5106 11.9972 5.46273 12C5.40801 11.9168 5.37177 11.8361 5.34273 11.7401C5.33851 11.7265 5.33428 11.7129 5.32993 11.6989C5.27614 11.5233 5.22807 11.3459 5.17999 11.1686C5.16898 11.1281 5.15791 11.0875 5.14685 11.047C5.0644 10.7448 4.98331 10.4423 4.90234 10.1397C4.56509 8.64299 4.56509 8.64299 3.71433 7.43288C3.7007 7.42128 3.68706 7.40968 3.67302 7.39773C3.1156 6.93203 2.3813 6.75959 1.70885 6.55751C1.54254 6.50749 1.37628 6.45724 1.21004 6.40697C1.1955 6.40258 1.1955 6.40258 1.18067 6.39809C0.940881 6.32556 0.701157 6.25283 0.462274 6.17711C0.452168 6.17393 0.442063 6.17075 0.431651 6.16747C0.0646543 6.05178 0.0646543 6.05178 0.000790211 5.9708C-0.00101599 5.93406 -0.00101599 5.93406 0.0152398 5.89543C0.0819909 5.8272 0.14676 5.79797 0.234862 5.76825C0.247618 5.76378 0.260375 5.75931 0.273518 5.75471C0.312587 5.7411 0.351741 5.72779 0.390929 5.71455C0.402112 5.71073 0.413295 5.7069 0.424817 5.70296C0.503904 5.6759 0.583275 5.64986 0.662762 5.62412C0.682294 5.61777 0.682294 5.61777 0.70222 5.61129C1.04166 5.50116 1.38332 5.39867 1.72487 5.29595C1.97939 5.21939 2.23347 5.14157 2.48674 5.06065C2.49838 5.05694 2.51001 5.05324 2.52201 5.04943C3.10872 4.86262 3.68229 4.59755 4.06112 4.0716C4.06679 4.0638 4.07247 4.05599 4.07831 4.04796C4.50019 3.4642 4.6647 2.7543 4.8485 2.06161C4.90896 1.83379 4.97015 1.60619 5.03155 1.37865C5.04856 1.31564 5.06553 1.25263 5.08244 1.18959C5.15037 0.936385 5.21932 0.683523 5.29222 0.431818C5.29904 0.408248 5.30583 0.384667 5.31259 0.361076C5.41466 0.00531681 5.41466 0.00531681 5.5115 0Z\" fill=\"#161617\"/><path d=\"M8.84391 0.740443C8.91024 0.818762 8.92349 0.910806 8.94415 1.01081C9.01305 1.32499 9.09241 1.61388 9.36787 1.79638C9.53782 1.89443 9.74037 1.93904 9.92867 1.98118C10.0082 1.99933 10.0753 2.02341 10.1435 2.07158C10.1588 2.09701 10.1588 2.09701 10.1579 2.14129C10.1421 2.19513 10.1282 2.2125 10.0866 2.24774C10.041 2.26364 10.041 2.26364 9.98633 2.27601C9.96564 2.28096 9.94496 2.28597 9.9243 2.29102C9.91322 2.2937 9.90215 2.29638 9.89075 2.29914C9.55401 2.38039 9.55401 2.38039 9.26295 2.56428C9.25348 2.57222 9.24402 2.58017 9.23427 2.58836C9.02625 2.7797 8.98226 3.098 8.91963 3.36464C8.91605 3.37928 8.91246 3.39393 8.90876 3.40901C8.90566 3.42198 8.90255 3.43494 8.89935 3.4483C8.88584 3.48788 8.87183 3.51369 8.84391 3.54402C8.76614 3.55432 8.76614 3.55432 8.72831 3.54402C8.66814 3.49537 8.65468 3.43996 8.63896 3.3655C8.63633 3.35397 8.63369 3.34244 8.63098 3.33056C8.62259 3.29374 8.61447 3.25686 8.60639 3.21995C8.54302 2.93259 8.47148 2.65064 8.21879 2.4822C8.02131 2.36732 7.78118 2.31298 7.56045 2.26911C7.49996 2.25597 7.4653 2.23944 7.42785 2.18745C7.41972 2.1347 7.41972 2.1347 7.42785 2.08194C7.48541 2.01979 7.54597 2.00462 7.62382 1.98585C7.64835 1.97952 7.67286 1.97314 7.69737 1.96671C7.71003 1.96342 7.72269 1.96012 7.73574 1.95673C7.80032 1.93939 7.86425 1.91995 7.92817 1.90012C7.93978 1.89661 7.95139 1.89309 7.96336 1.88947C8.09329 1.84895 8.20541 1.79712 8.30927 1.70512C8.31896 1.6968 8.32864 1.68848 8.33862 1.67992C8.50026 1.52817 8.55518 1.3002 8.60504 1.08748C8.60884 1.07133 8.61264 1.05518 8.61655 1.03854C8.62411 1.0061 8.63154 0.973622 8.63882 0.94111C8.64403 0.918489 8.64403 0.918489 8.64935 0.895412C8.65238 0.881899 8.65542 0.868385 8.65855 0.854462C8.67186 0.811441 8.68935 0.77766 8.71386 0.740443C8.76096 0.715878 8.79401 0.726983 8.84391 0.740443Z\" fill=\"#414146\"/><path d=\"M2.19446 8.32962C2.21166 8.32975 2.21166 8.32975 2.22919 8.32988C2.35253 8.3338 2.43597 8.37503 2.5268 8.46151C2.6325 8.58061 2.6813 8.71497 2.67852 8.87549C2.66666 9.00565 2.59307 9.11929 2.50282 9.20727C2.39658 9.29672 2.28941 9.32628 2.15366 9.32215C2.03919 9.30825 1.93151 9.25153 1.85038 9.16618C1.7495 9.02258 1.72 8.89087 1.73479 8.71398C1.76533 8.57472 1.85337 8.46167 1.96598 8.38238C2.04421 8.34101 2.10713 8.32886 2.19446 8.32962Z\" fill=\"#4C4C51\"/></svg>\n Analyze\n </button> -->\n </div>\n </div>\n\n <!-- Right Panel: Logs -->\n <div class=\"cqa-col-span-3 cqa-border cqa-border-solid cqa-border-[##E5E5E5] cqa-rounded-[10px] cqa-py-2 cqa-px-3 cqa-h-full cqa-max-h-[200px] cqa-overflow-auto\"\n style=\"scrollbar-width: thin;\">\n <div class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-medium cqa-text-[#0A0A0A] cqa-flex cqa-items-center cqa-gap-2 cqa-mb-2\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.6666 12L14.6666 8L10.6666 4\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M5.33337 4L1.33337 8L5.33337 12\" stroke=\"#0A0A0A\" stroke-width=\"1.33333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n Logs\n </div>\n \n <div class=\"cqa-flex cqa-flex-col cqa-gap-2 cqa-flex-1 cqa-min-h-0 cqa-h-[calc(100%-24px)]\">\n <div class=\"cqa-text-[11px] cqa-leading-[100%] cqa-text-[#737373] cqa-shrink-0\">Console</div>\n \n <div *ngIf=\"!logs || logs.length === 0\" class=\"cqa-px-2 cqa-py-[2px] cqa-rounded cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF] cqa-bg-[#f8f8f8] cqa-text-center\">\n No logs available\n </div>\n \n <cdk-virtual-scroll-viewport\n *ngIf=\"logs?.length\"\n itemSize=\"28\"\n minBufferPx=\"200\"\n maxBufferPx=\"300\"\n class=\"cqa-h-full cqa-w-full cqa-overflow-x-hidden\" style=\"scrollbar-width: thin;\">\n <div *cdkVirtualFor=\"let log of logs; trackBy: trackByLogIndex\" \n class=\"cqa-px-2 cqa-py-[2px] cqa-rounded cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-break-words cqa-overflow-hidden\" \n [ngClass]=\"getLogClass(log.level)\">\n {{ log.message }}\n </div>\n </cdk-virtual-scroll-viewport>\n </div>\n\n <!-- <a \n *ngIf=\"showFullLogsLink && logs?.length\"\n (click)=\"onViewFullLogs()\"\n class=\"cqa-text-[10px] cqa-leading-[15px] cqa-text-[#3F43EE] cqa-font-medium cqa-flex cqa-items-center cqa-justify-end cqa-gap-[2px] cqa-cursor-pointer hover:cqa-underline cqa-mt-4\">\n View full logs Iterations\n <div><svg width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M2.03833 6.74335L2.62833 7.33335L5.96166 4.00002L2.62833 0.666687L2.03833 1.25669L4.78166 4.00002L2.03833 6.74335Z\" fill=\"#3F43EE\"/></svg></div>\n </a> -->\n </div>\n</div>\n\n<style>\n @keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n</style>", styles: ["\n @keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n"] }]
|
|
8587
8627
|
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i1$4.MatDialog }]; }, propDecorators: { screenshots: [{
|
|
8588
8628
|
type: Input
|
|
8589
8629
|
}], logs: [{
|
|
@@ -8721,6 +8761,15 @@ class BasicStepComponent extends BaseStepComponent {
|
|
|
8721
8761
|
this.stepMoreMenuOptions = DEFAULT_STEP_MORE_MENU_OPTIONS;
|
|
8722
8762
|
// Track which steps are still loading to show skeleton
|
|
8723
8763
|
this.loadingSteps = new Set();
|
|
8764
|
+
// Processed sub-steps for live mode WAIT_FOR_LOCATOR countdown grouping
|
|
8765
|
+
this.processedSubSteps = [];
|
|
8766
|
+
this.lastProcessedIndex = 0;
|
|
8767
|
+
this.waitLocatorGroupEntry = null;
|
|
8768
|
+
this.countdownIntervalId = null;
|
|
8769
|
+
// AI_AUTO_HEAL grouping: show loading until AI_AUTO_HEAL_SUCCESS or AI_AUTO_HEAL_FAILED
|
|
8770
|
+
this.aiAutoHealGroupEntry = null;
|
|
8771
|
+
// Processed sub-steps for run result screen (filter and split AI_AUTO_HEAL_SUCCESS/FAILED)
|
|
8772
|
+
this.processedSubStepsForRunResult = [];
|
|
8724
8773
|
this.showFailedStepDetails = false;
|
|
8725
8774
|
}
|
|
8726
8775
|
/** Show debug icon when debug mode is on (shown on parent and all child steps). */
|
|
@@ -8751,6 +8800,14 @@ class BasicStepComponent extends BaseStepComponent {
|
|
|
8751
8800
|
nestedSteps: stepsToUse,
|
|
8752
8801
|
};
|
|
8753
8802
|
super.ngOnInit();
|
|
8803
|
+
// Initialize live sub-step processing for WAIT_FOR_LOCATOR grouping
|
|
8804
|
+
if (this.isLive && this.subSteps && this.subSteps.length > 0) {
|
|
8805
|
+
this.processLiveSubSteps();
|
|
8806
|
+
}
|
|
8807
|
+
else if (!this.isLive && this.subSteps && this.subSteps.length > 0) {
|
|
8808
|
+
// Process for run result screen: filter and split AI_AUTO_HEAL_SUCCESS/FAILED
|
|
8809
|
+
this.processSubStepsForRunResult();
|
|
8810
|
+
}
|
|
8754
8811
|
// Initialize loading state if already expanded
|
|
8755
8812
|
if (this.isExpanded && this.nestedSteps && this.nestedSteps.length > 0) {
|
|
8756
8813
|
this.loadingSteps.clear();
|
|
@@ -8778,6 +8835,21 @@ class BasicStepComponent extends BaseStepComponent {
|
|
|
8778
8835
|
// Update config when subSteps changes
|
|
8779
8836
|
if (changes['subSteps'] && this.config) {
|
|
8780
8837
|
this.config.subSteps = this.subSteps || [];
|
|
8838
|
+
if (this.isLive) {
|
|
8839
|
+
this.processLiveSubSteps();
|
|
8840
|
+
}
|
|
8841
|
+
else {
|
|
8842
|
+
this.processSubStepsForRunResult();
|
|
8843
|
+
}
|
|
8844
|
+
}
|
|
8845
|
+
// Re-process when isLive changes
|
|
8846
|
+
if (changes['isLive'] && this.subSteps && this.subSteps.length > 0) {
|
|
8847
|
+
if (this.isLive) {
|
|
8848
|
+
this.processLiveSubSteps();
|
|
8849
|
+
}
|
|
8850
|
+
else {
|
|
8851
|
+
this.processSubStepsForRunResult();
|
|
8852
|
+
}
|
|
8781
8853
|
}
|
|
8782
8854
|
// Update config when nestedSteps changes
|
|
8783
8855
|
if (changes['nestedSteps'] && this.config) {
|
|
@@ -8811,6 +8883,14 @@ class BasicStepComponent extends BaseStepComponent {
|
|
|
8811
8883
|
});
|
|
8812
8884
|
}
|
|
8813
8885
|
}
|
|
8886
|
+
ngDoCheck() {
|
|
8887
|
+
if (!this.isLive)
|
|
8888
|
+
return;
|
|
8889
|
+
const currentLength = (this.subSteps || []).length;
|
|
8890
|
+
if (currentLength !== this.lastProcessedIndex) {
|
|
8891
|
+
this.processLiveSubSteps();
|
|
8892
|
+
}
|
|
8893
|
+
}
|
|
8814
8894
|
get hasSubSteps() {
|
|
8815
8895
|
return this.subSteps && this.subSteps.length > 0;
|
|
8816
8896
|
}
|
|
@@ -8940,12 +9020,172 @@ class BasicStepComponent extends BaseStepComponent {
|
|
|
8940
9020
|
}
|
|
8941
9021
|
}
|
|
8942
9022
|
}
|
|
9023
|
+
ngOnDestroy() {
|
|
9024
|
+
this.clearCountdownTimer();
|
|
9025
|
+
}
|
|
9026
|
+
processLiveSubSteps() {
|
|
9027
|
+
var _a, _b, _c, _d;
|
|
9028
|
+
const allSubSteps = (this.subSteps || []);
|
|
9029
|
+
// Reset if subSteps were cleared or replaced with fewer entries
|
|
9030
|
+
if (allSubSteps.length < this.lastProcessedIndex) {
|
|
9031
|
+
this.resetLiveProcessing();
|
|
9032
|
+
}
|
|
9033
|
+
for (let i = this.lastProcessedIndex; i < allSubSteps.length; i++) {
|
|
9034
|
+
const subStep = allSubSteps[i];
|
|
9035
|
+
const uiType = (subStep === null || subStep === void 0 ? void 0 : subStep.uiType) || (subStep === null || subStep === void 0 ? void 0 : subStep.type) || '';
|
|
9036
|
+
const status = ((subStep === null || subStep === void 0 ? void 0 : subStep.status) || '').toLowerCase();
|
|
9037
|
+
if (uiType === 'WAIT_FOR_LOCATOR') {
|
|
9038
|
+
// Create a single grouped entry with a countdown; absorbs FIND_LOCATOR and LOCATOR_FOUND
|
|
9039
|
+
const timeoutSeconds = typeof subStep.value === 'number'
|
|
9040
|
+
? subStep.value
|
|
9041
|
+
: (subStep.value ? parseFloat(subStep.value) : 30);
|
|
9042
|
+
this.clearCountdownTimer();
|
|
9043
|
+
this.waitLocatorGroupEntry = Object.assign(Object.assign({}, subStep), { remainingSeconds: timeoutSeconds, status: 'running' });
|
|
9044
|
+
this.processedSubSteps.push(this.waitLocatorGroupEntry);
|
|
9045
|
+
// Tick down every second
|
|
9046
|
+
this.countdownIntervalId = setInterval(() => {
|
|
9047
|
+
if (this.waitLocatorGroupEntry) {
|
|
9048
|
+
this.waitLocatorGroupEntry.remainingSeconds = Math.max(0, this.waitLocatorGroupEntry.remainingSeconds - 1);
|
|
9049
|
+
if (this.waitLocatorGroupEntry.remainingSeconds <= 0) {
|
|
9050
|
+
this.waitLocatorGroupEntry.status = 'failed';
|
|
9051
|
+
this.waitLocatorGroupEntry.remainingSeconds = null;
|
|
9052
|
+
this.clearCountdownTimer();
|
|
9053
|
+
this.waitLocatorGroupEntry = null;
|
|
9054
|
+
}
|
|
9055
|
+
}
|
|
9056
|
+
}, 1000);
|
|
9057
|
+
}
|
|
9058
|
+
else if (uiType === 'FIND_LOCATOR') {
|
|
9059
|
+
if (status === 'failed' || status === 'failure') {
|
|
9060
|
+
// Abort countdown, replace group entry with this failed log
|
|
9061
|
+
if (this.waitLocatorGroupEntry) {
|
|
9062
|
+
this.processedSubSteps = this.processedSubSteps.filter(entry => entry !== this.waitLocatorGroupEntry);
|
|
9063
|
+
this.clearCountdownTimer();
|
|
9064
|
+
this.waitLocatorGroupEntry = null;
|
|
9065
|
+
}
|
|
9066
|
+
this.processedSubSteps.push(Object.assign(Object.assign({}, subStep), { status: 'failed' }));
|
|
9067
|
+
}
|
|
9068
|
+
else if (this.waitLocatorGroupEntry) {
|
|
9069
|
+
// Update the single group entry's text so the user sees progress
|
|
9070
|
+
const newText = subStep.description || subStep.text || subStep.title;
|
|
9071
|
+
if (newText)
|
|
9072
|
+
this.waitLocatorGroupEntry.description = newText;
|
|
9073
|
+
}
|
|
9074
|
+
}
|
|
9075
|
+
else if (uiType === 'LOCATOR_FOUND') {
|
|
9076
|
+
if (status === 'failed' || status === 'failure') {
|
|
9077
|
+
// Abort countdown, replace group entry with this failed log
|
|
9078
|
+
if (this.waitLocatorGroupEntry) {
|
|
9079
|
+
this.processedSubSteps = this.processedSubSteps.filter(entry => entry !== this.waitLocatorGroupEntry);
|
|
9080
|
+
this.clearCountdownTimer();
|
|
9081
|
+
this.waitLocatorGroupEntry = null;
|
|
9082
|
+
}
|
|
9083
|
+
this.processedSubSteps.push(Object.assign(Object.assign({}, subStep), { status: 'failed' }));
|
|
9084
|
+
}
|
|
9085
|
+
else {
|
|
9086
|
+
// Sequence complete – update group entry to show LOCATOR_FOUND text as success
|
|
9087
|
+
if (this.waitLocatorGroupEntry) {
|
|
9088
|
+
const newText = subStep.description || subStep.text || subStep.title;
|
|
9089
|
+
if (newText)
|
|
9090
|
+
this.waitLocatorGroupEntry.description = newText;
|
|
9091
|
+
this.waitLocatorGroupEntry.status = 'success';
|
|
9092
|
+
this.waitLocatorGroupEntry.remainingSeconds = null;
|
|
9093
|
+
this.clearCountdownTimer();
|
|
9094
|
+
this.waitLocatorGroupEntry = null;
|
|
9095
|
+
}
|
|
9096
|
+
else {
|
|
9097
|
+
// No active group – push LOCATOR_FOUND normally
|
|
9098
|
+
this.processedSubSteps.push(Object.assign({}, subStep));
|
|
9099
|
+
}
|
|
9100
|
+
}
|
|
9101
|
+
}
|
|
9102
|
+
else if (uiType === 'AI_AUTO_HEAL') {
|
|
9103
|
+
// Add single loading entry; will be replaced by AI_AUTO_HEAL_SUCCESS or AI_AUTO_HEAL_FAILED
|
|
9104
|
+
this.aiAutoHealGroupEntry = Object.assign(Object.assign({}, subStep), { description: subStep.description || subStep.text || 'AI auto-heal started', status: 'running', uiType: 'AI_AUTO_HEAL' });
|
|
9105
|
+
this.processedSubSteps.push(this.aiAutoHealGroupEntry);
|
|
9106
|
+
}
|
|
9107
|
+
else if (uiType === 'AI_AUTO_HEAL_SUCCESS' || uiType === 'AI_AUTO_HEAL_FAILED') {
|
|
9108
|
+
// Remove loading entry and add TWO separate entries: value and reasoning (like AI_ANSWER)
|
|
9109
|
+
if (this.aiAutoHealGroupEntry) {
|
|
9110
|
+
this.processedSubSteps = this.processedSubSteps.filter(entry => entry !== this.aiAutoHealGroupEntry);
|
|
9111
|
+
this.aiAutoHealGroupEntry = null;
|
|
9112
|
+
}
|
|
9113
|
+
const isSuccess = uiType === 'AI_AUTO_HEAL_SUCCESS';
|
|
9114
|
+
const value = (_b = (_a = subStep.value) !== null && _a !== void 0 ? _a : subStep.text) !== null && _b !== void 0 ? _b : '';
|
|
9115
|
+
const reasoning = (_d = (_c = subStep.reasoning) !== null && _c !== void 0 ? _c : subStep.Reasoning) !== null && _d !== void 0 ? _d : '';
|
|
9116
|
+
const baseDuration = subStep.duration || 0;
|
|
9117
|
+
const finalStatus = isSuccess ? 'success' : 'failed';
|
|
9118
|
+
// First entry: value/description
|
|
9119
|
+
const valueDescription = subStep.text || subStep.description || (isSuccess
|
|
9120
|
+
? `AI auto-heal successful. New locator: ${value}`
|
|
9121
|
+
: `AI auto-heal failed for element: ${value}`);
|
|
9122
|
+
this.processedSubSteps.push(Object.assign(Object.assign({}, subStep), { description: valueDescription, value: value, reasoning: null, status: finalStatus, uiType: 'AI_AUTO_HEAL_VALUE', type: 'AI_AUTO_HEAL_VALUE', duration: baseDuration, isAiAutoHealResult: true }));
|
|
9123
|
+
// Second entry: reasoning (only if present)
|
|
9124
|
+
if (reasoning) {
|
|
9125
|
+
this.processedSubSteps.push(Object.assign(Object.assign({}, subStep), { description: reasoning, value: null, reasoning: reasoning, status: finalStatus, uiType: 'AI_AUTO_HEAL_REASONING', type: 'AI_AUTO_HEAL_REASONING', duration: baseDuration, isAiAutoHealResult: true }));
|
|
9126
|
+
}
|
|
9127
|
+
}
|
|
9128
|
+
else {
|
|
9129
|
+
// Any failed log while a countdown is active – resolve it as failed
|
|
9130
|
+
if ((status === 'failed' || status === 'failure') && this.waitLocatorGroupEntry) {
|
|
9131
|
+
this.waitLocatorGroupEntry.status = 'failed';
|
|
9132
|
+
this.waitLocatorGroupEntry.remainingSeconds = null;
|
|
9133
|
+
this.clearCountdownTimer();
|
|
9134
|
+
this.waitLocatorGroupEntry = null;
|
|
9135
|
+
}
|
|
9136
|
+
this.processedSubSteps.push(subStep);
|
|
9137
|
+
}
|
|
9138
|
+
}
|
|
9139
|
+
this.lastProcessedIndex = allSubSteps.length;
|
|
9140
|
+
}
|
|
9141
|
+
resetLiveProcessing() {
|
|
9142
|
+
this.clearCountdownTimer();
|
|
9143
|
+
this.processedSubSteps = [];
|
|
9144
|
+
this.lastProcessedIndex = 0;
|
|
9145
|
+
this.waitLocatorGroupEntry = null;
|
|
9146
|
+
this.aiAutoHealGroupEntry = null;
|
|
9147
|
+
}
|
|
9148
|
+
clearCountdownTimer() {
|
|
9149
|
+
if (this.countdownIntervalId !== null) {
|
|
9150
|
+
clearInterval(this.countdownIntervalId);
|
|
9151
|
+
this.countdownIntervalId = null;
|
|
9152
|
+
}
|
|
9153
|
+
}
|
|
9154
|
+
processSubStepsForRunResult() {
|
|
9155
|
+
var _a, _b, _c, _d;
|
|
9156
|
+
const allSubSteps = (this.subSteps || []);
|
|
9157
|
+
this.processedSubStepsForRunResult = [];
|
|
9158
|
+
for (const subStep of allSubSteps) {
|
|
9159
|
+
const uiType = (subStep === null || subStep === void 0 ? void 0 : subStep.uiType) || (subStep === null || subStep === void 0 ? void 0 : subStep.type) || '';
|
|
9160
|
+
// Split AI_AUTO_HEAL_SUCCESS/FAILED into two entries
|
|
9161
|
+
if (uiType === 'AI_AUTO_HEAL_SUCCESS' || uiType === 'AI_AUTO_HEAL_FAILED') {
|
|
9162
|
+
const isSuccess = uiType === 'AI_AUTO_HEAL_SUCCESS';
|
|
9163
|
+
const value = (_b = (_a = subStep.value) !== null && _a !== void 0 ? _a : subStep.text) !== null && _b !== void 0 ? _b : '';
|
|
9164
|
+
const reasoning = (_d = (_c = subStep.reasoning) !== null && _c !== void 0 ? _c : subStep.Reasoning) !== null && _d !== void 0 ? _d : '';
|
|
9165
|
+
const baseDuration = subStep.duration || 0;
|
|
9166
|
+
const finalStatus = isSuccess ? 'success' : 'failed';
|
|
9167
|
+
// First entry: value/description
|
|
9168
|
+
const valueDescription = (isSuccess
|
|
9169
|
+
? `AI auto-heal successful. New locator: ${value}`
|
|
9170
|
+
: `AI auto-heal failed for element: ${value}`);
|
|
9171
|
+
this.processedSubStepsForRunResult.push(Object.assign(Object.assign({}, subStep), { description: valueDescription, value: value, reasoning: null, status: finalStatus, uiType: 'AI_AUTO_HEAL_VALUE', type: 'AI_AUTO_HEAL_VALUE', duration: baseDuration, isAiAutoHealResult: true }));
|
|
9172
|
+
// Second entry: reasoning (only if present)
|
|
9173
|
+
if (reasoning) {
|
|
9174
|
+
this.processedSubStepsForRunResult.push(Object.assign(Object.assign({}, subStep), { description: reasoning, value: null, reasoning: reasoning, status: finalStatus, uiType: 'AI_AUTO_HEAL_REASONING', type: 'AI_AUTO_HEAL_REASONING', duration: baseDuration, isAiAutoHealResult: true }));
|
|
9175
|
+
}
|
|
9176
|
+
}
|
|
9177
|
+
else {
|
|
9178
|
+
// All other logs pass through as-is
|
|
9179
|
+
this.processedSubStepsForRunResult.push(subStep);
|
|
9180
|
+
}
|
|
9181
|
+
}
|
|
9182
|
+
}
|
|
8943
9183
|
}
|
|
8944
9184
|
BasicStepComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: BasicStepComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
8945
|
-
BasicStepComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: BasicStepComponent, selector: "cqa-basic-step", inputs: { id: "id", testStepResultId: "testStepResultId", stepNumber: "stepNumber", title: "title", status: "status", isDebug: "isDebug", debugPointSet: "debugPointSet", getDebugPointSetHandler: "getDebugPointSetHandler", onDebugPointChangeHandler: "onDebugPointChangeHandler", duration: "duration", timingBreakdown: "timingBreakdown", expanded: "expanded", subSteps: "subSteps", selfHealAnalysis: "selfHealAnalysis", selfHealed: "selfHealed", selfHealDuration: "selfHealDuration", failureDetails: "failureDetails", reasoning: "reasoning", confidence: "confidence", stepDeleted: "stepDeleted", isUploadingBaseline: "isUploadingBaseline", isMakingCurrentBaseline: "isMakingCurrentBaseline", isLive: "isLive", nestedSteps: "nestedSteps", hasChild: "hasChild", isLoading: "isLoading", onExpandHandler: "onExpandHandler", onEditStepHandler: "onEditStepHandler", onAddStepOptionSelectHandler: "onAddStepOptionSelectHandler", onStepMoreOptionSelectHandler: "onStepMoreOptionSelectHandler", getConditionBranchesHandler: "getConditionBranchesHandler", onConditionBranchClickHandler: "onConditionBranchClickHandler", isStepLoadingHandler: "isStepLoadingHandler", isStepExpandedHandler: "isStepExpandedHandler", convertMsToSecondsHandler: "convertMsToSecondsHandler", formatFailureDetailsHandler: "formatFailureDetailsHandler", getSelfHealAnalysisHandler: "getSelfHealAnalysisHandler", onMakeCurrentBaselineHandler: "onMakeCurrentBaselineHandler", onUploadBaselineHandler: "onUploadBaselineHandler", onAnalyzeHandler: "onAnalyzeHandler", onViewFullLogsHandler: "onViewFullLogsHandler", onSelfHealActionHandler: "onSelfHealActionHandler", getSelfHealLoadingStatesHandler: "getSelfHealLoadingStatesHandler", getLoopIterationsHandler: "getLoopIterationsHandler", getApiAssertionsHandler: "getApiAssertionsHandler", formatActionsHandler: "formatActionsHandler", onViewAllIterationsHandler: "onViewAllIterationsHandler", onStepClickHandler: "onStepClickHandler", onJsonPathCopiedHandler: "onJsonPathCopiedHandler", onDownloadHandler: "onDownloadHandler", onFilePathCopiedHandler: "onFilePathCopiedHandler", onTextCopiedHandler: "onTextCopiedHandler", jumpToTimestampHandler: "jumpToTimestampHandler", downloadingStepId: "downloadingStepId", step: "step", addStepMenuOptions: "addStepMenuOptions", stepMoreMenuOptions: "stepMoreMenuOptions" }, outputs: { debugPointChange: "debugPointChange", makeCurrentBaseline: "makeCurrentBaseline", uploadBaseline: "uploadBaseline", analyze: "analyze", viewFullLogs: "viewFullLogs", selfHealAction: "selfHealAction", editStep: "editStep", addStepOptionSelect: "addStepOptionSelect", stepMoreOptionSelect: "stepMoreOptionSelect" }, host: { classAttribute: "cqa-ui-root" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-font-inter\" (click)=\"$event.stopPropagation()\">\n <!-- Header -->\n <div\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-p-2 cqa-cursor-pointer\"\n (click)=\"toggleHeader($event)\"\n style=\"border-bottom: '1px solid #F3F4F6'\"\n >\n <div *ngIf=\"showDebugIcon\" class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer cqa-rounded-full hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" (click)=\"onDebugPointClick($event)\" [attr.aria-label]=\"debugPointSet ? 'Remove debug point' : 'Set debug point'\">\n <svg *ngIf=\"debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" fill=\"#C63535\"/>\n </svg>\n <svg *ngIf=\"!debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" stroke=\"#C63535\" stroke-width=\"1.5\" fill=\"none\"/>\n </svg>\n </button>\n </div>\n <!-- Status Icon -->\n <!-- {{ getStatusIcon(config.status) }} -->\n<!-- Success -->\n <div *ngIf=\"config.status.toLowerCase() === 'success'\" >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Failure -->\n <div *ngIf=\"config.status.toLowerCase() === 'failure' || config.status.toLowerCase() === 'failed'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7.5 4.5L4.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 4.5L7.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Pending -->\n <div *ngIf=\"config.status.toLowerCase() === 'pending'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Running - Show spinner -->\n <div *ngIf=\"config.status.toLowerCase() === 'running'\">\n <svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n </div>\n <!-- Skipped -->\n <div class=\"cqa-flex cqa-items-center\" *ngIf=\"config.status.toLowerCase() === 'skipped'\">\n <span class=\"material-symbols-outlined cqa-text-[#9CA3AF] cqa-text-[12px]\">\n skip_next\n </span>\n </div>\n\n <!-- Step Number and Title -->\n <div class=\"cqa-font-semibold cqa-flex-1 cqa-text-[#334155] cqa-text-[14px] cqa-leading-[18px] cqa-font-inter cqa-flex cqa-items-center cqa-gap-1\" style=\"word-break: break-word;\">\n <span>{{ stepNumber }}. <span [innerHTML]=\"title\"></span></span>\n <span *ngIf=\"config.stepDeleted\" class=\"cqa-px-1.5 cqa-py-[2px] cqa-rounded-[4px] cqa-text-[10px] cqa-leading-[12px] cqa-font-medium cqa-text-[#B42318] cqa-bg-[#FEF3F2] cqa-border cqa-border-[#FEE4E2]\">\n Deleted\n </span>\n </div>\n\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-font-inter\">\n <span *ngIf=\"selfHealAnalysis\" class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-[#097E53] cqa-bg-[#CFF2E5] cqa-text-[10px] cqa-leading-[15px] cqa-min-w-max cqa-flex cqa-items-center cqa-gap-[6px]\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"9\" height=\"9\" viewBox=\"0 0 9 9\" fill=\"none\">\n <path d=\"M4.50941 0C4.56489 0.0227384 4.58859 0.0782652 4.61131 0.129846C4.62269 0.1599 4.63314 0.190117 4.64329 0.220575C4.64726 0.232247 4.65123 0.243918 4.65532 0.255943C4.70806 0.413005 4.75504 0.571748 4.80229 0.73038C4.81297 0.76619 4.82369 0.801987 4.83442 0.837783C4.88905 1.02004 4.94327 1.2024 4.99719 1.38484C5.00476 1.41047 5.01234 1.43609 5.01992 1.46171C5.04128 1.53395 5.06262 1.60619 5.08383 1.67847C5.12867 1.8312 5.17473 1.98347 5.22378 2.13501C5.22807 2.14827 5.23236 2.16152 5.23677 2.17518C5.3642 2.565 5.54482 2.91437 5.8409 3.21196C5.84823 3.2197 5.85556 3.22744 5.86312 3.23541C5.9895 3.36437 6.15169 3.46771 6.3138 3.55111C6.32206 3.55542 6.33031 3.55974 6.33882 3.56419C6.81587 3.80925 7.38951 3.91704 7.90619 4.0605C8.1326 4.1234 8.3583 4.18829 8.58317 4.25603C8.59897 4.26079 8.61478 4.26554 8.63058 4.27028C8.67784 4.28445 8.725 4.29887 8.77211 4.31347C8.7831 4.31679 8.79408 4.32011 8.80539 4.32353C8.87029 4.34406 8.93239 4.36829 8.98566 4.41027C9.00191 4.44418 9.00191 4.44418 8.99748 4.4781C8.94564 4.52736 8.8942 4.55046 8.82578 4.573C8.816 4.57632 8.80622 4.57965 8.79614 4.58308C8.68061 4.62183 8.56351 4.65575 8.44626 4.68935C8.4222 4.6963 8.39814 4.70326 8.37408 4.71021C8.22571 4.75301 8.07708 4.7949 7.92829 4.83632C7.73232 4.89088 7.53663 4.94634 7.34113 5.00243C7.3091 5.01162 7.27706 5.02078 7.24501 5.02991C7.07671 5.07786 6.90923 5.12753 6.74314 5.18208C6.72937 5.18659 6.71559 5.1911 6.70139 5.19574C6.14511 5.38082 5.7211 5.72609 5.45571 6.23099C5.31263 6.51475 5.22823 6.82161 5.14214 7.12447C5.11884 7.20619 5.09409 7.28745 5.06905 7.36869C5.0494 7.43261 5.0302 7.49663 5.01149 7.56081C5.00926 7.56844 5.00703 7.57608 5.00473 7.58395C4.99394 7.62094 4.98319 7.65793 4.97252 7.69495C4.94519 7.78879 4.91578 7.88187 4.88555 7.97489C4.83191 8.14021 4.7831 8.30674 4.73459 8.4735C4.66144 8.72457 4.66144 8.72457 4.61997 8.84527C4.61721 8.85337 4.61446 8.86147 4.61163 8.86982C4.59649 8.91278 4.58092 8.95233 4.55226 8.9887C4.50867 8.99788 4.50867 8.99788 4.46951 9C4.42473 8.93759 4.39508 8.87711 4.37133 8.80508C4.36787 8.79487 4.36441 8.78466 4.36085 8.77415C4.31684 8.64248 4.27751 8.50946 4.23817 8.37646C4.22916 8.34604 4.22011 8.31564 4.21105 8.28524C4.1436 8.05863 4.07725 7.83174 4.01101 7.60481C3.73507 6.48224 3.73507 6.48224 3.039 5.57466C3.02784 5.56596 3.01669 5.55726 3.00519 5.5483C2.54913 5.19902 1.94834 5.06969 1.39815 4.91813C1.26207 4.88062 1.12605 4.84293 0.990032 4.80523C0.978138 4.80193 0.978138 4.80193 0.966003 4.79857C0.769811 4.74417 0.573674 4.68963 0.378224 4.63283C0.369956 4.63045 0.361688 4.62806 0.353169 4.62561C0.0528989 4.53883 0.0528989 4.53883 0.000646537 4.4781C-0.000831261 4.45054 -0.000831261 4.45054 0.0124689 4.42157C0.0670835 4.3704 0.120077 4.34848 0.19216 4.32619C0.202597 4.32284 0.213034 4.31948 0.223787 4.31603C0.255753 4.30582 0.287788 4.29584 0.319851 4.28592C0.329001 4.28305 0.338151 4.28017 0.347578 4.27722C0.412285 4.25693 0.477225 4.2374 0.542259 4.21809C0.55824 4.21332 0.55824 4.21332 0.574544 4.20846C0.852269 4.12587 1.13181 4.049 1.41126 3.97196C1.6195 3.91455 1.82738 3.85618 2.0346 3.79548C2.04413 3.79271 2.05365 3.78993 2.06346 3.78707C2.5435 3.64696 3.01278 3.44816 3.32274 3.0537C3.32738 3.04785 3.33202 3.042 3.3368 3.03597C3.68197 2.59815 3.81658 2.06572 3.96695 1.54621C4.01643 1.37534 4.06649 1.20464 4.11673 1.03399C4.13064 0.986733 4.14453 0.939471 4.15836 0.892194C4.21394 0.702289 4.27035 0.512642 4.33 0.323864C4.33558 0.306186 4.34114 0.288501 4.34666 0.270807C4.43017 0.00398761 4.43017 0.00398761 4.50941 0Z\" fill=\"#0DBD7D\"/>\n <path d=\"M7.23597 0.554859C7.29024 0.613599 7.30109 0.682631 7.31799 0.757638C7.37436 0.993269 7.43929 1.20993 7.66467 1.34681C7.80371 1.42035 7.96944 1.45381 8.1235 1.48541C8.18854 1.49902 8.24348 1.51709 8.29924 1.55321C8.31181 1.57229 8.31181 1.57229 8.31107 1.60549C8.29814 1.64588 8.28678 1.6589 8.25269 1.68533C8.21543 1.69726 8.21543 1.69726 8.17068 1.70653C8.15375 1.71025 8.13683 1.714 8.11992 1.71779C8.11086 1.7198 8.10181 1.72181 8.09247 1.72388C7.81696 1.78482 7.81696 1.78482 7.57882 1.92273C7.57108 1.92869 7.56333 1.93466 7.55536 1.9408C7.38516 2.08431 7.34916 2.32303 7.29793 2.52301C7.29499 2.53399 7.29206 2.54497 7.28903 2.55629C7.28649 2.56601 7.28395 2.57573 7.28133 2.58575C7.27028 2.61544 7.25881 2.63479 7.23597 2.65754C7.17234 2.66527 7.17234 2.66527 7.14139 2.65754C7.09216 2.62106 7.08114 2.5795 7.06828 2.52365C7.06613 2.51501 7.06398 2.50636 7.06176 2.49745C7.05489 2.46983 7.04824 2.44217 7.04164 2.41449C6.98979 2.19897 6.93126 1.98751 6.72451 1.86118C6.56293 1.77501 6.36646 1.73426 6.18587 1.70136C6.13637 1.69151 6.10802 1.67911 6.07738 1.64012C6.07073 1.60055 6.07073 1.60055 6.07738 1.56098C6.12447 1.51437 6.17402 1.50299 6.23772 1.48891C6.25778 1.48416 6.27784 1.47938 6.29789 1.47456C6.30825 1.47209 6.31861 1.46962 6.32929 1.46707C6.38212 1.45407 6.43443 1.43949 6.48673 1.42462C6.49623 1.42198 6.50573 1.41935 6.51552 1.41663C6.62182 1.38624 6.71356 1.34737 6.79854 1.27836C6.80647 1.27213 6.81439 1.26589 6.82255 1.25946C6.9548 1.14565 6.99974 0.974674 7.04053 0.815134C7.04364 0.803022 7.04675 0.79091 7.04995 0.778432C7.05614 0.754101 7.06222 0.729743 7.06817 0.705359C7.07243 0.688394 7.07243 0.688394 7.07678 0.671086C7.07927 0.660951 7.08175 0.650816 7.08431 0.640373C7.09521 0.608108 7.10952 0.582772 7.12957 0.554859C7.1681 0.536435 7.19515 0.544764 7.23597 0.554859Z\" fill=\"#075F3F\"/>\n <path d=\"M1.79545 6.2471C1.80951 6.24719 1.80951 6.24719 1.82386 6.24729C1.92477 6.25022 1.99304 6.28115 2.06736 6.34601C2.15384 6.43533 2.19377 6.53611 2.1915 6.6565C2.18178 6.75412 2.12158 6.83935 2.04773 6.90533C1.96081 6.97242 1.87313 6.99459 1.76206 6.99149C1.66841 6.98107 1.5803 6.93852 1.51393 6.87451C1.43138 6.76681 1.40725 6.66803 1.41935 6.53537C1.44433 6.43092 1.51637 6.34613 1.6085 6.28666C1.67251 6.25564 1.72399 6.24652 1.79545 6.2471Z\" fill=\"#0DBD7D\"/>\n </svg>\n Self-healed\n </span>\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-rounded-[4px] cqa-py-0.5 cqa-px-1 cqa-bg-[#6366F11A] cqa-ml-1 cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity\" \n *ngIf=\"step?.executedResult?.video_start_time\" \n [matTooltip]=\"'Jump to video time'\" \n matTooltipPosition=\"below\"\n (click)=\"onJumpToTimestamp($event)\">\n <mat-icon class=\"cqa-text-[#636363] !cqa-text-[10px] !cqa-w-[10px] !cqa-h-[10px]\">\n play_arrow\n </mat-icon>\n <span class=\"cqa-text-[8px] cqa-leading-[12px] cqa-font-normal cqa-text-[#636363]\">\n {{ formatDurationClock(step?.executedResult?.video_start_time || 0) }}\n </span>\n </div>\n <div *ngIf=\"isDebug\" class=\"cqa-flex cqa-items-center cqa-gap-0.5 cqa-text-[#9CA3AF]\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Edit\" (click)=\"onEditStep($event)\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">edit</mat-icon>\n </button>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Add\" [matMenuTriggerFor]=\"addStepMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">add</mat-icon>\n </button>\n <mat-menu #addStepMenu=\"matMenu\" class=\"cqa-add-step-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of addStepMenuOptions\" (click)=\"onAddStepOptionSelect(opt, $event)\">\n {{ opt.label }}\n </button>\n </mat-menu>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"More options\" [matMenuTriggerFor]=\"stepMoreMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">more_vert</mat-icon>\n </button>\n <mat-menu #stepMoreMenu=\"matMenu\" class=\"cqa-step-more-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of stepMoreMenuOptions\" (click)=\"onStepMoreOptionSelect(opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n </div>\n <span class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF]\">\n {{ formatDuration(duration) }}\n </span>\n <svg *ngIf=\"hasSubSteps || (config.nestedSteps && config.nestedSteps.length > 0)\" [class.cqa-rotate-180]=\"isExpanded\" class=\"cqa-transition-transform\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M3.5 5L7 8.5L10.5 5\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n </div>\n\n <!-- Expanded Content -->\n <div *ngIf=\"isExpanded && (hasSubSteps || (config.nestedSteps && config.nestedSteps.length > 0))\">\n <!-- Sub-steps -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-1 cqa-pt-1 cqa-pl-9\">\n <div\n *ngFor=\"let subStep of subSteps\"\n class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-py-[5.5px] cqa-px-3\">\n \n <!-- Sub-step Status Icon -->\n <!-- <mat-icon\n class=\"!cqa-w-4 !cqa-h-4 !cqa-text-[16px]\"\n [ngClass]=\"getStatusColorClass(subStep.status)\">\n {{ getStatusIcon(subStep.status) }}\n </mat-icon> -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'success' || subStep?.status?.toLowerCase() === 'passed'\" >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Failure -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'failure' || subStep?.status?.toLowerCase() === 'failed'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7.5 4.5L4.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 4.5L7.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Pending -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'pending'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Running - Show spinner -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'running'\">\n <svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n </div>\n\n <!-- Sub-step Description -->\n <span class=\"cqa-flex-1 cqa-text-[13px] cqa-leading-[15px] cqa-text-[#364153]\" style=\"white-space: pre-line; word-break: break-word;\">\n {{ subStep.description }}\n </span>\n\n <!-- Sub-step Duration -->\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-metadata-key\">\n {{ formatDuration(subStep.duration) }}\n </span>\n </div>\n </div>\n\n <!-- Nested Steps -->\n <div *ngIf=\"hasChild || (config.nestedSteps && config.nestedSteps.length > 0)\" class=\"cqa-ml-9 cqa-pb-1\" style=\"border-bottom: '1px solid #F3F4F6'\">\n <div class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#737373] cqa-py-[2px] cqa-px-3\">Nested steps</div>\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2 cqa-pl-[18px]\" style=\"border-left: 2px solid #C5C7FA;\">\n <!-- Loading indicator for nested steps -->\n <div *ngIf=\"hasChild && (!config.nestedSteps || config.nestedSteps.length === 0) && isStepLoading()\" \n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-py-2 cqa-px-3\">\n <svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M7 1A6 6 0 0 1 13 7\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n <span class=\"cqa-text-[11px] cqa-leading-[13px] cqa-text-[#737373]\">Loading nested steps...</span>\n </div>\n\n\n <ng-container *ngFor=\"let step of config.nestedSteps; index as i\">\n <!-- Wrapper to show skeleton while step-renderer is loading -->\n <div\n class=\"cqa-step-renderer-wrapper\"\n [attr.id]=\"'exc-' + step.id\"\n [class.loaded]=\"!isNestedStepLoading(step)\">\n <!-- Loading skeleton overlay -->\n <!-- <div *ngIf=\"isNestedStepLoading(step)\" class=\"cqa-step-skeleton-overlay\">\n <div class=\"cqa-step-skeleton cqa-mx-3 cqa-my-1\"></div>\n </div> -->\n <!-- Use step-renderer for all nested steps to avoid circular dependencies -->\n <!-- The step-renderer will dynamically load the appropriate component and pass handlers -->\n <cqa-step-renderer \n [step]=\"step\"\n [stepNumber]=\"stepNumber + '.' + (i + 1)\"\n [onExpandHandler]=\"onExpandHandler\"\n [onConditionBranchClickHandler]=\"onConditionBranchClickHandler\"\n [getConditionBranchesHandler]=\"getConditionBranchesHandler\"\n [isStepLoadingHandler]=\"isStepLoadingHandler\"\n [isStepExpandedHandler]=\"isStepExpandedHandler\"\n [jumpToTimestampHandler]=\"jumpToTimestampHandler\"\n [convertMsToSecondsHandler]=\"convertMsToSecondsHandler\"\n [formatFailureDetailsHandler]=\"formatFailureDetailsHandler\"\n [getSelfHealAnalysisHandler]=\"getSelfHealAnalysisHandler\"\n [getLoopIterationsHandler]=\"getLoopIterationsHandler\"\n [getApiAssertionsHandler]=\"getApiAssertionsHandler\"\n [formatActionsHandler]=\"formatActionsHandler\"\n [onViewAllIterationsHandler]=\"onViewAllIterationsHandler\"\n [onMakeCurrentBaselineHandler]=\"onMakeCurrentBaselineHandler\"\n [onUploadBaselineHandler]=\"onUploadBaselineHandler\"\n [onAnalyzeHandler]=\"onAnalyzeHandler\"\n [onViewFullLogsHandler]=\"onViewFullLogsHandler\"\n [onSelfHealActionHandler]=\"onSelfHealActionHandler\"\n [getSelfHealLoadingStatesHandler]=\"getSelfHealLoadingStatesHandler\"\n [onStepClickHandler]=\"onStepClickHandler\"\n [onJsonPathCopiedHandler]=\"onJsonPathCopiedHandler\"\n [onDownloadHandler]=\"onDownloadHandler\"\n [onFilePathCopiedHandler]=\"onFilePathCopiedHandler\"\n [onTextCopiedHandler]=\"onTextCopiedHandler\"\n [downloadingStepId]=\"downloadingStepId\"\n [isUploadingBaseline]=\"isUploadingBaseline\"\n [isMakingCurrentBaseline]=\"isMakingCurrentBaseline\"\n [isLive]=\"isLive\"\n [isDebug]=\"isDebug\"\n [debugPointSet]=\"getDebugPointSetHandler ? getDebugPointSetHandler(step) : debugPointSet\"\n [getDebugPointSetHandler]=\"getDebugPointSetHandler\"\n [onDebugPointChangeHandler]=\"onDebugPointChangeHandler\"\n [onEditStepHandler]=\"onEditStepHandler\"\n [addStepMenuOptions]=\"addStepMenuOptions\"\n [onAddStepOptionSelectHandler]=\"onAddStepOptionSelectHandler\"\n [stepMoreMenuOptions]=\"stepMoreMenuOptions\"\n [onStepMoreOptionSelectHandler]=\"onStepMoreOptionSelectHandler\"\n (componentReady)=\"markStepLoaded(step)\">\n </cqa-step-renderer>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Self Heal Analysis -->\n <cqa-self-heal-analysis \n *ngIf=\"selfHealAnalysis\" \n [id]=\"step?.testStepId\"\n [originalLocator]=\"selfHealAnalysis.originalLocator\"\n [healedLocator]=\"selfHealAnalysis.healedLocator\"\n [confidence]=\"selfHealAnalysis.confidence\"\n [healMethod]=\"selfHealAnalysis.healMethod\"\n [isLoadingAccept]=\"getSelfHealLoadingStatesHandler ? getSelfHealLoadingStatesHandler().isLoadingAccept?.[step?.testStepId] : false\"\n [isLoadingModifyAccept]=\"getSelfHealLoadingStatesHandler ? getSelfHealLoadingStatesHandler().isLoadingModifyAccept?.[step?.testStepId] : false\"\n (action)=\"onSelfHealAction($event)\">\n </cqa-self-heal-analysis>\n\n <!-- Timing Breakdown -->\n <div *ngIf=\"timingBreakdown\" class=\"cqa-flex cqa-items-center cqa-justify-end cqa-gap-5 cqa-mt-1 cqa-pt-4 cqa-px-4 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF]\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <span>Timing breakdown</span>\n </div>\n <span class=\"cqa-text-dialog-muted cqa-flex cqa-items-center cqa-gap-3\">\n <div>\n App <span class=\"cqa-text-gray-700\">{{ formatDuration(timingBreakdown.app) }}</span>\n </div>\n <div><svg width=\"1\" height=\"11\" viewBox=\"0 0 1 11\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M-3.8147e-06 10.32V-7.15256e-07H0.959996V10.32H-3.8147e-06Z\" fill=\"#E5E7EB\"/></svg></div>\n <div>\n Tool <span class=\"cqa-text-gray-700\">{{ formatDuration(timingBreakdown.tool) }}</span>\n </div>\n </span>\n </div>\n </div>\n\n <!-- View More Failed Step Button - shown when expanded and failure details exist -->\n <div *ngIf=\"showViewMoreButton\" class=\"cqa-mt-2 cqa-px-4\">\n <cqa-view-more-failed-step-button\n [timingBreakdown]=\"timingBreakdown\"\n [subSteps]=\"subSteps\"\n [failureDetails]=\"failureDetails\"\n [isExpanded]=\"showFailedStepDetails\"\n (viewMoreClick)=\"onViewMoreFailedStepClick($event)\">\n </cqa-view-more-failed-step-button>\n </div>\n\n <!-- Updated Failed Step Component - shown when button is clicked -->\n <div *ngIf=\"showViewMoreButton && showFailedStepDetails && failureDetails\" class=\"cqa-mt-2 cqa-px-4\">\n <cqa-updated-failed-step\n [testStepResultId]=\"testStepResultId\"\n [timingBreakdown]=\"timingBreakdown\"\n [expanded]=\"true\"\n [subSteps]=\"subSteps\"\n [failureDetails]=\"failureDetails\"\n [reasoning]=\"reasoning\"\n [confidence]=\"confidence\"\n [isUploadingBaseline]=\"isUploadingBaseline\"\n [isMakingCurrentBaseline]=\"isMakingCurrentBaseline\"\n [isLive]=\"isLive\"\n (makeCurrentBaseline)=\"onMakeCurrentBaseline($event)\"\n (uploadBaseline)=\"onUploadBaseline($event)\"\n (analyze)=\"onAnalyze()\"\n (viewFullLogs)=\"onViewFullLogs()\">\n </cqa-updated-failed-step>\n </div>\n</div>\n", components: [{ type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i2$1.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { type: i2$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { type: StepRendererComponent, selector: "cqa-step-renderer", inputs: ["step", "onExpandHandler", "getConditionBranchesHandler", "isStepLoadingHandler", "isStepExpandedHandler", "convertMsToSecondsHandler", "formatFailureDetailsHandler", "getSelfHealAnalysisHandler", "onMakeCurrentBaselineHandler", "onUploadBaselineHandler", "onAnalyzeHandler", "onViewFullLogsHandler", "onSelfHealActionHandler", "getSelfHealLoadingStatesHandler", "isUploadingBaseline", "isMakingCurrentBaseline", "selectedIterationId", "getLoopIterationsHandler", "getApiAssertionsHandler", "formatActionsHandler", "onViewAllIterationsHandler", "onConditionBranchClickHandler", "onStepClickHandler", "onJsonPathCopiedHandler", "onDownloadHandler", "onFilePathCopiedHandler", "onTextCopiedHandler", "jumpToTimestampHandler", "downloadingStepId", "isLive", "isDebug", "debugPointSet", "getDebugPointSetHandler", "onDebugPointChangeHandler", "onEditStepHandler", "addStepMenuOptions", "onAddStepOptionSelectHandler", "stepMoreMenuOptions", "onStepMoreOptionSelectHandler", "getAddStepMenuOptionsForNested", "getStepMoreMenuOptionsForNested", "stepNumber"], outputs: ["addStepOptionSelect", "stepMoreOptionSelect", "componentReady"] }, { type: SelfHealAnalysisComponent, selector: "cqa-self-heal-analysis", inputs: ["id", "originalLocator", "healedLocator", "confidence", "healMethod", "isLoadingAccept", "isLoadingModifyAccept"], outputs: ["action"] }, { type: ViewMoreFailedStepButtonComponent, selector: "cqa-view-more-failed-step-button", inputs: ["timingBreakdown", "subSteps", "failureDetails", "isExpanded"], outputs: ["viewMoreClick"] }, { type: UpdatedFailedStepComponent, selector: "cqa-updated-failed-step", inputs: ["timingBreakdown", "testStepResultId", "expanded", "subSteps", "failureDetails", "reasoning", "confidence", "isUploadingBaseline", "isMakingCurrentBaseline", "isLive"], outputs: ["makeCurrentBaseline", "uploadBaseline", "analyze", "viewFullLogs"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { type: i2$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
|
|
9185
|
+
BasicStepComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: BasicStepComponent, selector: "cqa-basic-step", inputs: { id: "id", testStepResultId: "testStepResultId", stepNumber: "stepNumber", title: "title", status: "status", isDebug: "isDebug", debugPointSet: "debugPointSet", getDebugPointSetHandler: "getDebugPointSetHandler", onDebugPointChangeHandler: "onDebugPointChangeHandler", duration: "duration", timingBreakdown: "timingBreakdown", expanded: "expanded", subSteps: "subSteps", selfHealAnalysis: "selfHealAnalysis", selfHealed: "selfHealed", selfHealDuration: "selfHealDuration", failureDetails: "failureDetails", reasoning: "reasoning", confidence: "confidence", stepDeleted: "stepDeleted", isUploadingBaseline: "isUploadingBaseline", isMakingCurrentBaseline: "isMakingCurrentBaseline", isLive: "isLive", nestedSteps: "nestedSteps", hasChild: "hasChild", isLoading: "isLoading", onExpandHandler: "onExpandHandler", onEditStepHandler: "onEditStepHandler", onAddStepOptionSelectHandler: "onAddStepOptionSelectHandler", onStepMoreOptionSelectHandler: "onStepMoreOptionSelectHandler", getConditionBranchesHandler: "getConditionBranchesHandler", onConditionBranchClickHandler: "onConditionBranchClickHandler", isStepLoadingHandler: "isStepLoadingHandler", isStepExpandedHandler: "isStepExpandedHandler", convertMsToSecondsHandler: "convertMsToSecondsHandler", formatFailureDetailsHandler: "formatFailureDetailsHandler", getSelfHealAnalysisHandler: "getSelfHealAnalysisHandler", onMakeCurrentBaselineHandler: "onMakeCurrentBaselineHandler", onUploadBaselineHandler: "onUploadBaselineHandler", onAnalyzeHandler: "onAnalyzeHandler", onViewFullLogsHandler: "onViewFullLogsHandler", onSelfHealActionHandler: "onSelfHealActionHandler", getSelfHealLoadingStatesHandler: "getSelfHealLoadingStatesHandler", getLoopIterationsHandler: "getLoopIterationsHandler", getApiAssertionsHandler: "getApiAssertionsHandler", formatActionsHandler: "formatActionsHandler", onViewAllIterationsHandler: "onViewAllIterationsHandler", onStepClickHandler: "onStepClickHandler", onJsonPathCopiedHandler: "onJsonPathCopiedHandler", onDownloadHandler: "onDownloadHandler", onFilePathCopiedHandler: "onFilePathCopiedHandler", onTextCopiedHandler: "onTextCopiedHandler", jumpToTimestampHandler: "jumpToTimestampHandler", downloadingStepId: "downloadingStepId", step: "step", addStepMenuOptions: "addStepMenuOptions", stepMoreMenuOptions: "stepMoreMenuOptions" }, outputs: { debugPointChange: "debugPointChange", makeCurrentBaseline: "makeCurrentBaseline", uploadBaseline: "uploadBaseline", analyze: "analyze", viewFullLogs: "viewFullLogs", selfHealAction: "selfHealAction", editStep: "editStep", addStepOptionSelect: "addStepOptionSelect", stepMoreOptionSelect: "stepMoreOptionSelect" }, host: { classAttribute: "cqa-ui-root" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-font-inter\" (click)=\"$event.stopPropagation()\">\n <!-- Header -->\n <div\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-p-2 cqa-cursor-pointer\"\n (click)=\"toggleHeader($event)\"\n style=\"border-bottom: '1px solid #F3F4F6'\"\n >\n <div *ngIf=\"showDebugIcon\" class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer cqa-rounded-full hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" (click)=\"onDebugPointClick($event)\" [attr.aria-label]=\"debugPointSet ? 'Remove debug point' : 'Set debug point'\">\n <svg *ngIf=\"debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" fill=\"#C63535\"/>\n </svg>\n <svg *ngIf=\"!debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" stroke=\"#C63535\" stroke-width=\"1.5\" fill=\"none\"/>\n </svg>\n </button>\n </div>\n <!-- Status Icon -->\n <!-- {{ getStatusIcon(config.status) }} -->\n<!-- Success -->\n <div *ngIf=\"config.status.toLowerCase() === 'success'\" >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Failure -->\n <div *ngIf=\"config.status.toLowerCase() === 'failure' || config.status.toLowerCase() === 'failed'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7.5 4.5L4.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 4.5L7.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Pending -->\n <div *ngIf=\"config.status.toLowerCase() === 'pending'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Running - Show spinner -->\n <div *ngIf=\"config.status.toLowerCase() === 'running'\">\n <svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n </div>\n <!-- Skipped -->\n <div class=\"cqa-flex cqa-items-center\" *ngIf=\"config.status.toLowerCase() === 'skipped'\">\n <span class=\"material-symbols-outlined cqa-text-[#9CA3AF] cqa-text-[12px]\">\n skip_next\n </span>\n </div>\n\n <!-- Step Number and Title -->\n <div class=\"cqa-font-semibold cqa-flex-1 cqa-text-[#334155] cqa-text-[14px] cqa-leading-[18px] cqa-font-inter cqa-flex cqa-items-center cqa-gap-1\" style=\"word-break: break-word;\">\n <span>{{ stepNumber }}. <span [innerHTML]=\"title\"></span></span>\n <span *ngIf=\"config.stepDeleted\" class=\"cqa-px-1.5 cqa-py-[2px] cqa-rounded-[4px] cqa-text-[10px] cqa-leading-[12px] cqa-font-medium cqa-text-[#B42318] cqa-bg-[#FEF3F2] cqa-border cqa-border-[#FEE4E2]\">\n Deleted\n </span>\n </div>\n\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-font-inter\">\n <span *ngIf=\"selfHealAnalysis\" class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-[#097E53] cqa-bg-[#CFF2E5] cqa-text-[10px] cqa-leading-[15px] cqa-min-w-max cqa-flex cqa-items-center cqa-gap-[6px]\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"9\" height=\"9\" viewBox=\"0 0 9 9\" fill=\"none\">\n <path d=\"M4.50941 0C4.56489 0.0227384 4.58859 0.0782652 4.61131 0.129846C4.62269 0.1599 4.63314 0.190117 4.64329 0.220575C4.64726 0.232247 4.65123 0.243918 4.65532 0.255943C4.70806 0.413005 4.75504 0.571748 4.80229 0.73038C4.81297 0.76619 4.82369 0.801987 4.83442 0.837783C4.88905 1.02004 4.94327 1.2024 4.99719 1.38484C5.00476 1.41047 5.01234 1.43609 5.01992 1.46171C5.04128 1.53395 5.06262 1.60619 5.08383 1.67847C5.12867 1.8312 5.17473 1.98347 5.22378 2.13501C5.22807 2.14827 5.23236 2.16152 5.23677 2.17518C5.3642 2.565 5.54482 2.91437 5.8409 3.21196C5.84823 3.2197 5.85556 3.22744 5.86312 3.23541C5.9895 3.36437 6.15169 3.46771 6.3138 3.55111C6.32206 3.55542 6.33031 3.55974 6.33882 3.56419C6.81587 3.80925 7.38951 3.91704 7.90619 4.0605C8.1326 4.1234 8.3583 4.18829 8.58317 4.25603C8.59897 4.26079 8.61478 4.26554 8.63058 4.27028C8.67784 4.28445 8.725 4.29887 8.77211 4.31347C8.7831 4.31679 8.79408 4.32011 8.80539 4.32353C8.87029 4.34406 8.93239 4.36829 8.98566 4.41027C9.00191 4.44418 9.00191 4.44418 8.99748 4.4781C8.94564 4.52736 8.8942 4.55046 8.82578 4.573C8.816 4.57632 8.80622 4.57965 8.79614 4.58308C8.68061 4.62183 8.56351 4.65575 8.44626 4.68935C8.4222 4.6963 8.39814 4.70326 8.37408 4.71021C8.22571 4.75301 8.07708 4.7949 7.92829 4.83632C7.73232 4.89088 7.53663 4.94634 7.34113 5.00243C7.3091 5.01162 7.27706 5.02078 7.24501 5.02991C7.07671 5.07786 6.90923 5.12753 6.74314 5.18208C6.72937 5.18659 6.71559 5.1911 6.70139 5.19574C6.14511 5.38082 5.7211 5.72609 5.45571 6.23099C5.31263 6.51475 5.22823 6.82161 5.14214 7.12447C5.11884 7.20619 5.09409 7.28745 5.06905 7.36869C5.0494 7.43261 5.0302 7.49663 5.01149 7.56081C5.00926 7.56844 5.00703 7.57608 5.00473 7.58395C4.99394 7.62094 4.98319 7.65793 4.97252 7.69495C4.94519 7.78879 4.91578 7.88187 4.88555 7.97489C4.83191 8.14021 4.7831 8.30674 4.73459 8.4735C4.66144 8.72457 4.66144 8.72457 4.61997 8.84527C4.61721 8.85337 4.61446 8.86147 4.61163 8.86982C4.59649 8.91278 4.58092 8.95233 4.55226 8.9887C4.50867 8.99788 4.50867 8.99788 4.46951 9C4.42473 8.93759 4.39508 8.87711 4.37133 8.80508C4.36787 8.79487 4.36441 8.78466 4.36085 8.77415C4.31684 8.64248 4.27751 8.50946 4.23817 8.37646C4.22916 8.34604 4.22011 8.31564 4.21105 8.28524C4.1436 8.05863 4.07725 7.83174 4.01101 7.60481C3.73507 6.48224 3.73507 6.48224 3.039 5.57466C3.02784 5.56596 3.01669 5.55726 3.00519 5.5483C2.54913 5.19902 1.94834 5.06969 1.39815 4.91813C1.26207 4.88062 1.12605 4.84293 0.990032 4.80523C0.978138 4.80193 0.978138 4.80193 0.966003 4.79857C0.769811 4.74417 0.573674 4.68963 0.378224 4.63283C0.369956 4.63045 0.361688 4.62806 0.353169 4.62561C0.0528989 4.53883 0.0528989 4.53883 0.000646537 4.4781C-0.000831261 4.45054 -0.000831261 4.45054 0.0124689 4.42157C0.0670835 4.3704 0.120077 4.34848 0.19216 4.32619C0.202597 4.32284 0.213034 4.31948 0.223787 4.31603C0.255753 4.30582 0.287788 4.29584 0.319851 4.28592C0.329001 4.28305 0.338151 4.28017 0.347578 4.27722C0.412285 4.25693 0.477225 4.2374 0.542259 4.21809C0.55824 4.21332 0.55824 4.21332 0.574544 4.20846C0.852269 4.12587 1.13181 4.049 1.41126 3.97196C1.6195 3.91455 1.82738 3.85618 2.0346 3.79548C2.04413 3.79271 2.05365 3.78993 2.06346 3.78707C2.5435 3.64696 3.01278 3.44816 3.32274 3.0537C3.32738 3.04785 3.33202 3.042 3.3368 3.03597C3.68197 2.59815 3.81658 2.06572 3.96695 1.54621C4.01643 1.37534 4.06649 1.20464 4.11673 1.03399C4.13064 0.986733 4.14453 0.939471 4.15836 0.892194C4.21394 0.702289 4.27035 0.512642 4.33 0.323864C4.33558 0.306186 4.34114 0.288501 4.34666 0.270807C4.43017 0.00398761 4.43017 0.00398761 4.50941 0Z\" fill=\"#0DBD7D\"/>\n <path d=\"M7.23597 0.554859C7.29024 0.613599 7.30109 0.682631 7.31799 0.757638C7.37436 0.993269 7.43929 1.20993 7.66467 1.34681C7.80371 1.42035 7.96944 1.45381 8.1235 1.48541C8.18854 1.49902 8.24348 1.51709 8.29924 1.55321C8.31181 1.57229 8.31181 1.57229 8.31107 1.60549C8.29814 1.64588 8.28678 1.6589 8.25269 1.68533C8.21543 1.69726 8.21543 1.69726 8.17068 1.70653C8.15375 1.71025 8.13683 1.714 8.11992 1.71779C8.11086 1.7198 8.10181 1.72181 8.09247 1.72388C7.81696 1.78482 7.81696 1.78482 7.57882 1.92273C7.57108 1.92869 7.56333 1.93466 7.55536 1.9408C7.38516 2.08431 7.34916 2.32303 7.29793 2.52301C7.29499 2.53399 7.29206 2.54497 7.28903 2.55629C7.28649 2.56601 7.28395 2.57573 7.28133 2.58575C7.27028 2.61544 7.25881 2.63479 7.23597 2.65754C7.17234 2.66527 7.17234 2.66527 7.14139 2.65754C7.09216 2.62106 7.08114 2.5795 7.06828 2.52365C7.06613 2.51501 7.06398 2.50636 7.06176 2.49745C7.05489 2.46983 7.04824 2.44217 7.04164 2.41449C6.98979 2.19897 6.93126 1.98751 6.72451 1.86118C6.56293 1.77501 6.36646 1.73426 6.18587 1.70136C6.13637 1.69151 6.10802 1.67911 6.07738 1.64012C6.07073 1.60055 6.07073 1.60055 6.07738 1.56098C6.12447 1.51437 6.17402 1.50299 6.23772 1.48891C6.25778 1.48416 6.27784 1.47938 6.29789 1.47456C6.30825 1.47209 6.31861 1.46962 6.32929 1.46707C6.38212 1.45407 6.43443 1.43949 6.48673 1.42462C6.49623 1.42198 6.50573 1.41935 6.51552 1.41663C6.62182 1.38624 6.71356 1.34737 6.79854 1.27836C6.80647 1.27213 6.81439 1.26589 6.82255 1.25946C6.9548 1.14565 6.99974 0.974674 7.04053 0.815134C7.04364 0.803022 7.04675 0.79091 7.04995 0.778432C7.05614 0.754101 7.06222 0.729743 7.06817 0.705359C7.07243 0.688394 7.07243 0.688394 7.07678 0.671086C7.07927 0.660951 7.08175 0.650816 7.08431 0.640373C7.09521 0.608108 7.10952 0.582772 7.12957 0.554859C7.1681 0.536435 7.19515 0.544764 7.23597 0.554859Z\" fill=\"#075F3F\"/>\n <path d=\"M1.79545 6.2471C1.80951 6.24719 1.80951 6.24719 1.82386 6.24729C1.92477 6.25022 1.99304 6.28115 2.06736 6.34601C2.15384 6.43533 2.19377 6.53611 2.1915 6.6565C2.18178 6.75412 2.12158 6.83935 2.04773 6.90533C1.96081 6.97242 1.87313 6.99459 1.76206 6.99149C1.66841 6.98107 1.5803 6.93852 1.51393 6.87451C1.43138 6.76681 1.40725 6.66803 1.41935 6.53537C1.44433 6.43092 1.51637 6.34613 1.6085 6.28666C1.67251 6.25564 1.72399 6.24652 1.79545 6.2471Z\" fill=\"#0DBD7D\"/>\n </svg>\n Self-healed\n </span>\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-rounded-[4px] cqa-py-0.5 cqa-px-1 cqa-bg-[#6366F11A] cqa-ml-1 cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity\" \n *ngIf=\"step?.executedResult?.video_start_time\" \n [matTooltip]=\"'Jump to video time'\" \n matTooltipPosition=\"below\"\n (click)=\"onJumpToTimestamp($event)\">\n <mat-icon class=\"cqa-text-[#636363] !cqa-text-[10px] !cqa-w-[10px] !cqa-h-[10px]\">\n play_arrow\n </mat-icon>\n <span class=\"cqa-text-[8px] cqa-leading-[12px] cqa-font-normal cqa-text-[#636363]\">\n {{ formatDurationClock(step?.executedResult?.video_start_time || 0) }}\n </span>\n </div>\n <div *ngIf=\"isDebug\" class=\"cqa-flex cqa-items-center cqa-gap-0.5 cqa-text-[#9CA3AF]\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Edit\" (click)=\"onEditStep($event)\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">edit</mat-icon>\n </button>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Add\" [matMenuTriggerFor]=\"addStepMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">add</mat-icon>\n </button>\n <mat-menu #addStepMenu=\"matMenu\" class=\"cqa-add-step-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of addStepMenuOptions\" (click)=\"onAddStepOptionSelect(opt, $event)\">\n {{ opt.label }}\n </button>\n </mat-menu>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"More options\" [matMenuTriggerFor]=\"stepMoreMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">more_vert</mat-icon>\n </button>\n <mat-menu #stepMoreMenu=\"matMenu\" class=\"cqa-step-more-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of stepMoreMenuOptions\" (click)=\"onStepMoreOptionSelect(opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n </div>\n <span class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF]\">\n {{ formatDuration(duration) }}\n </span>\n <svg *ngIf=\"hasSubSteps || (config.nestedSteps && config.nestedSteps.length > 0)\" [class.cqa-rotate-180]=\"isExpanded\" class=\"cqa-transition-transform\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M3.5 5L7 8.5L10.5 5\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n </div>\n\n <!-- Expanded Content -->\n <div *ngIf=\"isExpanded && (hasSubSteps || (config.nestedSteps && config.nestedSteps.length > 0))\">\n <!-- Sub-steps -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-1 cqa-pt-1 cqa-pl-9\">\n <!-- Single loop: render all entries in chronological order -->\n <ng-container *ngFor=\"let subStep of (isLive ? processedSubSteps : processedSubStepsForRunResult)\">\n <!-- AI_AUTO_HEAL_SUCCESS/FAILED: render with ai-agent-step style (both live and run result screens) -->\n <cqa-ai-logs-with-reasoning\n *ngIf=\"$any(subStep).isAiAutoHealResult\"\n [status]=\"subStep.status\"\n [text]=\"$any(subStep).text || subStep?.value\"\n [description]=\"$any(subStep).description || subStep?.text || subStep?.value\"\n [reasoning]=\"$any(subStep).reasoning || subStep?.reasoning\"\n [duration]=\"subStep.duration\">\n </cqa-ai-logs-with-reasoning>\n\n <!-- Regular sub-steps -->\n <div\n *ngIf=\"!$any(subStep).isAiAutoHealResult\"\n class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-py-[5.5px] cqa-px-3\">\n \n <!-- Sub-step Status Icon -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'success' || subStep?.status?.toLowerCase() === 'passed'\" >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Failure -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'failure' || subStep?.status?.toLowerCase() === 'failed'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7.5 4.5L4.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 4.5L7.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Pending -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'pending'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Running - Show spinner (also used for active WAIT_FOR_LOCATOR countdown in live mode) -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'running'\">\n <svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n </div>\n\n <!-- Sub-step Description -->\n <span class=\"cqa-flex-1 cqa-text-[13px] cqa-leading-[15px] cqa-text-[#364153]\" style=\"white-space: pre-line; word-break: break-word;\">\n {{ $any(subStep).description || $any(subStep).text }}\n <!-- Countdown for active WAIT_FOR_LOCATOR in live mode -->\n <span *ngIf=\"isLive && $any(subStep).remainingSeconds != null\" class=\"cqa-text-[#F97316] cqa-font-medium cqa-ml-1\">({{ $any(subStep).remainingSeconds }}s remaining)</span>\n </span>\n\n <!-- Sub-step Duration -->\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-metadata-key\">\n {{ formatDuration(subStep.duration) }}\n </span>\n </div>\n </ng-container>\n </div>\n\n <!-- Nested Steps -->\n <div *ngIf=\"hasChild || (config.nestedSteps && config.nestedSteps.length > 0)\" class=\"cqa-ml-9 cqa-pb-1\" style=\"border-bottom: '1px solid #F3F4F6'\">\n <div class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#737373] cqa-py-[2px] cqa-px-3\">Nested steps</div>\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2 cqa-pl-[18px]\" style=\"border-left: 2px solid #C5C7FA;\">\n <!-- Loading indicator for nested steps -->\n <div *ngIf=\"hasChild && (!config.nestedSteps || config.nestedSteps.length === 0) && isStepLoading()\" \n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-py-2 cqa-px-3\">\n <svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M7 1A6 6 0 0 1 13 7\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n <span class=\"cqa-text-[11px] cqa-leading-[13px] cqa-text-[#737373]\">Loading nested steps...</span>\n </div>\n\n\n <ng-container *ngFor=\"let step of config.nestedSteps; index as i\">\n <!-- Wrapper to show skeleton while step-renderer is loading -->\n <div\n class=\"cqa-step-renderer-wrapper\"\n [attr.id]=\"'exc-' + step.id\"\n [class.loaded]=\"!isNestedStepLoading(step)\">\n <!-- Loading skeleton overlay -->\n <!-- <div *ngIf=\"isNestedStepLoading(step)\" class=\"cqa-step-skeleton-overlay\">\n <div class=\"cqa-step-skeleton cqa-mx-3 cqa-my-1\"></div>\n </div> -->\n <!-- Use step-renderer for all nested steps to avoid circular dependencies -->\n <!-- The step-renderer will dynamically load the appropriate component and pass handlers -->\n <cqa-step-renderer \n [step]=\"step\"\n [stepNumber]=\"stepNumber + '.' + (i + 1)\"\n [onExpandHandler]=\"onExpandHandler\"\n [onConditionBranchClickHandler]=\"onConditionBranchClickHandler\"\n [getConditionBranchesHandler]=\"getConditionBranchesHandler\"\n [isStepLoadingHandler]=\"isStepLoadingHandler\"\n [isStepExpandedHandler]=\"isStepExpandedHandler\"\n [jumpToTimestampHandler]=\"jumpToTimestampHandler\"\n [convertMsToSecondsHandler]=\"convertMsToSecondsHandler\"\n [formatFailureDetailsHandler]=\"formatFailureDetailsHandler\"\n [getSelfHealAnalysisHandler]=\"getSelfHealAnalysisHandler\"\n [getLoopIterationsHandler]=\"getLoopIterationsHandler\"\n [getApiAssertionsHandler]=\"getApiAssertionsHandler\"\n [formatActionsHandler]=\"formatActionsHandler\"\n [onViewAllIterationsHandler]=\"onViewAllIterationsHandler\"\n [onMakeCurrentBaselineHandler]=\"onMakeCurrentBaselineHandler\"\n [onUploadBaselineHandler]=\"onUploadBaselineHandler\"\n [onAnalyzeHandler]=\"onAnalyzeHandler\"\n [onViewFullLogsHandler]=\"onViewFullLogsHandler\"\n [onSelfHealActionHandler]=\"onSelfHealActionHandler\"\n [getSelfHealLoadingStatesHandler]=\"getSelfHealLoadingStatesHandler\"\n [onStepClickHandler]=\"onStepClickHandler\"\n [onJsonPathCopiedHandler]=\"onJsonPathCopiedHandler\"\n [onDownloadHandler]=\"onDownloadHandler\"\n [onFilePathCopiedHandler]=\"onFilePathCopiedHandler\"\n [onTextCopiedHandler]=\"onTextCopiedHandler\"\n [downloadingStepId]=\"downloadingStepId\"\n [isUploadingBaseline]=\"isUploadingBaseline\"\n [isMakingCurrentBaseline]=\"isMakingCurrentBaseline\"\n [isLive]=\"isLive\"\n [isDebug]=\"isDebug\"\n [debugPointSet]=\"getDebugPointSetHandler ? getDebugPointSetHandler(step) : debugPointSet\"\n [getDebugPointSetHandler]=\"getDebugPointSetHandler\"\n [onDebugPointChangeHandler]=\"onDebugPointChangeHandler\"\n [onEditStepHandler]=\"onEditStepHandler\"\n [addStepMenuOptions]=\"addStepMenuOptions\"\n [onAddStepOptionSelectHandler]=\"onAddStepOptionSelectHandler\"\n [stepMoreMenuOptions]=\"stepMoreMenuOptions\"\n [onStepMoreOptionSelectHandler]=\"onStepMoreOptionSelectHandler\"\n (componentReady)=\"markStepLoaded(step)\">\n </cqa-step-renderer>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Self Heal Analysis -->\n <cqa-self-heal-analysis \n *ngIf=\"selfHealAnalysis\" \n [id]=\"step?.testStepId\"\n [originalLocator]=\"selfHealAnalysis.originalLocator\"\n [healedLocator]=\"selfHealAnalysis.healedLocator\"\n [confidence]=\"selfHealAnalysis.confidence\"\n [healMethod]=\"selfHealAnalysis.healMethod\"\n [isLoadingAccept]=\"getSelfHealLoadingStatesHandler ? getSelfHealLoadingStatesHandler().isLoadingAccept?.[step?.testStepId] : false\"\n [isLoadingModifyAccept]=\"getSelfHealLoadingStatesHandler ? getSelfHealLoadingStatesHandler().isLoadingModifyAccept?.[step?.testStepId] : false\"\n (action)=\"onSelfHealAction($event)\">\n </cqa-self-heal-analysis>\n\n <!-- Timing Breakdown -->\n <div *ngIf=\"timingBreakdown\" class=\"cqa-flex cqa-items-center cqa-justify-end cqa-gap-5 cqa-mt-1 cqa-pt-4 cqa-px-4 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF]\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <span>Timing breakdown</span>\n </div>\n <span class=\"cqa-text-dialog-muted cqa-flex cqa-items-center cqa-gap-3\">\n <div>\n App <span class=\"cqa-text-gray-700\">{{ formatDuration(timingBreakdown.app) }}</span>\n </div>\n <div><svg width=\"1\" height=\"11\" viewBox=\"0 0 1 11\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M-3.8147e-06 10.32V-7.15256e-07H0.959996V10.32H-3.8147e-06Z\" fill=\"#E5E7EB\"/></svg></div>\n <div>\n Tool <span class=\"cqa-text-gray-700\">{{ formatDuration(timingBreakdown.tool) }}</span>\n </div>\n </span>\n </div>\n </div>\n\n <!-- View More Failed Step Button - shown when expanded and failure details exist -->\n <div *ngIf=\"showViewMoreButton\" class=\"cqa-mt-2 cqa-px-4\">\n <cqa-view-more-failed-step-button\n [timingBreakdown]=\"timingBreakdown\"\n [subSteps]=\"subSteps\"\n [failureDetails]=\"failureDetails\"\n [isExpanded]=\"showFailedStepDetails\"\n (viewMoreClick)=\"onViewMoreFailedStepClick($event)\">\n </cqa-view-more-failed-step-button>\n </div>\n\n <!-- Updated Failed Step Component - shown when button is clicked -->\n <div *ngIf=\"showViewMoreButton && showFailedStepDetails && failureDetails\" class=\"cqa-mt-2 cqa-px-4\">\n <cqa-updated-failed-step\n [testStepResultId]=\"testStepResultId\"\n [timingBreakdown]=\"timingBreakdown\"\n [expanded]=\"true\"\n [subSteps]=\"subSteps\"\n [failureDetails]=\"failureDetails\"\n [reasoning]=\"reasoning\"\n [confidence]=\"confidence\"\n [isUploadingBaseline]=\"isUploadingBaseline\"\n [isMakingCurrentBaseline]=\"isMakingCurrentBaseline\"\n [isLive]=\"isLive\"\n (makeCurrentBaseline)=\"onMakeCurrentBaseline($event)\"\n (uploadBaseline)=\"onUploadBaseline($event)\"\n (analyze)=\"onAnalyze()\"\n (viewFullLogs)=\"onViewFullLogs()\">\n </cqa-updated-failed-step>\n </div>\n</div>\n", components: [{ type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i2$1.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { type: i2$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { type: AiLogsWithReasoningComponent, selector: "cqa-ai-logs-with-reasoning", inputs: ["status", "text", "description", "reasoning", "duration"] }, { type: StepRendererComponent, selector: "cqa-step-renderer", inputs: ["step", "onExpandHandler", "getConditionBranchesHandler", "isStepLoadingHandler", "isStepExpandedHandler", "convertMsToSecondsHandler", "formatFailureDetailsHandler", "getSelfHealAnalysisHandler", "onMakeCurrentBaselineHandler", "onUploadBaselineHandler", "onAnalyzeHandler", "onViewFullLogsHandler", "onSelfHealActionHandler", "getSelfHealLoadingStatesHandler", "isUploadingBaseline", "isMakingCurrentBaseline", "selectedIterationId", "getLoopIterationsHandler", "getApiAssertionsHandler", "formatActionsHandler", "onViewAllIterationsHandler", "onConditionBranchClickHandler", "onStepClickHandler", "onJsonPathCopiedHandler", "onDownloadHandler", "onFilePathCopiedHandler", "onTextCopiedHandler", "jumpToTimestampHandler", "downloadingStepId", "isLive", "isDebug", "debugPointSet", "getDebugPointSetHandler", "onDebugPointChangeHandler", "onEditStepHandler", "addStepMenuOptions", "onAddStepOptionSelectHandler", "stepMoreMenuOptions", "onStepMoreOptionSelectHandler", "getAddStepMenuOptionsForNested", "getStepMoreMenuOptionsForNested", "stepNumber"], outputs: ["addStepOptionSelect", "stepMoreOptionSelect", "componentReady"] }, { type: SelfHealAnalysisComponent, selector: "cqa-self-heal-analysis", inputs: ["id", "originalLocator", "healedLocator", "confidence", "healMethod", "isLoadingAccept", "isLoadingModifyAccept"], outputs: ["action"] }, { type: ViewMoreFailedStepButtonComponent, selector: "cqa-view-more-failed-step-button", inputs: ["timingBreakdown", "subSteps", "failureDetails", "isExpanded"], outputs: ["viewMoreClick"] }, { type: UpdatedFailedStepComponent, selector: "cqa-updated-failed-step", inputs: ["timingBreakdown", "testStepResultId", "expanded", "subSteps", "failureDetails", "reasoning", "confidence", "isUploadingBaseline", "isMakingCurrentBaseline", "isLive"], outputs: ["makeCurrentBaseline", "uploadBaseline", "analyze", "viewFullLogs"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { type: i2$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
|
|
8946
9186
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: BasicStepComponent, decorators: [{
|
|
8947
9187
|
type: Component,
|
|
8948
|
-
args: [{ selector: 'cqa-basic-step', host: { class: 'cqa-ui-root' }, template: "<div class=\"cqa-font-inter\" (click)=\"$event.stopPropagation()\">\n <!-- Header -->\n <div\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-p-2 cqa-cursor-pointer\"\n (click)=\"toggleHeader($event)\"\n style=\"border-bottom: '1px solid #F3F4F6'\"\n >\n <div *ngIf=\"showDebugIcon\" class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer cqa-rounded-full hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" (click)=\"onDebugPointClick($event)\" [attr.aria-label]=\"debugPointSet ? 'Remove debug point' : 'Set debug point'\">\n <svg *ngIf=\"debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" fill=\"#C63535\"/>\n </svg>\n <svg *ngIf=\"!debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" stroke=\"#C63535\" stroke-width=\"1.5\" fill=\"none\"/>\n </svg>\n </button>\n </div>\n <!-- Status Icon -->\n <!-- {{ getStatusIcon(config.status) }} -->\n<!-- Success -->\n <div *ngIf=\"config.status.toLowerCase() === 'success'\" >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Failure -->\n <div *ngIf=\"config.status.toLowerCase() === 'failure' || config.status.toLowerCase() === 'failed'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7.5 4.5L4.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 4.5L7.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Pending -->\n <div *ngIf=\"config.status.toLowerCase() === 'pending'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Running - Show spinner -->\n <div *ngIf=\"config.status.toLowerCase() === 'running'\">\n <svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n </div>\n <!-- Skipped -->\n <div class=\"cqa-flex cqa-items-center\" *ngIf=\"config.status.toLowerCase() === 'skipped'\">\n <span class=\"material-symbols-outlined cqa-text-[#9CA3AF] cqa-text-[12px]\">\n skip_next\n </span>\n </div>\n\n <!-- Step Number and Title -->\n <div class=\"cqa-font-semibold cqa-flex-1 cqa-text-[#334155] cqa-text-[14px] cqa-leading-[18px] cqa-font-inter cqa-flex cqa-items-center cqa-gap-1\" style=\"word-break: break-word;\">\n <span>{{ stepNumber }}. <span [innerHTML]=\"title\"></span></span>\n <span *ngIf=\"config.stepDeleted\" class=\"cqa-px-1.5 cqa-py-[2px] cqa-rounded-[4px] cqa-text-[10px] cqa-leading-[12px] cqa-font-medium cqa-text-[#B42318] cqa-bg-[#FEF3F2] cqa-border cqa-border-[#FEE4E2]\">\n Deleted\n </span>\n </div>\n\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-font-inter\">\n <span *ngIf=\"selfHealAnalysis\" class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-[#097E53] cqa-bg-[#CFF2E5] cqa-text-[10px] cqa-leading-[15px] cqa-min-w-max cqa-flex cqa-items-center cqa-gap-[6px]\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"9\" height=\"9\" viewBox=\"0 0 9 9\" fill=\"none\">\n <path d=\"M4.50941 0C4.56489 0.0227384 4.58859 0.0782652 4.61131 0.129846C4.62269 0.1599 4.63314 0.190117 4.64329 0.220575C4.64726 0.232247 4.65123 0.243918 4.65532 0.255943C4.70806 0.413005 4.75504 0.571748 4.80229 0.73038C4.81297 0.76619 4.82369 0.801987 4.83442 0.837783C4.88905 1.02004 4.94327 1.2024 4.99719 1.38484C5.00476 1.41047 5.01234 1.43609 5.01992 1.46171C5.04128 1.53395 5.06262 1.60619 5.08383 1.67847C5.12867 1.8312 5.17473 1.98347 5.22378 2.13501C5.22807 2.14827 5.23236 2.16152 5.23677 2.17518C5.3642 2.565 5.54482 2.91437 5.8409 3.21196C5.84823 3.2197 5.85556 3.22744 5.86312 3.23541C5.9895 3.36437 6.15169 3.46771 6.3138 3.55111C6.32206 3.55542 6.33031 3.55974 6.33882 3.56419C6.81587 3.80925 7.38951 3.91704 7.90619 4.0605C8.1326 4.1234 8.3583 4.18829 8.58317 4.25603C8.59897 4.26079 8.61478 4.26554 8.63058 4.27028C8.67784 4.28445 8.725 4.29887 8.77211 4.31347C8.7831 4.31679 8.79408 4.32011 8.80539 4.32353C8.87029 4.34406 8.93239 4.36829 8.98566 4.41027C9.00191 4.44418 9.00191 4.44418 8.99748 4.4781C8.94564 4.52736 8.8942 4.55046 8.82578 4.573C8.816 4.57632 8.80622 4.57965 8.79614 4.58308C8.68061 4.62183 8.56351 4.65575 8.44626 4.68935C8.4222 4.6963 8.39814 4.70326 8.37408 4.71021C8.22571 4.75301 8.07708 4.7949 7.92829 4.83632C7.73232 4.89088 7.53663 4.94634 7.34113 5.00243C7.3091 5.01162 7.27706 5.02078 7.24501 5.02991C7.07671 5.07786 6.90923 5.12753 6.74314 5.18208C6.72937 5.18659 6.71559 5.1911 6.70139 5.19574C6.14511 5.38082 5.7211 5.72609 5.45571 6.23099C5.31263 6.51475 5.22823 6.82161 5.14214 7.12447C5.11884 7.20619 5.09409 7.28745 5.06905 7.36869C5.0494 7.43261 5.0302 7.49663 5.01149 7.56081C5.00926 7.56844 5.00703 7.57608 5.00473 7.58395C4.99394 7.62094 4.98319 7.65793 4.97252 7.69495C4.94519 7.78879 4.91578 7.88187 4.88555 7.97489C4.83191 8.14021 4.7831 8.30674 4.73459 8.4735C4.66144 8.72457 4.66144 8.72457 4.61997 8.84527C4.61721 8.85337 4.61446 8.86147 4.61163 8.86982C4.59649 8.91278 4.58092 8.95233 4.55226 8.9887C4.50867 8.99788 4.50867 8.99788 4.46951 9C4.42473 8.93759 4.39508 8.87711 4.37133 8.80508C4.36787 8.79487 4.36441 8.78466 4.36085 8.77415C4.31684 8.64248 4.27751 8.50946 4.23817 8.37646C4.22916 8.34604 4.22011 8.31564 4.21105 8.28524C4.1436 8.05863 4.07725 7.83174 4.01101 7.60481C3.73507 6.48224 3.73507 6.48224 3.039 5.57466C3.02784 5.56596 3.01669 5.55726 3.00519 5.5483C2.54913 5.19902 1.94834 5.06969 1.39815 4.91813C1.26207 4.88062 1.12605 4.84293 0.990032 4.80523C0.978138 4.80193 0.978138 4.80193 0.966003 4.79857C0.769811 4.74417 0.573674 4.68963 0.378224 4.63283C0.369956 4.63045 0.361688 4.62806 0.353169 4.62561C0.0528989 4.53883 0.0528989 4.53883 0.000646537 4.4781C-0.000831261 4.45054 -0.000831261 4.45054 0.0124689 4.42157C0.0670835 4.3704 0.120077 4.34848 0.19216 4.32619C0.202597 4.32284 0.213034 4.31948 0.223787 4.31603C0.255753 4.30582 0.287788 4.29584 0.319851 4.28592C0.329001 4.28305 0.338151 4.28017 0.347578 4.27722C0.412285 4.25693 0.477225 4.2374 0.542259 4.21809C0.55824 4.21332 0.55824 4.21332 0.574544 4.20846C0.852269 4.12587 1.13181 4.049 1.41126 3.97196C1.6195 3.91455 1.82738 3.85618 2.0346 3.79548C2.04413 3.79271 2.05365 3.78993 2.06346 3.78707C2.5435 3.64696 3.01278 3.44816 3.32274 3.0537C3.32738 3.04785 3.33202 3.042 3.3368 3.03597C3.68197 2.59815 3.81658 2.06572 3.96695 1.54621C4.01643 1.37534 4.06649 1.20464 4.11673 1.03399C4.13064 0.986733 4.14453 0.939471 4.15836 0.892194C4.21394 0.702289 4.27035 0.512642 4.33 0.323864C4.33558 0.306186 4.34114 0.288501 4.34666 0.270807C4.43017 0.00398761 4.43017 0.00398761 4.50941 0Z\" fill=\"#0DBD7D\"/>\n <path d=\"M7.23597 0.554859C7.29024 0.613599 7.30109 0.682631 7.31799 0.757638C7.37436 0.993269 7.43929 1.20993 7.66467 1.34681C7.80371 1.42035 7.96944 1.45381 8.1235 1.48541C8.18854 1.49902 8.24348 1.51709 8.29924 1.55321C8.31181 1.57229 8.31181 1.57229 8.31107 1.60549C8.29814 1.64588 8.28678 1.6589 8.25269 1.68533C8.21543 1.69726 8.21543 1.69726 8.17068 1.70653C8.15375 1.71025 8.13683 1.714 8.11992 1.71779C8.11086 1.7198 8.10181 1.72181 8.09247 1.72388C7.81696 1.78482 7.81696 1.78482 7.57882 1.92273C7.57108 1.92869 7.56333 1.93466 7.55536 1.9408C7.38516 2.08431 7.34916 2.32303 7.29793 2.52301C7.29499 2.53399 7.29206 2.54497 7.28903 2.55629C7.28649 2.56601 7.28395 2.57573 7.28133 2.58575C7.27028 2.61544 7.25881 2.63479 7.23597 2.65754C7.17234 2.66527 7.17234 2.66527 7.14139 2.65754C7.09216 2.62106 7.08114 2.5795 7.06828 2.52365C7.06613 2.51501 7.06398 2.50636 7.06176 2.49745C7.05489 2.46983 7.04824 2.44217 7.04164 2.41449C6.98979 2.19897 6.93126 1.98751 6.72451 1.86118C6.56293 1.77501 6.36646 1.73426 6.18587 1.70136C6.13637 1.69151 6.10802 1.67911 6.07738 1.64012C6.07073 1.60055 6.07073 1.60055 6.07738 1.56098C6.12447 1.51437 6.17402 1.50299 6.23772 1.48891C6.25778 1.48416 6.27784 1.47938 6.29789 1.47456C6.30825 1.47209 6.31861 1.46962 6.32929 1.46707C6.38212 1.45407 6.43443 1.43949 6.48673 1.42462C6.49623 1.42198 6.50573 1.41935 6.51552 1.41663C6.62182 1.38624 6.71356 1.34737 6.79854 1.27836C6.80647 1.27213 6.81439 1.26589 6.82255 1.25946C6.9548 1.14565 6.99974 0.974674 7.04053 0.815134C7.04364 0.803022 7.04675 0.79091 7.04995 0.778432C7.05614 0.754101 7.06222 0.729743 7.06817 0.705359C7.07243 0.688394 7.07243 0.688394 7.07678 0.671086C7.07927 0.660951 7.08175 0.650816 7.08431 0.640373C7.09521 0.608108 7.10952 0.582772 7.12957 0.554859C7.1681 0.536435 7.19515 0.544764 7.23597 0.554859Z\" fill=\"#075F3F\"/>\n <path d=\"M1.79545 6.2471C1.80951 6.24719 1.80951 6.24719 1.82386 6.24729C1.92477 6.25022 1.99304 6.28115 2.06736 6.34601C2.15384 6.43533 2.19377 6.53611 2.1915 6.6565C2.18178 6.75412 2.12158 6.83935 2.04773 6.90533C1.96081 6.97242 1.87313 6.99459 1.76206 6.99149C1.66841 6.98107 1.5803 6.93852 1.51393 6.87451C1.43138 6.76681 1.40725 6.66803 1.41935 6.53537C1.44433 6.43092 1.51637 6.34613 1.6085 6.28666C1.67251 6.25564 1.72399 6.24652 1.79545 6.2471Z\" fill=\"#0DBD7D\"/>\n </svg>\n Self-healed\n </span>\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-rounded-[4px] cqa-py-0.5 cqa-px-1 cqa-bg-[#6366F11A] cqa-ml-1 cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity\" \n *ngIf=\"step?.executedResult?.video_start_time\" \n [matTooltip]=\"'Jump to video time'\" \n matTooltipPosition=\"below\"\n (click)=\"onJumpToTimestamp($event)\">\n <mat-icon class=\"cqa-text-[#636363] !cqa-text-[10px] !cqa-w-[10px] !cqa-h-[10px]\">\n play_arrow\n </mat-icon>\n <span class=\"cqa-text-[8px] cqa-leading-[12px] cqa-font-normal cqa-text-[#636363]\">\n {{ formatDurationClock(step?.executedResult?.video_start_time || 0) }}\n </span>\n </div>\n <div *ngIf=\"isDebug\" class=\"cqa-flex cqa-items-center cqa-gap-0.5 cqa-text-[#9CA3AF]\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Edit\" (click)=\"onEditStep($event)\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">edit</mat-icon>\n </button>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Add\" [matMenuTriggerFor]=\"addStepMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">add</mat-icon>\n </button>\n <mat-menu #addStepMenu=\"matMenu\" class=\"cqa-add-step-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of addStepMenuOptions\" (click)=\"onAddStepOptionSelect(opt, $event)\">\n {{ opt.label }}\n </button>\n </mat-menu>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"More options\" [matMenuTriggerFor]=\"stepMoreMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">more_vert</mat-icon>\n </button>\n <mat-menu #stepMoreMenu=\"matMenu\" class=\"cqa-step-more-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of stepMoreMenuOptions\" (click)=\"onStepMoreOptionSelect(opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n </div>\n <span class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF]\">\n {{ formatDuration(duration) }}\n </span>\n <svg *ngIf=\"hasSubSteps || (config.nestedSteps && config.nestedSteps.length > 0)\" [class.cqa-rotate-180]=\"isExpanded\" class=\"cqa-transition-transform\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M3.5 5L7 8.5L10.5 5\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n </div>\n\n <!-- Expanded Content -->\n <div *ngIf=\"isExpanded && (hasSubSteps || (config.nestedSteps && config.nestedSteps.length > 0))\">\n <!-- Sub-steps -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-1 cqa-pt-1 cqa-pl-9\">\n <div\n *ngFor=\"let subStep of subSteps\"\n class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-py-[5.5px] cqa-px-3\">\n \n <!-- Sub-step Status Icon -->\n <!-- <mat-icon\n class=\"!cqa-w-4 !cqa-h-4 !cqa-text-[16px]\"\n [ngClass]=\"getStatusColorClass(subStep.status)\">\n {{ getStatusIcon(subStep.status) }}\n </mat-icon> -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'success' || subStep?.status?.toLowerCase() === 'passed'\" >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Failure -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'failure' || subStep?.status?.toLowerCase() === 'failed'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7.5 4.5L4.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 4.5L7.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Pending -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'pending'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Running - Show spinner -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'running'\">\n <svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n </div>\n\n <!-- Sub-step Description -->\n <span class=\"cqa-flex-1 cqa-text-[13px] cqa-leading-[15px] cqa-text-[#364153]\" style=\"white-space: pre-line; word-break: break-word;\">\n {{ subStep.description }}\n </span>\n\n <!-- Sub-step Duration -->\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-metadata-key\">\n {{ formatDuration(subStep.duration) }}\n </span>\n </div>\n </div>\n\n <!-- Nested Steps -->\n <div *ngIf=\"hasChild || (config.nestedSteps && config.nestedSteps.length > 0)\" class=\"cqa-ml-9 cqa-pb-1\" style=\"border-bottom: '1px solid #F3F4F6'\">\n <div class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#737373] cqa-py-[2px] cqa-px-3\">Nested steps</div>\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2 cqa-pl-[18px]\" style=\"border-left: 2px solid #C5C7FA;\">\n <!-- Loading indicator for nested steps -->\n <div *ngIf=\"hasChild && (!config.nestedSteps || config.nestedSteps.length === 0) && isStepLoading()\" \n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-py-2 cqa-px-3\">\n <svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M7 1A6 6 0 0 1 13 7\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n <span class=\"cqa-text-[11px] cqa-leading-[13px] cqa-text-[#737373]\">Loading nested steps...</span>\n </div>\n\n\n <ng-container *ngFor=\"let step of config.nestedSteps; index as i\">\n <!-- Wrapper to show skeleton while step-renderer is loading -->\n <div\n class=\"cqa-step-renderer-wrapper\"\n [attr.id]=\"'exc-' + step.id\"\n [class.loaded]=\"!isNestedStepLoading(step)\">\n <!-- Loading skeleton overlay -->\n <!-- <div *ngIf=\"isNestedStepLoading(step)\" class=\"cqa-step-skeleton-overlay\">\n <div class=\"cqa-step-skeleton cqa-mx-3 cqa-my-1\"></div>\n </div> -->\n <!-- Use step-renderer for all nested steps to avoid circular dependencies -->\n <!-- The step-renderer will dynamically load the appropriate component and pass handlers -->\n <cqa-step-renderer \n [step]=\"step\"\n [stepNumber]=\"stepNumber + '.' + (i + 1)\"\n [onExpandHandler]=\"onExpandHandler\"\n [onConditionBranchClickHandler]=\"onConditionBranchClickHandler\"\n [getConditionBranchesHandler]=\"getConditionBranchesHandler\"\n [isStepLoadingHandler]=\"isStepLoadingHandler\"\n [isStepExpandedHandler]=\"isStepExpandedHandler\"\n [jumpToTimestampHandler]=\"jumpToTimestampHandler\"\n [convertMsToSecondsHandler]=\"convertMsToSecondsHandler\"\n [formatFailureDetailsHandler]=\"formatFailureDetailsHandler\"\n [getSelfHealAnalysisHandler]=\"getSelfHealAnalysisHandler\"\n [getLoopIterationsHandler]=\"getLoopIterationsHandler\"\n [getApiAssertionsHandler]=\"getApiAssertionsHandler\"\n [formatActionsHandler]=\"formatActionsHandler\"\n [onViewAllIterationsHandler]=\"onViewAllIterationsHandler\"\n [onMakeCurrentBaselineHandler]=\"onMakeCurrentBaselineHandler\"\n [onUploadBaselineHandler]=\"onUploadBaselineHandler\"\n [onAnalyzeHandler]=\"onAnalyzeHandler\"\n [onViewFullLogsHandler]=\"onViewFullLogsHandler\"\n [onSelfHealActionHandler]=\"onSelfHealActionHandler\"\n [getSelfHealLoadingStatesHandler]=\"getSelfHealLoadingStatesHandler\"\n [onStepClickHandler]=\"onStepClickHandler\"\n [onJsonPathCopiedHandler]=\"onJsonPathCopiedHandler\"\n [onDownloadHandler]=\"onDownloadHandler\"\n [onFilePathCopiedHandler]=\"onFilePathCopiedHandler\"\n [onTextCopiedHandler]=\"onTextCopiedHandler\"\n [downloadingStepId]=\"downloadingStepId\"\n [isUploadingBaseline]=\"isUploadingBaseline\"\n [isMakingCurrentBaseline]=\"isMakingCurrentBaseline\"\n [isLive]=\"isLive\"\n [isDebug]=\"isDebug\"\n [debugPointSet]=\"getDebugPointSetHandler ? getDebugPointSetHandler(step) : debugPointSet\"\n [getDebugPointSetHandler]=\"getDebugPointSetHandler\"\n [onDebugPointChangeHandler]=\"onDebugPointChangeHandler\"\n [onEditStepHandler]=\"onEditStepHandler\"\n [addStepMenuOptions]=\"addStepMenuOptions\"\n [onAddStepOptionSelectHandler]=\"onAddStepOptionSelectHandler\"\n [stepMoreMenuOptions]=\"stepMoreMenuOptions\"\n [onStepMoreOptionSelectHandler]=\"onStepMoreOptionSelectHandler\"\n (componentReady)=\"markStepLoaded(step)\">\n </cqa-step-renderer>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Self Heal Analysis -->\n <cqa-self-heal-analysis \n *ngIf=\"selfHealAnalysis\" \n [id]=\"step?.testStepId\"\n [originalLocator]=\"selfHealAnalysis.originalLocator\"\n [healedLocator]=\"selfHealAnalysis.healedLocator\"\n [confidence]=\"selfHealAnalysis.confidence\"\n [healMethod]=\"selfHealAnalysis.healMethod\"\n [isLoadingAccept]=\"getSelfHealLoadingStatesHandler ? getSelfHealLoadingStatesHandler().isLoadingAccept?.[step?.testStepId] : false\"\n [isLoadingModifyAccept]=\"getSelfHealLoadingStatesHandler ? getSelfHealLoadingStatesHandler().isLoadingModifyAccept?.[step?.testStepId] : false\"\n (action)=\"onSelfHealAction($event)\">\n </cqa-self-heal-analysis>\n\n <!-- Timing Breakdown -->\n <div *ngIf=\"timingBreakdown\" class=\"cqa-flex cqa-items-center cqa-justify-end cqa-gap-5 cqa-mt-1 cqa-pt-4 cqa-px-4 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF]\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <span>Timing breakdown</span>\n </div>\n <span class=\"cqa-text-dialog-muted cqa-flex cqa-items-center cqa-gap-3\">\n <div>\n App <span class=\"cqa-text-gray-700\">{{ formatDuration(timingBreakdown.app) }}</span>\n </div>\n <div><svg width=\"1\" height=\"11\" viewBox=\"0 0 1 11\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M-3.8147e-06 10.32V-7.15256e-07H0.959996V10.32H-3.8147e-06Z\" fill=\"#E5E7EB\"/></svg></div>\n <div>\n Tool <span class=\"cqa-text-gray-700\">{{ formatDuration(timingBreakdown.tool) }}</span>\n </div>\n </span>\n </div>\n </div>\n\n <!-- View More Failed Step Button - shown when expanded and failure details exist -->\n <div *ngIf=\"showViewMoreButton\" class=\"cqa-mt-2 cqa-px-4\">\n <cqa-view-more-failed-step-button\n [timingBreakdown]=\"timingBreakdown\"\n [subSteps]=\"subSteps\"\n [failureDetails]=\"failureDetails\"\n [isExpanded]=\"showFailedStepDetails\"\n (viewMoreClick)=\"onViewMoreFailedStepClick($event)\">\n </cqa-view-more-failed-step-button>\n </div>\n\n <!-- Updated Failed Step Component - shown when button is clicked -->\n <div *ngIf=\"showViewMoreButton && showFailedStepDetails && failureDetails\" class=\"cqa-mt-2 cqa-px-4\">\n <cqa-updated-failed-step\n [testStepResultId]=\"testStepResultId\"\n [timingBreakdown]=\"timingBreakdown\"\n [expanded]=\"true\"\n [subSteps]=\"subSteps\"\n [failureDetails]=\"failureDetails\"\n [reasoning]=\"reasoning\"\n [confidence]=\"confidence\"\n [isUploadingBaseline]=\"isUploadingBaseline\"\n [isMakingCurrentBaseline]=\"isMakingCurrentBaseline\"\n [isLive]=\"isLive\"\n (makeCurrentBaseline)=\"onMakeCurrentBaseline($event)\"\n (uploadBaseline)=\"onUploadBaseline($event)\"\n (analyze)=\"onAnalyze()\"\n (viewFullLogs)=\"onViewFullLogs()\">\n </cqa-updated-failed-step>\n </div>\n</div>\n" }]
|
|
9188
|
+
args: [{ selector: 'cqa-basic-step', host: { class: 'cqa-ui-root' }, template: "<div class=\"cqa-font-inter\" (click)=\"$event.stopPropagation()\">\n <!-- Header -->\n <div\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-p-2 cqa-cursor-pointer\"\n (click)=\"toggleHeader($event)\"\n style=\"border-bottom: '1px solid #F3F4F6'\"\n >\n <div *ngIf=\"showDebugIcon\" class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer cqa-rounded-full hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" (click)=\"onDebugPointClick($event)\" [attr.aria-label]=\"debugPointSet ? 'Remove debug point' : 'Set debug point'\">\n <svg *ngIf=\"debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" fill=\"#C63535\"/>\n </svg>\n <svg *ngIf=\"!debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" stroke=\"#C63535\" stroke-width=\"1.5\" fill=\"none\"/>\n </svg>\n </button>\n </div>\n <!-- Status Icon -->\n <!-- {{ getStatusIcon(config.status) }} -->\n<!-- Success -->\n <div *ngIf=\"config.status.toLowerCase() === 'success'\" >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Failure -->\n <div *ngIf=\"config.status.toLowerCase() === 'failure' || config.status.toLowerCase() === 'failed'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7.5 4.5L4.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 4.5L7.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Pending -->\n <div *ngIf=\"config.status.toLowerCase() === 'pending'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Running - Show spinner -->\n <div *ngIf=\"config.status.toLowerCase() === 'running'\">\n <svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n </div>\n <!-- Skipped -->\n <div class=\"cqa-flex cqa-items-center\" *ngIf=\"config.status.toLowerCase() === 'skipped'\">\n <span class=\"material-symbols-outlined cqa-text-[#9CA3AF] cqa-text-[12px]\">\n skip_next\n </span>\n </div>\n\n <!-- Step Number and Title -->\n <div class=\"cqa-font-semibold cqa-flex-1 cqa-text-[#334155] cqa-text-[14px] cqa-leading-[18px] cqa-font-inter cqa-flex cqa-items-center cqa-gap-1\" style=\"word-break: break-word;\">\n <span>{{ stepNumber }}. <span [innerHTML]=\"title\"></span></span>\n <span *ngIf=\"config.stepDeleted\" class=\"cqa-px-1.5 cqa-py-[2px] cqa-rounded-[4px] cqa-text-[10px] cqa-leading-[12px] cqa-font-medium cqa-text-[#B42318] cqa-bg-[#FEF3F2] cqa-border cqa-border-[#FEE4E2]\">\n Deleted\n </span>\n </div>\n\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-font-inter\">\n <span *ngIf=\"selfHealAnalysis\" class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-[#097E53] cqa-bg-[#CFF2E5] cqa-text-[10px] cqa-leading-[15px] cqa-min-w-max cqa-flex cqa-items-center cqa-gap-[6px]\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"9\" height=\"9\" viewBox=\"0 0 9 9\" fill=\"none\">\n <path d=\"M4.50941 0C4.56489 0.0227384 4.58859 0.0782652 4.61131 0.129846C4.62269 0.1599 4.63314 0.190117 4.64329 0.220575C4.64726 0.232247 4.65123 0.243918 4.65532 0.255943C4.70806 0.413005 4.75504 0.571748 4.80229 0.73038C4.81297 0.76619 4.82369 0.801987 4.83442 0.837783C4.88905 1.02004 4.94327 1.2024 4.99719 1.38484C5.00476 1.41047 5.01234 1.43609 5.01992 1.46171C5.04128 1.53395 5.06262 1.60619 5.08383 1.67847C5.12867 1.8312 5.17473 1.98347 5.22378 2.13501C5.22807 2.14827 5.23236 2.16152 5.23677 2.17518C5.3642 2.565 5.54482 2.91437 5.8409 3.21196C5.84823 3.2197 5.85556 3.22744 5.86312 3.23541C5.9895 3.36437 6.15169 3.46771 6.3138 3.55111C6.32206 3.55542 6.33031 3.55974 6.33882 3.56419C6.81587 3.80925 7.38951 3.91704 7.90619 4.0605C8.1326 4.1234 8.3583 4.18829 8.58317 4.25603C8.59897 4.26079 8.61478 4.26554 8.63058 4.27028C8.67784 4.28445 8.725 4.29887 8.77211 4.31347C8.7831 4.31679 8.79408 4.32011 8.80539 4.32353C8.87029 4.34406 8.93239 4.36829 8.98566 4.41027C9.00191 4.44418 9.00191 4.44418 8.99748 4.4781C8.94564 4.52736 8.8942 4.55046 8.82578 4.573C8.816 4.57632 8.80622 4.57965 8.79614 4.58308C8.68061 4.62183 8.56351 4.65575 8.44626 4.68935C8.4222 4.6963 8.39814 4.70326 8.37408 4.71021C8.22571 4.75301 8.07708 4.7949 7.92829 4.83632C7.73232 4.89088 7.53663 4.94634 7.34113 5.00243C7.3091 5.01162 7.27706 5.02078 7.24501 5.02991C7.07671 5.07786 6.90923 5.12753 6.74314 5.18208C6.72937 5.18659 6.71559 5.1911 6.70139 5.19574C6.14511 5.38082 5.7211 5.72609 5.45571 6.23099C5.31263 6.51475 5.22823 6.82161 5.14214 7.12447C5.11884 7.20619 5.09409 7.28745 5.06905 7.36869C5.0494 7.43261 5.0302 7.49663 5.01149 7.56081C5.00926 7.56844 5.00703 7.57608 5.00473 7.58395C4.99394 7.62094 4.98319 7.65793 4.97252 7.69495C4.94519 7.78879 4.91578 7.88187 4.88555 7.97489C4.83191 8.14021 4.7831 8.30674 4.73459 8.4735C4.66144 8.72457 4.66144 8.72457 4.61997 8.84527C4.61721 8.85337 4.61446 8.86147 4.61163 8.86982C4.59649 8.91278 4.58092 8.95233 4.55226 8.9887C4.50867 8.99788 4.50867 8.99788 4.46951 9C4.42473 8.93759 4.39508 8.87711 4.37133 8.80508C4.36787 8.79487 4.36441 8.78466 4.36085 8.77415C4.31684 8.64248 4.27751 8.50946 4.23817 8.37646C4.22916 8.34604 4.22011 8.31564 4.21105 8.28524C4.1436 8.05863 4.07725 7.83174 4.01101 7.60481C3.73507 6.48224 3.73507 6.48224 3.039 5.57466C3.02784 5.56596 3.01669 5.55726 3.00519 5.5483C2.54913 5.19902 1.94834 5.06969 1.39815 4.91813C1.26207 4.88062 1.12605 4.84293 0.990032 4.80523C0.978138 4.80193 0.978138 4.80193 0.966003 4.79857C0.769811 4.74417 0.573674 4.68963 0.378224 4.63283C0.369956 4.63045 0.361688 4.62806 0.353169 4.62561C0.0528989 4.53883 0.0528989 4.53883 0.000646537 4.4781C-0.000831261 4.45054 -0.000831261 4.45054 0.0124689 4.42157C0.0670835 4.3704 0.120077 4.34848 0.19216 4.32619C0.202597 4.32284 0.213034 4.31948 0.223787 4.31603C0.255753 4.30582 0.287788 4.29584 0.319851 4.28592C0.329001 4.28305 0.338151 4.28017 0.347578 4.27722C0.412285 4.25693 0.477225 4.2374 0.542259 4.21809C0.55824 4.21332 0.55824 4.21332 0.574544 4.20846C0.852269 4.12587 1.13181 4.049 1.41126 3.97196C1.6195 3.91455 1.82738 3.85618 2.0346 3.79548C2.04413 3.79271 2.05365 3.78993 2.06346 3.78707C2.5435 3.64696 3.01278 3.44816 3.32274 3.0537C3.32738 3.04785 3.33202 3.042 3.3368 3.03597C3.68197 2.59815 3.81658 2.06572 3.96695 1.54621C4.01643 1.37534 4.06649 1.20464 4.11673 1.03399C4.13064 0.986733 4.14453 0.939471 4.15836 0.892194C4.21394 0.702289 4.27035 0.512642 4.33 0.323864C4.33558 0.306186 4.34114 0.288501 4.34666 0.270807C4.43017 0.00398761 4.43017 0.00398761 4.50941 0Z\" fill=\"#0DBD7D\"/>\n <path d=\"M7.23597 0.554859C7.29024 0.613599 7.30109 0.682631 7.31799 0.757638C7.37436 0.993269 7.43929 1.20993 7.66467 1.34681C7.80371 1.42035 7.96944 1.45381 8.1235 1.48541C8.18854 1.49902 8.24348 1.51709 8.29924 1.55321C8.31181 1.57229 8.31181 1.57229 8.31107 1.60549C8.29814 1.64588 8.28678 1.6589 8.25269 1.68533C8.21543 1.69726 8.21543 1.69726 8.17068 1.70653C8.15375 1.71025 8.13683 1.714 8.11992 1.71779C8.11086 1.7198 8.10181 1.72181 8.09247 1.72388C7.81696 1.78482 7.81696 1.78482 7.57882 1.92273C7.57108 1.92869 7.56333 1.93466 7.55536 1.9408C7.38516 2.08431 7.34916 2.32303 7.29793 2.52301C7.29499 2.53399 7.29206 2.54497 7.28903 2.55629C7.28649 2.56601 7.28395 2.57573 7.28133 2.58575C7.27028 2.61544 7.25881 2.63479 7.23597 2.65754C7.17234 2.66527 7.17234 2.66527 7.14139 2.65754C7.09216 2.62106 7.08114 2.5795 7.06828 2.52365C7.06613 2.51501 7.06398 2.50636 7.06176 2.49745C7.05489 2.46983 7.04824 2.44217 7.04164 2.41449C6.98979 2.19897 6.93126 1.98751 6.72451 1.86118C6.56293 1.77501 6.36646 1.73426 6.18587 1.70136C6.13637 1.69151 6.10802 1.67911 6.07738 1.64012C6.07073 1.60055 6.07073 1.60055 6.07738 1.56098C6.12447 1.51437 6.17402 1.50299 6.23772 1.48891C6.25778 1.48416 6.27784 1.47938 6.29789 1.47456C6.30825 1.47209 6.31861 1.46962 6.32929 1.46707C6.38212 1.45407 6.43443 1.43949 6.48673 1.42462C6.49623 1.42198 6.50573 1.41935 6.51552 1.41663C6.62182 1.38624 6.71356 1.34737 6.79854 1.27836C6.80647 1.27213 6.81439 1.26589 6.82255 1.25946C6.9548 1.14565 6.99974 0.974674 7.04053 0.815134C7.04364 0.803022 7.04675 0.79091 7.04995 0.778432C7.05614 0.754101 7.06222 0.729743 7.06817 0.705359C7.07243 0.688394 7.07243 0.688394 7.07678 0.671086C7.07927 0.660951 7.08175 0.650816 7.08431 0.640373C7.09521 0.608108 7.10952 0.582772 7.12957 0.554859C7.1681 0.536435 7.19515 0.544764 7.23597 0.554859Z\" fill=\"#075F3F\"/>\n <path d=\"M1.79545 6.2471C1.80951 6.24719 1.80951 6.24719 1.82386 6.24729C1.92477 6.25022 1.99304 6.28115 2.06736 6.34601C2.15384 6.43533 2.19377 6.53611 2.1915 6.6565C2.18178 6.75412 2.12158 6.83935 2.04773 6.90533C1.96081 6.97242 1.87313 6.99459 1.76206 6.99149C1.66841 6.98107 1.5803 6.93852 1.51393 6.87451C1.43138 6.76681 1.40725 6.66803 1.41935 6.53537C1.44433 6.43092 1.51637 6.34613 1.6085 6.28666C1.67251 6.25564 1.72399 6.24652 1.79545 6.2471Z\" fill=\"#0DBD7D\"/>\n </svg>\n Self-healed\n </span>\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-rounded-[4px] cqa-py-0.5 cqa-px-1 cqa-bg-[#6366F11A] cqa-ml-1 cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity\" \n *ngIf=\"step?.executedResult?.video_start_time\" \n [matTooltip]=\"'Jump to video time'\" \n matTooltipPosition=\"below\"\n (click)=\"onJumpToTimestamp($event)\">\n <mat-icon class=\"cqa-text-[#636363] !cqa-text-[10px] !cqa-w-[10px] !cqa-h-[10px]\">\n play_arrow\n </mat-icon>\n <span class=\"cqa-text-[8px] cqa-leading-[12px] cqa-font-normal cqa-text-[#636363]\">\n {{ formatDurationClock(step?.executedResult?.video_start_time || 0) }}\n </span>\n </div>\n <div *ngIf=\"isDebug\" class=\"cqa-flex cqa-items-center cqa-gap-0.5 cqa-text-[#9CA3AF]\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Edit\" (click)=\"onEditStep($event)\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">edit</mat-icon>\n </button>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Add\" [matMenuTriggerFor]=\"addStepMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">add</mat-icon>\n </button>\n <mat-menu #addStepMenu=\"matMenu\" class=\"cqa-add-step-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of addStepMenuOptions\" (click)=\"onAddStepOptionSelect(opt, $event)\">\n {{ opt.label }}\n </button>\n </mat-menu>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"More options\" [matMenuTriggerFor]=\"stepMoreMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">more_vert</mat-icon>\n </button>\n <mat-menu #stepMoreMenu=\"matMenu\" class=\"cqa-step-more-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of stepMoreMenuOptions\" (click)=\"onStepMoreOptionSelect(opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n </div>\n <span class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF]\">\n {{ formatDuration(duration) }}\n </span>\n <svg *ngIf=\"hasSubSteps || (config.nestedSteps && config.nestedSteps.length > 0)\" [class.cqa-rotate-180]=\"isExpanded\" class=\"cqa-transition-transform\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M3.5 5L7 8.5L10.5 5\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n </div>\n\n <!-- Expanded Content -->\n <div *ngIf=\"isExpanded && (hasSubSteps || (config.nestedSteps && config.nestedSteps.length > 0))\">\n <!-- Sub-steps -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-1 cqa-pt-1 cqa-pl-9\">\n <!-- Single loop: render all entries in chronological order -->\n <ng-container *ngFor=\"let subStep of (isLive ? processedSubSteps : processedSubStepsForRunResult)\">\n <!-- AI_AUTO_HEAL_SUCCESS/FAILED: render with ai-agent-step style (both live and run result screens) -->\n <cqa-ai-logs-with-reasoning\n *ngIf=\"$any(subStep).isAiAutoHealResult\"\n [status]=\"subStep.status\"\n [text]=\"$any(subStep).text || subStep?.value\"\n [description]=\"$any(subStep).description || subStep?.text || subStep?.value\"\n [reasoning]=\"$any(subStep).reasoning || subStep?.reasoning\"\n [duration]=\"subStep.duration\">\n </cqa-ai-logs-with-reasoning>\n\n <!-- Regular sub-steps -->\n <div\n *ngIf=\"!$any(subStep).isAiAutoHealResult\"\n class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-py-[5.5px] cqa-px-3\">\n \n <!-- Sub-step Status Icon -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'success' || subStep?.status?.toLowerCase() === 'passed'\" >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Failure -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'failure' || subStep?.status?.toLowerCase() === 'failed'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7.5 4.5L4.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 4.5L7.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Pending -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'pending'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Running - Show spinner (also used for active WAIT_FOR_LOCATOR countdown in live mode) -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'running'\">\n <svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n </div>\n\n <!-- Sub-step Description -->\n <span class=\"cqa-flex-1 cqa-text-[13px] cqa-leading-[15px] cqa-text-[#364153]\" style=\"white-space: pre-line; word-break: break-word;\">\n {{ $any(subStep).description || $any(subStep).text }}\n <!-- Countdown for active WAIT_FOR_LOCATOR in live mode -->\n <span *ngIf=\"isLive && $any(subStep).remainingSeconds != null\" class=\"cqa-text-[#F97316] cqa-font-medium cqa-ml-1\">({{ $any(subStep).remainingSeconds }}s remaining)</span>\n </span>\n\n <!-- Sub-step Duration -->\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-metadata-key\">\n {{ formatDuration(subStep.duration) }}\n </span>\n </div>\n </ng-container>\n </div>\n\n <!-- Nested Steps -->\n <div *ngIf=\"hasChild || (config.nestedSteps && config.nestedSteps.length > 0)\" class=\"cqa-ml-9 cqa-pb-1\" style=\"border-bottom: '1px solid #F3F4F6'\">\n <div class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#737373] cqa-py-[2px] cqa-px-3\">Nested steps</div>\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2 cqa-pl-[18px]\" style=\"border-left: 2px solid #C5C7FA;\">\n <!-- Loading indicator for nested steps -->\n <div *ngIf=\"hasChild && (!config.nestedSteps || config.nestedSteps.length === 0) && isStepLoading()\" \n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-py-2 cqa-px-3\">\n <svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M7 1A6 6 0 0 1 13 7\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n <span class=\"cqa-text-[11px] cqa-leading-[13px] cqa-text-[#737373]\">Loading nested steps...</span>\n </div>\n\n\n <ng-container *ngFor=\"let step of config.nestedSteps; index as i\">\n <!-- Wrapper to show skeleton while step-renderer is loading -->\n <div\n class=\"cqa-step-renderer-wrapper\"\n [attr.id]=\"'exc-' + step.id\"\n [class.loaded]=\"!isNestedStepLoading(step)\">\n <!-- Loading skeleton overlay -->\n <!-- <div *ngIf=\"isNestedStepLoading(step)\" class=\"cqa-step-skeleton-overlay\">\n <div class=\"cqa-step-skeleton cqa-mx-3 cqa-my-1\"></div>\n </div> -->\n <!-- Use step-renderer for all nested steps to avoid circular dependencies -->\n <!-- The step-renderer will dynamically load the appropriate component and pass handlers -->\n <cqa-step-renderer \n [step]=\"step\"\n [stepNumber]=\"stepNumber + '.' + (i + 1)\"\n [onExpandHandler]=\"onExpandHandler\"\n [onConditionBranchClickHandler]=\"onConditionBranchClickHandler\"\n [getConditionBranchesHandler]=\"getConditionBranchesHandler\"\n [isStepLoadingHandler]=\"isStepLoadingHandler\"\n [isStepExpandedHandler]=\"isStepExpandedHandler\"\n [jumpToTimestampHandler]=\"jumpToTimestampHandler\"\n [convertMsToSecondsHandler]=\"convertMsToSecondsHandler\"\n [formatFailureDetailsHandler]=\"formatFailureDetailsHandler\"\n [getSelfHealAnalysisHandler]=\"getSelfHealAnalysisHandler\"\n [getLoopIterationsHandler]=\"getLoopIterationsHandler\"\n [getApiAssertionsHandler]=\"getApiAssertionsHandler\"\n [formatActionsHandler]=\"formatActionsHandler\"\n [onViewAllIterationsHandler]=\"onViewAllIterationsHandler\"\n [onMakeCurrentBaselineHandler]=\"onMakeCurrentBaselineHandler\"\n [onUploadBaselineHandler]=\"onUploadBaselineHandler\"\n [onAnalyzeHandler]=\"onAnalyzeHandler\"\n [onViewFullLogsHandler]=\"onViewFullLogsHandler\"\n [onSelfHealActionHandler]=\"onSelfHealActionHandler\"\n [getSelfHealLoadingStatesHandler]=\"getSelfHealLoadingStatesHandler\"\n [onStepClickHandler]=\"onStepClickHandler\"\n [onJsonPathCopiedHandler]=\"onJsonPathCopiedHandler\"\n [onDownloadHandler]=\"onDownloadHandler\"\n [onFilePathCopiedHandler]=\"onFilePathCopiedHandler\"\n [onTextCopiedHandler]=\"onTextCopiedHandler\"\n [downloadingStepId]=\"downloadingStepId\"\n [isUploadingBaseline]=\"isUploadingBaseline\"\n [isMakingCurrentBaseline]=\"isMakingCurrentBaseline\"\n [isLive]=\"isLive\"\n [isDebug]=\"isDebug\"\n [debugPointSet]=\"getDebugPointSetHandler ? getDebugPointSetHandler(step) : debugPointSet\"\n [getDebugPointSetHandler]=\"getDebugPointSetHandler\"\n [onDebugPointChangeHandler]=\"onDebugPointChangeHandler\"\n [onEditStepHandler]=\"onEditStepHandler\"\n [addStepMenuOptions]=\"addStepMenuOptions\"\n [onAddStepOptionSelectHandler]=\"onAddStepOptionSelectHandler\"\n [stepMoreMenuOptions]=\"stepMoreMenuOptions\"\n [onStepMoreOptionSelectHandler]=\"onStepMoreOptionSelectHandler\"\n (componentReady)=\"markStepLoaded(step)\">\n </cqa-step-renderer>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- Self Heal Analysis -->\n <cqa-self-heal-analysis \n *ngIf=\"selfHealAnalysis\" \n [id]=\"step?.testStepId\"\n [originalLocator]=\"selfHealAnalysis.originalLocator\"\n [healedLocator]=\"selfHealAnalysis.healedLocator\"\n [confidence]=\"selfHealAnalysis.confidence\"\n [healMethod]=\"selfHealAnalysis.healMethod\"\n [isLoadingAccept]=\"getSelfHealLoadingStatesHandler ? getSelfHealLoadingStatesHandler().isLoadingAccept?.[step?.testStepId] : false\"\n [isLoadingModifyAccept]=\"getSelfHealLoadingStatesHandler ? getSelfHealLoadingStatesHandler().isLoadingModifyAccept?.[step?.testStepId] : false\"\n (action)=\"onSelfHealAction($event)\">\n </cqa-self-heal-analysis>\n\n <!-- Timing Breakdown -->\n <div *ngIf=\"timingBreakdown\" class=\"cqa-flex cqa-items-center cqa-justify-end cqa-gap-5 cqa-mt-1 cqa-pt-4 cqa-px-4 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF]\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <span>Timing breakdown</span>\n </div>\n <span class=\"cqa-text-dialog-muted cqa-flex cqa-items-center cqa-gap-3\">\n <div>\n App <span class=\"cqa-text-gray-700\">{{ formatDuration(timingBreakdown.app) }}</span>\n </div>\n <div><svg width=\"1\" height=\"11\" viewBox=\"0 0 1 11\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M-3.8147e-06 10.32V-7.15256e-07H0.959996V10.32H-3.8147e-06Z\" fill=\"#E5E7EB\"/></svg></div>\n <div>\n Tool <span class=\"cqa-text-gray-700\">{{ formatDuration(timingBreakdown.tool) }}</span>\n </div>\n </span>\n </div>\n </div>\n\n <!-- View More Failed Step Button - shown when expanded and failure details exist -->\n <div *ngIf=\"showViewMoreButton\" class=\"cqa-mt-2 cqa-px-4\">\n <cqa-view-more-failed-step-button\n [timingBreakdown]=\"timingBreakdown\"\n [subSteps]=\"subSteps\"\n [failureDetails]=\"failureDetails\"\n [isExpanded]=\"showFailedStepDetails\"\n (viewMoreClick)=\"onViewMoreFailedStepClick($event)\">\n </cqa-view-more-failed-step-button>\n </div>\n\n <!-- Updated Failed Step Component - shown when button is clicked -->\n <div *ngIf=\"showViewMoreButton && showFailedStepDetails && failureDetails\" class=\"cqa-mt-2 cqa-px-4\">\n <cqa-updated-failed-step\n [testStepResultId]=\"testStepResultId\"\n [timingBreakdown]=\"timingBreakdown\"\n [expanded]=\"true\"\n [subSteps]=\"subSteps\"\n [failureDetails]=\"failureDetails\"\n [reasoning]=\"reasoning\"\n [confidence]=\"confidence\"\n [isUploadingBaseline]=\"isUploadingBaseline\"\n [isMakingCurrentBaseline]=\"isMakingCurrentBaseline\"\n [isLive]=\"isLive\"\n (makeCurrentBaseline)=\"onMakeCurrentBaseline($event)\"\n (uploadBaseline)=\"onUploadBaseline($event)\"\n (analyze)=\"onAnalyze()\"\n (viewFullLogs)=\"onViewFullLogs()\">\n </cqa-updated-failed-step>\n </div>\n</div>\n" }]
|
|
8949
9189
|
}], propDecorators: { id: [{
|
|
8950
9190
|
type: Input
|
|
8951
9191
|
}], testStepResultId: [{
|
|
@@ -9567,6 +9807,15 @@ class LoopStepComponent extends BaseStepComponent {
|
|
|
9567
9807
|
this.userManuallyClosed = false;
|
|
9568
9808
|
// Track which steps are still loading to show skeleton
|
|
9569
9809
|
this.loadingSteps = new Set();
|
|
9810
|
+
// Processed sub-steps for live mode WAIT_FOR_LOCATOR countdown grouping
|
|
9811
|
+
this.processedSubSteps = [];
|
|
9812
|
+
this.lastProcessedIndex = 0;
|
|
9813
|
+
this.waitLocatorGroupEntry = null;
|
|
9814
|
+
this.countdownIntervalId = null;
|
|
9815
|
+
// AI_AUTO_HEAL grouping: show loading until AI_AUTO_HEAL_SUCCESS or AI_AUTO_HEAL_FAILED
|
|
9816
|
+
this.aiAutoHealGroupEntry = null;
|
|
9817
|
+
// Processed sub-steps for run result screen (filter and split AI_AUTO_HEAL_SUCCESS/FAILED)
|
|
9818
|
+
this.processedSubStepsForRunResult = [];
|
|
9570
9819
|
}
|
|
9571
9820
|
/** Show debug icon when debug mode is on (shown on parent and all child steps). */
|
|
9572
9821
|
get showDebugIcon() {
|
|
@@ -9601,6 +9850,14 @@ class LoopStepComponent extends BaseStepComponent {
|
|
|
9601
9850
|
expanded: this.expanded,
|
|
9602
9851
|
};
|
|
9603
9852
|
super.ngOnInit();
|
|
9853
|
+
// Initialize live sub-step processing for WAIT_FOR_LOCATOR grouping
|
|
9854
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.subSteps && this.selectedIteration.subSteps.length > 0) {
|
|
9855
|
+
this.processLiveSubSteps();
|
|
9856
|
+
}
|
|
9857
|
+
else if (!this.isLive && this.selectedIteration && this.selectedIteration.subSteps && this.selectedIteration.subSteps.length > 0) {
|
|
9858
|
+
// Process for run result screen: filter and split AI_AUTO_HEAL_SUCCESS/FAILED
|
|
9859
|
+
this.processSubStepsForRunResult();
|
|
9860
|
+
}
|
|
9604
9861
|
// Initialize selection - prioritize selectedIterationId input, then default
|
|
9605
9862
|
if (this.selectedIterationId && this.iterations && this.iterations.length > 0) {
|
|
9606
9863
|
const found = this.iterations.find(iter => iter.id === this.selectedIterationId);
|
|
@@ -9641,9 +9898,20 @@ class LoopStepComponent extends BaseStepComponent {
|
|
|
9641
9898
|
if (currentValue) {
|
|
9642
9899
|
const found = this.iterations.find(iter => iter.id === currentValue);
|
|
9643
9900
|
if (found) {
|
|
9901
|
+
// Reset processing when switching to a different iteration
|
|
9902
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.id !== found.id) {
|
|
9903
|
+
this.resetLiveProcessing();
|
|
9904
|
+
}
|
|
9644
9905
|
this.selectedIteration = found;
|
|
9645
9906
|
// Sync userSelectedIterationId with the input value
|
|
9646
9907
|
this.userSelectedIterationId = currentValue;
|
|
9908
|
+
// Process live sub-steps when iteration changes
|
|
9909
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
9910
|
+
this.processLiveSubSteps();
|
|
9911
|
+
}
|
|
9912
|
+
else if (!this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
9913
|
+
this.processSubStepsForRunResult();
|
|
9914
|
+
}
|
|
9647
9915
|
}
|
|
9648
9916
|
else {
|
|
9649
9917
|
// If not found, select default
|
|
@@ -9662,14 +9930,35 @@ class LoopStepComponent extends BaseStepComponent {
|
|
|
9662
9930
|
if (this.userSelectedIterationId) {
|
|
9663
9931
|
const found = this.iterations.find(iter => iter.id === this.userSelectedIterationId);
|
|
9664
9932
|
if (found) {
|
|
9933
|
+
// Reset processing when switching to a different iteration
|
|
9934
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.id !== found.id) {
|
|
9935
|
+
this.resetLiveProcessing();
|
|
9936
|
+
}
|
|
9665
9937
|
this.selectedIteration = found;
|
|
9938
|
+
// Process live sub-steps when iteration changes
|
|
9939
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
9940
|
+
this.processLiveSubSteps();
|
|
9941
|
+
}
|
|
9942
|
+
else if (!this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
9943
|
+
this.processSubStepsForRunResult();
|
|
9944
|
+
}
|
|
9666
9945
|
}
|
|
9667
9946
|
else {
|
|
9668
9947
|
// User selection no longer valid, use selectedIterationId or default
|
|
9669
9948
|
if (this.selectedIterationId) {
|
|
9670
9949
|
const foundById = this.iterations.find(iter => iter.id === this.selectedIterationId);
|
|
9671
9950
|
if (foundById) {
|
|
9951
|
+
// Reset processing when switching to a different iteration
|
|
9952
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.id !== foundById.id) {
|
|
9953
|
+
this.resetLiveProcessing();
|
|
9954
|
+
}
|
|
9672
9955
|
this.selectedIteration = foundById;
|
|
9956
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
9957
|
+
this.processLiveSubSteps();
|
|
9958
|
+
}
|
|
9959
|
+
else if (!this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
9960
|
+
this.processSubStepsForRunResult();
|
|
9961
|
+
}
|
|
9673
9962
|
}
|
|
9674
9963
|
else {
|
|
9675
9964
|
this.selectDefaultIteration();
|
|
@@ -9685,7 +9974,14 @@ class LoopStepComponent extends BaseStepComponent {
|
|
|
9685
9974
|
if (this.selectedIterationId) {
|
|
9686
9975
|
const found = this.iterations.find(iter => iter.id === this.selectedIterationId);
|
|
9687
9976
|
if (found) {
|
|
9977
|
+
// Reset processing when switching to a different iteration
|
|
9978
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.id !== found.id) {
|
|
9979
|
+
this.resetLiveProcessing();
|
|
9980
|
+
}
|
|
9688
9981
|
this.selectedIteration = found;
|
|
9982
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
9983
|
+
this.processLiveSubSteps();
|
|
9984
|
+
}
|
|
9689
9985
|
}
|
|
9690
9986
|
else {
|
|
9691
9987
|
this.selectDefaultIteration();
|
|
@@ -9849,7 +10145,15 @@ class LoopStepComponent extends BaseStepComponent {
|
|
|
9849
10145
|
if (this.selectedIterationId) {
|
|
9850
10146
|
const found = this.iterations.find(iter => iter.id === this.selectedIterationId);
|
|
9851
10147
|
if (found) {
|
|
10148
|
+
// Reset processing when switching to a different iteration
|
|
10149
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.id !== found.id) {
|
|
10150
|
+
this.resetLiveProcessing();
|
|
10151
|
+
}
|
|
9852
10152
|
this.selectedIteration = found;
|
|
10153
|
+
// Process live sub-steps when iteration is selected
|
|
10154
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
10155
|
+
this.processLiveSubSteps();
|
|
10156
|
+
}
|
|
9853
10157
|
return;
|
|
9854
10158
|
}
|
|
9855
10159
|
}
|
|
@@ -9857,27 +10161,61 @@ class LoopStepComponent extends BaseStepComponent {
|
|
|
9857
10161
|
if (this.userSelectedIterationId) {
|
|
9858
10162
|
const found = this.iterations.find(iter => iter.id === this.userSelectedIterationId);
|
|
9859
10163
|
if (found) {
|
|
10164
|
+
// Reset processing when switching to a different iteration
|
|
10165
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.id !== found.id) {
|
|
10166
|
+
this.resetLiveProcessing();
|
|
10167
|
+
}
|
|
9860
10168
|
this.selectedIteration = found;
|
|
10169
|
+
// Process live sub-steps when iteration is selected
|
|
10170
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
10171
|
+
this.processLiveSubSteps();
|
|
10172
|
+
}
|
|
9861
10173
|
return;
|
|
9862
10174
|
}
|
|
9863
10175
|
}
|
|
9864
10176
|
// Apply default based on defaultIteration setting
|
|
9865
10177
|
if (this.defaultIteration === 'last' && this.iterations.length > 0) {
|
|
9866
10178
|
const lastIteration = this.iterations[this.iterations.length - 1];
|
|
10179
|
+
// Reset processing when switching to a different iteration
|
|
10180
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.id !== lastIteration.id) {
|
|
10181
|
+
this.resetLiveProcessing();
|
|
10182
|
+
}
|
|
9867
10183
|
this.selectedIteration = lastIteration;
|
|
9868
10184
|
// Set userSelectedIterationId to track the default selection
|
|
9869
10185
|
this.userSelectedIterationId = lastIteration.id;
|
|
10186
|
+
// Process live sub-steps when iteration is selected
|
|
10187
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
10188
|
+
this.processLiveSubSteps();
|
|
10189
|
+
}
|
|
10190
|
+
else if (!this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
10191
|
+
this.processSubStepsForRunResult();
|
|
10192
|
+
}
|
|
9870
10193
|
}
|
|
9871
10194
|
else if (this.iterations.length > 0) {
|
|
9872
10195
|
const firstIteration = this.iterations[0];
|
|
10196
|
+
// Reset processing when switching to a different iteration
|
|
10197
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.id !== firstIteration.id) {
|
|
10198
|
+
this.resetLiveProcessing();
|
|
10199
|
+
}
|
|
9873
10200
|
this.selectedIteration = firstIteration;
|
|
9874
10201
|
// Set userSelectedIterationId to track the default selection
|
|
9875
10202
|
this.userSelectedIterationId = firstIteration.id;
|
|
10203
|
+
// Process live sub-steps when iteration is selected
|
|
10204
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
10205
|
+
this.processLiveSubSteps();
|
|
10206
|
+
}
|
|
10207
|
+
else if (!this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
10208
|
+
this.processSubStepsForRunResult();
|
|
10209
|
+
}
|
|
9876
10210
|
}
|
|
9877
10211
|
}
|
|
9878
10212
|
handleIterationChange(iteration) {
|
|
9879
10213
|
var _a;
|
|
9880
10214
|
console.log("ITERATION CHANGE", this.config, iteration);
|
|
10215
|
+
// Reset processing when switching iterations
|
|
10216
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.id !== iteration.id) {
|
|
10217
|
+
this.resetLiveProcessing();
|
|
10218
|
+
}
|
|
9881
10219
|
// Store the user's manual selection
|
|
9882
10220
|
this.selectedIteration = iteration;
|
|
9883
10221
|
this.userSelectedIterationId = iteration.id;
|
|
@@ -9897,6 +10235,13 @@ class LoopStepComponent extends BaseStepComponent {
|
|
|
9897
10235
|
this.config = Object.assign(Object.assign({}, this.config), { nestedSteps: updatedNestedSteps });
|
|
9898
10236
|
}
|
|
9899
10237
|
}
|
|
10238
|
+
// Process live sub-steps when iteration changes
|
|
10239
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
10240
|
+
this.processLiveSubSteps();
|
|
10241
|
+
}
|
|
10242
|
+
else if (!this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
10243
|
+
this.processSubStepsForRunResult();
|
|
10244
|
+
}
|
|
9900
10245
|
}
|
|
9901
10246
|
// Emit the event with the iteration ID
|
|
9902
10247
|
this.onIterationChange.emit(iteration.id);
|
|
@@ -10187,12 +10532,193 @@ class LoopStepComponent extends BaseStepComponent {
|
|
|
10187
10532
|
}
|
|
10188
10533
|
}
|
|
10189
10534
|
}
|
|
10535
|
+
ngDoCheck() {
|
|
10536
|
+
if (!this.isLive || !this.selectedIteration)
|
|
10537
|
+
return;
|
|
10538
|
+
const currentLength = (this.selectedIteration.subSteps || []).length;
|
|
10539
|
+
// Reset if iteration changed (detected by checking if we have a different iteration's subSteps)
|
|
10540
|
+
if (this.lastProcessedIndex > 0 && currentLength < this.lastProcessedIndex) {
|
|
10541
|
+
// Likely switched to a different iteration, reset
|
|
10542
|
+
this.resetLiveProcessing();
|
|
10543
|
+
}
|
|
10544
|
+
if (currentLength !== this.lastProcessedIndex) {
|
|
10545
|
+
this.processLiveSubSteps();
|
|
10546
|
+
}
|
|
10547
|
+
}
|
|
10548
|
+
ngOnDestroy() {
|
|
10549
|
+
this.clearCountdownTimer();
|
|
10550
|
+
}
|
|
10551
|
+
processLiveSubSteps() {
|
|
10552
|
+
var _a, _b, _c, _d;
|
|
10553
|
+
if (!this.selectedIteration || !this.selectedIteration.subSteps) {
|
|
10554
|
+
this.resetLiveProcessing();
|
|
10555
|
+
return;
|
|
10556
|
+
}
|
|
10557
|
+
const allSubSteps = (this.selectedIteration.subSteps || []);
|
|
10558
|
+
// Reset if subSteps were cleared or replaced with fewer entries
|
|
10559
|
+
if (allSubSteps.length < this.lastProcessedIndex) {
|
|
10560
|
+
this.resetLiveProcessing();
|
|
10561
|
+
}
|
|
10562
|
+
for (let i = this.lastProcessedIndex; i < allSubSteps.length; i++) {
|
|
10563
|
+
const subStep = allSubSteps[i];
|
|
10564
|
+
const uiType = (subStep === null || subStep === void 0 ? void 0 : subStep.uiType) || (subStep === null || subStep === void 0 ? void 0 : subStep.type) || '';
|
|
10565
|
+
const status = ((subStep === null || subStep === void 0 ? void 0 : subStep.status) || '').toLowerCase();
|
|
10566
|
+
if (uiType === 'WAIT_FOR_LOCATOR') {
|
|
10567
|
+
// Create a single grouped entry with a countdown; absorbs FIND_LOCATOR and LOCATOR_FOUND
|
|
10568
|
+
const timeoutSeconds = typeof subStep.value === 'number'
|
|
10569
|
+
? subStep.value
|
|
10570
|
+
: (subStep.value ? parseFloat(subStep.value) : 30);
|
|
10571
|
+
this.clearCountdownTimer();
|
|
10572
|
+
this.waitLocatorGroupEntry = Object.assign(Object.assign({}, subStep), { remainingSeconds: timeoutSeconds, status: 'running' });
|
|
10573
|
+
this.processedSubSteps.push(this.waitLocatorGroupEntry);
|
|
10574
|
+
// Tick down every second
|
|
10575
|
+
this.countdownIntervalId = setInterval(() => {
|
|
10576
|
+
if (this.waitLocatorGroupEntry) {
|
|
10577
|
+
this.waitLocatorGroupEntry.remainingSeconds = Math.max(0, this.waitLocatorGroupEntry.remainingSeconds - 1);
|
|
10578
|
+
if (this.waitLocatorGroupEntry.remainingSeconds <= 0) {
|
|
10579
|
+
this.waitLocatorGroupEntry.status = 'failed';
|
|
10580
|
+
this.waitLocatorGroupEntry.remainingSeconds = null;
|
|
10581
|
+
this.clearCountdownTimer();
|
|
10582
|
+
this.waitLocatorGroupEntry = null;
|
|
10583
|
+
}
|
|
10584
|
+
}
|
|
10585
|
+
}, 1000);
|
|
10586
|
+
}
|
|
10587
|
+
else if (uiType === 'FIND_LOCATOR') {
|
|
10588
|
+
if (status === 'failed' || status === 'failure') {
|
|
10589
|
+
// Abort countdown, replace group entry with this failed log
|
|
10590
|
+
if (this.waitLocatorGroupEntry) {
|
|
10591
|
+
this.processedSubSteps = this.processedSubSteps.filter(entry => entry !== this.waitLocatorGroupEntry);
|
|
10592
|
+
this.clearCountdownTimer();
|
|
10593
|
+
this.waitLocatorGroupEntry = null;
|
|
10594
|
+
}
|
|
10595
|
+
this.processedSubSteps.push(Object.assign(Object.assign({}, subStep), { status: 'failed' }));
|
|
10596
|
+
}
|
|
10597
|
+
else if (this.waitLocatorGroupEntry) {
|
|
10598
|
+
// Update the single group entry's text so the user sees progress
|
|
10599
|
+
const newText = subStep.description || subStep.text || subStep.title;
|
|
10600
|
+
if (newText)
|
|
10601
|
+
this.waitLocatorGroupEntry.description = newText;
|
|
10602
|
+
}
|
|
10603
|
+
}
|
|
10604
|
+
else if (uiType === 'LOCATOR_FOUND') {
|
|
10605
|
+
if (status === 'failed' || status === 'failure') {
|
|
10606
|
+
// Abort countdown, replace group entry with this failed log
|
|
10607
|
+
if (this.waitLocatorGroupEntry) {
|
|
10608
|
+
this.processedSubSteps = this.processedSubSteps.filter(entry => entry !== this.waitLocatorGroupEntry);
|
|
10609
|
+
this.clearCountdownTimer();
|
|
10610
|
+
this.waitLocatorGroupEntry = null;
|
|
10611
|
+
}
|
|
10612
|
+
this.processedSubSteps.push(Object.assign(Object.assign({}, subStep), { status: 'failed' }));
|
|
10613
|
+
}
|
|
10614
|
+
else {
|
|
10615
|
+
// Sequence complete – update group entry to show LOCATOR_FOUND text as success
|
|
10616
|
+
if (this.waitLocatorGroupEntry) {
|
|
10617
|
+
const newText = subStep.description || subStep.text || subStep.title;
|
|
10618
|
+
if (newText)
|
|
10619
|
+
this.waitLocatorGroupEntry.description = newText;
|
|
10620
|
+
this.waitLocatorGroupEntry.status = 'success';
|
|
10621
|
+
this.waitLocatorGroupEntry.remainingSeconds = null;
|
|
10622
|
+
this.clearCountdownTimer();
|
|
10623
|
+
this.waitLocatorGroupEntry = null;
|
|
10624
|
+
}
|
|
10625
|
+
else {
|
|
10626
|
+
// No active group – push LOCATOR_FOUND normally
|
|
10627
|
+
this.processedSubSteps.push(Object.assign({}, subStep));
|
|
10628
|
+
}
|
|
10629
|
+
}
|
|
10630
|
+
}
|
|
10631
|
+
else if (uiType === 'AI_AUTO_HEAL') {
|
|
10632
|
+
// Add single loading entry; will be replaced by AI_AUTO_HEAL_SUCCESS or AI_AUTO_HEAL_FAILED
|
|
10633
|
+
this.aiAutoHealGroupEntry = Object.assign(Object.assign({}, subStep), { description: subStep.description || subStep.text || 'AI auto-heal started', status: 'running', uiType: 'AI_AUTO_HEAL' });
|
|
10634
|
+
this.processedSubSteps.push(this.aiAutoHealGroupEntry);
|
|
10635
|
+
}
|
|
10636
|
+
else if (uiType === 'AI_AUTO_HEAL_SUCCESS' || uiType === 'AI_AUTO_HEAL_FAILED') {
|
|
10637
|
+
// Remove loading entry and add TWO separate entries: value and reasoning (like AI_ANSWER)
|
|
10638
|
+
if (this.aiAutoHealGroupEntry) {
|
|
10639
|
+
this.processedSubSteps = this.processedSubSteps.filter(entry => entry !== this.aiAutoHealGroupEntry);
|
|
10640
|
+
this.aiAutoHealGroupEntry = null;
|
|
10641
|
+
}
|
|
10642
|
+
const isSuccess = uiType === 'AI_AUTO_HEAL_SUCCESS';
|
|
10643
|
+
const value = (_b = (_a = subStep.value) !== null && _a !== void 0 ? _a : subStep.text) !== null && _b !== void 0 ? _b : '';
|
|
10644
|
+
const reasoning = (_d = (_c = subStep.reasoning) !== null && _c !== void 0 ? _c : subStep.Reasoning) !== null && _d !== void 0 ? _d : '';
|
|
10645
|
+
const baseDuration = subStep.duration || 0;
|
|
10646
|
+
const finalStatus = isSuccess ? 'success' : 'failed';
|
|
10647
|
+
// First entry: value/description
|
|
10648
|
+
const valueDescription = subStep.text || subStep.description || (isSuccess
|
|
10649
|
+
? `AI auto-heal successful. New locator: ${value}`
|
|
10650
|
+
: `AI auto-heal failed for element: ${value}`);
|
|
10651
|
+
this.processedSubSteps.push(Object.assign(Object.assign({}, subStep), { description: valueDescription, value: value, reasoning: null, status: finalStatus, uiType: 'AI_AUTO_HEAL_VALUE', type: 'AI_AUTO_HEAL_VALUE', duration: baseDuration, isAiAutoHealResult: true }));
|
|
10652
|
+
// Second entry: reasoning (only if present)
|
|
10653
|
+
if (reasoning) {
|
|
10654
|
+
this.processedSubSteps.push(Object.assign(Object.assign({}, subStep), { description: reasoning, value: null, reasoning: reasoning, status: finalStatus, uiType: 'AI_AUTO_HEAL_REASONING', type: 'AI_AUTO_HEAL_REASONING', duration: baseDuration, isAiAutoHealResult: true }));
|
|
10655
|
+
}
|
|
10656
|
+
}
|
|
10657
|
+
else {
|
|
10658
|
+
// Any failed log while a countdown is active – resolve it as failed
|
|
10659
|
+
if ((status === 'failed' || status === 'failure') && this.waitLocatorGroupEntry) {
|
|
10660
|
+
this.waitLocatorGroupEntry.status = 'failed';
|
|
10661
|
+
this.waitLocatorGroupEntry.remainingSeconds = null;
|
|
10662
|
+
this.clearCountdownTimer();
|
|
10663
|
+
this.waitLocatorGroupEntry = null;
|
|
10664
|
+
}
|
|
10665
|
+
this.processedSubSteps.push(subStep);
|
|
10666
|
+
}
|
|
10667
|
+
}
|
|
10668
|
+
this.lastProcessedIndex = allSubSteps.length;
|
|
10669
|
+
}
|
|
10670
|
+
resetLiveProcessing() {
|
|
10671
|
+
this.clearCountdownTimer();
|
|
10672
|
+
this.processedSubSteps = [];
|
|
10673
|
+
this.lastProcessedIndex = 0;
|
|
10674
|
+
this.waitLocatorGroupEntry = null;
|
|
10675
|
+
this.aiAutoHealGroupEntry = null;
|
|
10676
|
+
}
|
|
10677
|
+
clearCountdownTimer() {
|
|
10678
|
+
if (this.countdownIntervalId !== null) {
|
|
10679
|
+
clearInterval(this.countdownIntervalId);
|
|
10680
|
+
this.countdownIntervalId = null;
|
|
10681
|
+
}
|
|
10682
|
+
}
|
|
10683
|
+
processSubStepsForRunResult() {
|
|
10684
|
+
var _a, _b, _c, _d;
|
|
10685
|
+
if (!this.selectedIteration || !this.selectedIteration.subSteps) {
|
|
10686
|
+
this.processedSubStepsForRunResult = [];
|
|
10687
|
+
return;
|
|
10688
|
+
}
|
|
10689
|
+
const allSubSteps = (this.selectedIteration.subSteps || []);
|
|
10690
|
+
this.processedSubStepsForRunResult = [];
|
|
10691
|
+
for (const subStep of allSubSteps) {
|
|
10692
|
+
const uiType = (subStep === null || subStep === void 0 ? void 0 : subStep.uiType) || (subStep === null || subStep === void 0 ? void 0 : subStep.type) || '';
|
|
10693
|
+
// Split AI_AUTO_HEAL_SUCCESS/FAILED into two entries
|
|
10694
|
+
if (uiType === 'AI_AUTO_HEAL_SUCCESS' || uiType === 'AI_AUTO_HEAL_FAILED') {
|
|
10695
|
+
const isSuccess = uiType === 'AI_AUTO_HEAL_SUCCESS';
|
|
10696
|
+
const value = (_b = (_a = subStep.value) !== null && _a !== void 0 ? _a : subStep.text) !== null && _b !== void 0 ? _b : '';
|
|
10697
|
+
const reasoning = (_d = (_c = subStep.reasoning) !== null && _c !== void 0 ? _c : subStep.Reasoning) !== null && _d !== void 0 ? _d : '';
|
|
10698
|
+
const baseDuration = subStep.duration || 0;
|
|
10699
|
+
const finalStatus = isSuccess ? 'success' : 'failed';
|
|
10700
|
+
// First entry: value/description
|
|
10701
|
+
const valueDescription = (isSuccess
|
|
10702
|
+
? `AI auto-heal successful. New locator: ${value}`
|
|
10703
|
+
: `AI auto-heal failed for element: ${value}`);
|
|
10704
|
+
this.processedSubStepsForRunResult.push(Object.assign(Object.assign({}, subStep), { description: valueDescription, value: value, reasoning: null, status: finalStatus, uiType: 'AI_AUTO_HEAL_VALUE', type: 'AI_AUTO_HEAL_VALUE', duration: baseDuration, isAiAutoHealResult: true }));
|
|
10705
|
+
// Second entry: reasoning (only if present)
|
|
10706
|
+
if (reasoning) {
|
|
10707
|
+
this.processedSubStepsForRunResult.push(Object.assign(Object.assign({}, subStep), { description: reasoning, value: null, reasoning: reasoning, status: finalStatus, uiType: 'AI_AUTO_HEAL_REASONING', type: 'AI_AUTO_HEAL_REASONING', duration: baseDuration, isAiAutoHealResult: true }));
|
|
10708
|
+
}
|
|
10709
|
+
}
|
|
10710
|
+
else {
|
|
10711
|
+
// All other logs pass through as-is
|
|
10712
|
+
this.processedSubStepsForRunResult.push(subStep);
|
|
10713
|
+
}
|
|
10714
|
+
}
|
|
10715
|
+
}
|
|
10190
10716
|
}
|
|
10191
10717
|
LoopStepComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: LoopStepComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
10192
|
-
LoopStepComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: LoopStepComponent, selector: "cqa-loop-step", inputs: { id: "id", testStepResultId: "testStepResultId", stepNumber: "stepNumber", title: "title", status: "status", duration: "duration", timingBreakdown: "timingBreakdown", expanded: "expanded", loopType: "loopType", iterations: "iterations", selectedIterationId: "selectedIterationId", defaultIteration: "defaultIteration", nestedSteps: "nestedSteps", showViewAllIterations: "showViewAllIterations", hasChild: "hasChild", isLive: "isLive", isLoading: "isLoading", stepDeleted: "stepDeleted", isDebug: "isDebug", debugPointSet: "debugPointSet", getDebugPointSetHandler: "getDebugPointSetHandler", onDebugPointChangeHandler: "onDebugPointChangeHandler", addStepMenuOptions: "addStepMenuOptions", stepMoreMenuOptions: "stepMoreMenuOptions", onExpandHandler: "onExpandHandler", onEditStepHandler: "onEditStepHandler", onAddStepOptionSelectHandler: "onAddStepOptionSelectHandler", onStepMoreOptionSelectHandler: "onStepMoreOptionSelectHandler", getAddStepMenuOptionsForNested: "getAddStepMenuOptionsForNested", getStepMoreMenuOptionsForNested: "getStepMoreMenuOptionsForNested", getConditionBranchesHandler: "getConditionBranchesHandler", onConditionBranchClickHandler: "onConditionBranchClickHandler", isStepLoadingHandler: "isStepLoadingHandler", isStepExpandedHandler: "isStepExpandedHandler", convertMsToSecondsHandler: "convertMsToSecondsHandler", formatFailureDetailsHandler: "formatFailureDetailsHandler", getSelfHealAnalysisHandler: "getSelfHealAnalysisHandler", onMakeCurrentBaselineHandler: "onMakeCurrentBaselineHandler", onUploadBaselineHandler: "onUploadBaselineHandler", onAnalyzeHandler: "onAnalyzeHandler", onViewFullLogsHandler: "onViewFullLogsHandler", onSelfHealActionHandler: "onSelfHealActionHandler", getSelfHealLoadingStatesHandler: "getSelfHealLoadingStatesHandler", getLoopIterationsHandler: "getLoopIterationsHandler", getApiAssertionsHandler: "getApiAssertionsHandler", formatActionsHandler: "formatActionsHandler", onViewAllIterationsHandler: "onViewAllIterationsHandler", onStepClickHandler: "onStepClickHandler", onJsonPathCopiedHandler: "onJsonPathCopiedHandler", onDownloadHandler: "onDownloadHandler", onFilePathCopiedHandler: "onFilePathCopiedHandler", onTextCopiedHandler: "onTextCopiedHandler", jumpToTimestampHandler: "jumpToTimestampHandler", downloadingStepId: "downloadingStepId", step: "step", failureDetails: "failureDetails", reasoning: "reasoning", confidence: "confidence", isUploadingBaseline: "isUploadingBaseline", isMakingCurrentBaseline: "isMakingCurrentBaseline", selfHealAnalysis: "selfHealAnalysis", iterationData: "iterationData" }, outputs: { debugPointChange: "debugPointChange", editStep: "editStep", addStepOptionSelect: "addStepOptionSelect", stepMoreOptionSelect: "stepMoreOptionSelect", makeCurrentBaseline: "makeCurrentBaseline", uploadBaseline: "uploadBaseline", analyze: "analyze", viewFullLogs: "viewFullLogs", selfHealAction: "selfHealAction", onExpand: "onExpand", onViewAllIterations: "onViewAllIterations", onIterationChange: "onIterationChange" }, host: { classAttribute: "cqa-ui-root" }, viewQueries: [{ propertyName: "addStepMenuTrigger", first: true, predicate: ["addStepMenuTrigger"], descendants: true }, { propertyName: "stepMoreMenuTrigger", first: true, predicate: ["stepMoreMenuTrigger"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-font-inter\" (click)=\"$event.stopPropagation()\">\n <!-- Header -->\n <div\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-p-2 cqa-cursor-pointer\"\n (click)=\"toggleHeader($event)\">\n <div *ngIf=\"showDebugIcon\" class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer cqa-rounded-full hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" (click)=\"onDebugPointClick($event)\" [attr.aria-label]=\"debugPointSet ? 'Remove debug point' : 'Set debug point'\">\n <svg *ngIf=\"debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" fill=\"#C63535\"/>\n </svg>\n <svg *ngIf=\"!debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" stroke=\"#C63535\" stroke-width=\"1.5\" fill=\"none\"/>\n </svg>\n </button>\n </div>\n <!-- Status Icon -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <!-- Success -->\n <svg *ngIf=\"status.toLowerCase() === 'success'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <!-- Failed -->\n <svg *ngIf=\"status.toLowerCase() === 'failure' || status.toLowerCase() === 'failed'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4 4L8 8M8 4L4 8\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <!-- Pending -->\n <svg *ngIf=\"status.toLowerCase() === 'pending'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <!-- Running -->\n <svg *ngIf=\"status.toLowerCase() === 'running'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#3B82F6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#3B82F6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n \n <span *ngIf=\"status.toLowerCase() === 'skipped'\" class=\"material-symbols-outlined cqa-text-[#9CA3AF] cqa-text-[12px]\">\n skip_next\n </span>\n </div>\n\n <!-- Loop Icon -->\n <div><svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"16\" height=\"16\" rx=\"4\" fill=\"#EBECFD\"/><path d=\"M9.66663 4.66666L11 5.99999L9.66663 7.33332\" stroke=\"#3F43EE\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M5 7.66667V7.33333C5 6.97971 5.14048 6.64057 5.39052 6.39052C5.64057 6.14048 5.97971 6 6.33333 6H11\" stroke=\"#3F43EE\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6.33333 11.3333L5 9.99999L6.33333 8.66666\" stroke=\"#3F43EE\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M11 8.33334V8.66668C11 9.0203 10.8595 9.35944 10.6095 9.60949C10.3594 9.85953 10.0203 10 9.66667 10H5\" stroke=\"#3F43EE\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n\n <!-- Step Number and Title -->\n <div class=\"cqa-flex-1 cqa-flex cqa-items-center cqa-gap-3 cqa-font-inter\">\n <span class=\"cqa-font-semibold cqa-text-[#334155] cqa-text-[14px] cqa-leading-[18px]\" style=\"word-break: break-word;\">\n {{ config?.stepNumber }}. <span [innerHTML]=\"config?.title\"></span>\n </span>\n \n <!-- Loop Type Badges -->\n <span *ngFor=\"let badge of getLoopTypeBadges()\" \n class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-primary cqa-bg-[#EBECFD] cqa-text-[10px] cqa-leading-[15px]\">\n {{ badge }}\n </span>\n <span *ngIf=\"config.stepDeleted\" class=\"cqa-px-1.5 cqa-py-[2px] cqa-rounded-[4px] cqa-text-[10px] cqa-leading-[12px] cqa-font-medium cqa-text-[#B42318] cqa-bg-[#FEF3F2] cqa-border cqa-border-[#FEE4E2]\">\n Deleted\n </span>\n </div>\n\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-font-inter\">\n <span *ngIf=\"selfHealAnalysis\" class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-[#097E53] cqa-bg-[#CFF2E5] cqa-text-[10px] cqa-leading-[15px] cqa-min-w-max cqa-flex cqa-items-center cqa-gap-[6px]\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"9\" height=\"9\" viewBox=\"0 0 9 9\" fill=\"none\">\n <path d=\"M4.50941 0C4.56489 0.0227384 4.58859 0.0782652 4.61131 0.129846C4.62269 0.1599 4.63314 0.190117 4.64329 0.220575C4.64726 0.232247 4.65123 0.243918 4.65532 0.255943C4.70806 0.413005 4.75504 0.571748 4.80229 0.73038C4.81297 0.76619 4.82369 0.801987 4.83442 0.837783C4.88905 1.02004 4.94327 1.2024 4.99719 1.38484C5.00476 1.41047 5.01234 1.43609 5.01992 1.46171C5.04128 1.53395 5.06262 1.60619 5.08383 1.67847C5.12867 1.8312 5.17473 1.98347 5.22378 2.13501C5.22807 2.14827 5.23236 2.16152 5.23677 2.17518C5.3642 2.565 5.54482 2.91437 5.8409 3.21196C5.84823 3.2197 5.85556 3.22744 5.86312 3.23541C5.9895 3.36437 6.15169 3.46771 6.3138 3.55111C6.32206 3.55542 6.33031 3.55974 6.33882 3.56419C6.81587 3.80925 7.38951 3.91704 7.90619 4.0605C8.1326 4.1234 8.3583 4.18829 8.58317 4.25603C8.59897 4.26079 8.61478 4.26554 8.63058 4.27028C8.67784 4.28445 8.725 4.29887 8.77211 4.31347C8.7831 4.31679 8.79408 4.32011 8.80539 4.32353C8.87029 4.34406 8.93239 4.36829 8.98566 4.41027C9.00191 4.44418 9.00191 4.44418 8.99748 4.4781C8.94564 4.52736 8.8942 4.55046 8.82578 4.573C8.816 4.57632 8.80622 4.57965 8.79614 4.58308C8.68061 4.62183 8.56351 4.65575 8.44626 4.68935C8.4222 4.6963 8.39814 4.70326 8.37408 4.71021C8.22571 4.75301 8.07708 4.7949 7.92829 4.83632C7.73232 4.89088 7.53663 4.94634 7.34113 5.00243C7.3091 5.01162 7.27706 5.02078 7.24501 5.02991C7.07671 5.07786 6.90923 5.12753 6.74314 5.18208C6.72937 5.18659 6.71559 5.1911 6.70139 5.19574C6.14511 5.38082 5.7211 5.72609 5.45571 6.23099C5.31263 6.51475 5.22823 6.82161 5.14214 7.12447C5.11884 7.20619 5.09409 7.28745 5.06905 7.36869C5.0494 7.43261 5.0302 7.49663 5.01149 7.56081C5.00926 7.56844 5.00703 7.57608 5.00473 7.58395C4.99394 7.62094 4.98319 7.65793 4.97252 7.69495C4.94519 7.78879 4.91578 7.88187 4.88555 7.97489C4.83191 8.14021 4.7831 8.30674 4.73459 8.4735C4.66144 8.72457 4.66144 8.72457 4.61997 8.84527C4.61721 8.85337 4.61446 8.86147 4.61163 8.86982C4.59649 8.91278 4.58092 8.95233 4.55226 8.9887C4.50867 8.99788 4.50867 8.99788 4.46951 9C4.42473 8.93759 4.39508 8.87711 4.37133 8.80508C4.36787 8.79487 4.36441 8.78466 4.36085 8.77415C4.31684 8.64248 4.27751 8.50946 4.23817 8.37646C4.22916 8.34604 4.22011 8.31564 4.21105 8.28524C4.1436 8.05863 4.07725 7.83174 4.01101 7.60481C3.73507 6.48224 3.73507 6.48224 3.039 5.57466C3.02784 5.56596 3.01669 5.55726 3.00519 5.5483C2.54913 5.19902 1.94834 5.06969 1.39815 4.91813C1.26207 4.88062 1.12605 4.84293 0.990032 4.80523C0.978138 4.80193 0.978138 4.80193 0.966003 4.79857C0.769811 4.74417 0.573674 4.68963 0.378224 4.63283C0.369956 4.63045 0.361688 4.62806 0.353169 4.62561C0.0528989 4.53883 0.0528989 4.53883 0.000646537 4.4781C-0.000831261 4.45054 -0.000831261 4.45054 0.0124689 4.42157C0.0670835 4.3704 0.120077 4.34848 0.19216 4.32619C0.202597 4.32284 0.213034 4.31948 0.223787 4.31603C0.255753 4.30582 0.287788 4.29584 0.319851 4.28592C0.329001 4.28305 0.338151 4.28017 0.347578 4.27722C0.412285 4.25693 0.477225 4.2374 0.542259 4.21809C0.55824 4.21332 0.55824 4.21332 0.574544 4.20846C0.852269 4.12587 1.13181 4.049 1.41126 3.97196C1.6195 3.91455 1.82738 3.85618 2.0346 3.79548C2.04413 3.79271 2.05365 3.78993 2.06346 3.78707C2.5435 3.64696 3.01278 3.44816 3.32274 3.0537C3.32738 3.04785 3.33202 3.042 3.3368 3.03597C3.68197 2.59815 3.81658 2.06572 3.96695 1.54621C4.01643 1.37534 4.06649 1.20464 4.11673 1.03399C4.13064 0.986733 4.14453 0.939471 4.15836 0.892194C4.21394 0.702289 4.27035 0.512642 4.33 0.323864C4.33558 0.306186 4.34114 0.288501 4.34666 0.270807C4.43017 0.00398761 4.43017 0.00398761 4.50941 0Z\" fill=\"#0DBD7D\"/>\n <path d=\"M7.23597 0.554859C7.29024 0.613599 7.30109 0.682631 7.31799 0.757638C7.37436 0.993269 7.43929 1.20993 7.66467 1.34681C7.80371 1.42035 7.96944 1.45381 8.1235 1.48541C8.18854 1.49902 8.24348 1.51709 8.29924 1.55321C8.31181 1.57229 8.31181 1.57229 8.31107 1.60549C8.29814 1.64588 8.28678 1.6589 8.25269 1.68533C8.21543 1.69726 8.21543 1.69726 8.17068 1.70653C8.15375 1.71025 8.13683 1.714 8.11992 1.71779C8.11086 1.7198 8.10181 1.72181 8.09247 1.72388C7.81696 1.78482 7.81696 1.78482 7.57882 1.92273C7.57108 1.92869 7.56333 1.93466 7.55536 1.9408C7.38516 2.08431 7.34916 2.32303 7.29793 2.52301C7.29499 2.53399 7.29206 2.54497 7.28903 2.55629C7.28649 2.56601 7.28395 2.57573 7.28133 2.58575C7.27028 2.61544 7.25881 2.63479 7.23597 2.65754C7.17234 2.66527 7.17234 2.66527 7.14139 2.65754C7.09216 2.62106 7.08114 2.5795 7.06828 2.52365C7.06613 2.51501 7.06398 2.50636 7.06176 2.49745C7.05489 2.46983 7.04824 2.44217 7.04164 2.41449C6.98979 2.19897 6.93126 1.98751 6.72451 1.86118C6.56293 1.77501 6.36646 1.73426 6.18587 1.70136C6.13637 1.69151 6.10802 1.67911 6.07738 1.64012C6.07073 1.60055 6.07073 1.60055 6.07738 1.56098C6.12447 1.51437 6.17402 1.50299 6.23772 1.48891C6.25778 1.48416 6.27784 1.47938 6.29789 1.47456C6.30825 1.47209 6.31861 1.46962 6.32929 1.46707C6.38212 1.45407 6.43443 1.43949 6.48673 1.42462C6.49623 1.42198 6.50573 1.41935 6.51552 1.41663C6.62182 1.38624 6.71356 1.34737 6.79854 1.27836C6.80647 1.27213 6.81439 1.26589 6.82255 1.25946C6.9548 1.14565 6.99974 0.974674 7.04053 0.815134C7.04364 0.803022 7.04675 0.79091 7.04995 0.778432C7.05614 0.754101 7.06222 0.729743 7.06817 0.705359C7.07243 0.688394 7.07243 0.688394 7.07678 0.671086C7.07927 0.660951 7.08175 0.650816 7.08431 0.640373C7.09521 0.608108 7.10952 0.582772 7.12957 0.554859C7.1681 0.536435 7.19515 0.544764 7.23597 0.554859Z\" fill=\"#075F3F\"/>\n <path d=\"M1.79545 6.2471C1.80951 6.24719 1.80951 6.24719 1.82386 6.24729C1.92477 6.25022 1.99304 6.28115 2.06736 6.34601C2.15384 6.43533 2.19377 6.53611 2.1915 6.6565C2.18178 6.75412 2.12158 6.83935 2.04773 6.90533C1.96081 6.97242 1.87313 6.99459 1.76206 6.99149C1.66841 6.98107 1.5803 6.93852 1.51393 6.87451C1.43138 6.76681 1.40725 6.66803 1.41935 6.53537C1.44433 6.43092 1.51637 6.34613 1.6085 6.28666C1.67251 6.25564 1.72399 6.24652 1.79545 6.2471Z\" fill=\"#0DBD7D\"/>\n </svg>\n Self-healed\n </span>\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-rounded-[4px] cqa-py-0.5 cqa-px-1 cqa-bg-[#6366F11A] cqa-ml-1 cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity\" \n *ngIf=\"step?.executedResult?.video_start_time\" \n [matTooltip]=\"'Jump to video time'\" \n matTooltipPosition=\"below\"\n (click)=\"onJumpToTimestamp($event)\">\n <mat-icon class=\"cqa-text-[#636363] !cqa-text-[10px] !cqa-w-[10px] !cqa-h-[10px]\">\n play_arrow\n </mat-icon>\n <span class=\"cqa-text-[8px] cqa-leading-[12px] cqa-font-normal cqa-text-[#636363]\">\n {{ formatDurationClock(step?.executedResult?.video_start_time || 0) }}\n </span>\n </div>\n <div *ngIf=\"isDebug\" class=\"cqa-flex cqa-items-center cqa-gap-0.5 cqa-text-[#9CA3AF]\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Edit\" (click)=\"onEditStep($event)\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">edit</mat-icon>\n </button>\n <button type=\"button\" #addStepMenuTrigger=\"matMenuTrigger\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Add\" [matMenuTriggerFor]=\"addStepMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">add</mat-icon>\n </button>\n <mat-menu #addStepMenu=\"matMenu\" class=\"cqa-add-step-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of addStepMenuOptions\" (click)=\"onAddStepOptionSelect(opt, $event)\">\n {{ opt.label }}\n </button>\n </mat-menu>\n <button type=\"button\" #stepMoreMenuTrigger=\"matMenuTrigger\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"More options\" [matMenuTriggerFor]=\"stepMoreMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">more_vert</mat-icon>\n </button>\n <mat-menu #stepMoreMenu=\"matMenu\" class=\"cqa-step-more-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of stepMoreMenuOptions\" (click)=\"onStepMoreOptionSelect(opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n </div>\n <span class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF]\">\n {{ formatDuration(config.duration) }}\n </span>\n <svg [class.cqa-rotate-180]=\"isExpanded\" class=\"cqa-transition-transform\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M3.5 5L7 8.5L10.5 5\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n </div>\n\n <!-- Expanded Content -->\n <div *ngIf=\"isExpanded\">\n <!-- Iteration Selector -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-px-4 cqa-py-2 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#737373]\" *ngIf=\"!isLive || (isLive && config?.iterations !== undefined)\">\n <label>Iteration</label>\n <div class=\"cqa-relative cqa-w-full cqa-max-w-[156px]\">\n <!-- Status indicator for selected iteration -->\n <div *ngIf=\"selectedIteration && config?.iterations && config?.iterations?.length > 0\" class=\"cqa-absolute cqa-left-[10px] cqa-top-1/2 cqa-transform cqa--translate-y-1/2 cqa-pointer-events-none cqa-z-10\">\n <svg *ngIf=\"selectedIteration.status === 'success'\" width=\"6\" height=\"6\" viewBox=\"0 0 6 6\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"3\" cy=\"3\" r=\"3\" fill=\"#00A63E\"/></svg>\n <svg *ngIf=\"selectedIteration.status === 'failed'\" width=\"6\" height=\"6\" viewBox=\"0 0 6 6\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"3\" cy=\"3\" r=\"3\" fill=\"#EF4444\"/></svg>\n <svg *ngIf=\"selectedIteration.status === 'pending'\" width=\"6\" height=\"6\" viewBox=\"0 0 6 6\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"3\" cy=\"3\" r=\"3\" fill=\"#9CA3AF\"/></svg>\n <svg *ngIf=\"selectedIteration.status === 'running'\" width=\"6\" height=\"6\" viewBox=\"0 0 6 6\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"3\" cy=\"3\" r=\"3\" fill=\"#3B82F6\"/></svg>\n </div>\n <select\n class=\"cqa-pl-[22px] cqa-pr-6 cqa-py-[5px] cqa-w-full cqa-border cqa-border-[#E5E5E5] cqa-rounded-md cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-[#FAFAFA] cqa-text-black-100 cqa-appearance-none\"\n [(ngModel)]=\"selectedIteration\"\n (ngModelChange)=\"handleIterationChange($event)\"\n [compareWith]=\"compareIteration\"\n [disabled]=\"(isLive && (status === 'running' || status === 'RUNNING'))\">\n <option *ngIf=\"!config?.iterations || config?.iterations?.length === 0\" value=\"\" disabled>\n No iterations available\n </option>\n <option *ngFor=\"let iteration of config.iterations\" [ngValue]=\"iteration\">\n {{ getIterationLabel(iteration) }}\n </option>\n </select>\n <!-- Dropdown arrow -->\n <div class=\"cqa-absolute cqa-right-2 cqa-top-1/2 cqa-transform cqa--translate-y-1/2 cqa-pointer-events-none\">\n <svg width=\"10\" height=\"6\" viewBox=\"0 0 10 6\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M1 1L5 5L9 1\" stroke=\"#9CA3AF\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n </div>\n <span class=\"cqa-ml-auto\" *ngIf=\"config?.iterations && config?.iterations?.length > 0\">\n Default: {{ config.defaultIteration === 'last' ? 'last iteration' : 'first iteration' }}\n </span>\n </div>\n\n <!-- Selected Iteration Sub-steps -->\n <div *ngIf=\"selectedIteration && selectedIteration.subSteps\" class=\"cqa-flex cqa-flex-col cqa-gap-1 cqa-py-1 cqa-ml-9\" style=\"border-bottom: '1px solid #F3F4F6'\">\n <div\n *ngFor=\"let subStep of selectedIteration.subSteps\"\n class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-py-[5.5px] cqa-px-3\">\n \n <!-- Sub-step Status Icon -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'success' || subStep?.status?.toLowerCase() === 'passed'\" >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Failure -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'failure' || subStep?.status?.toLowerCase() === 'failed'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7.5 4.5L4.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 4.5L7.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Pending -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'pending'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Running - Show spinner -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'running'\">\n <svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n </div>\n\n <div class=\"cqa-flex cqa-items-center\" *ngIf=\"subStep?.status?.toLowerCase() === 'skipped'\">\n <span class=\"material-symbols-outlined cqa-text-[#9CA3AF] cqa-text-[12px]\">\n skip_next\n </span>\n </div>\n\n <!-- Sub-step Description -->\n <span class=\"cqa-flex-1 cqa-text-[13px] cqa-leading-[15px] cqa-text-[#364153]\" style=\"white-space: pre-line; word-break: break-word;\">\n {{ subStep.description }}\n </span>\n\n <!-- Sub-step Duration -->\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-metadata-key\">\n {{ formatDuration(subStep.duration) }}\n </span>\n </div>\n </div>\n\n <!-- Nested Steps -->\n <div *ngIf=\"hasChild || (config.nestedSteps && config.nestedSteps.length > 0)\" class=\"cqa-ml-9 cqa-pb-1 cqa-nested-steps-container\" style=\"border-bottom: '1px solid #F3F4F6'\">\n <div class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#737373] cqa-py-[2px] cqa-px-3\">Nested steps</div>\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2 cqa-pl-[18px]\" style=\"border-left: 2px solid #C5C7FA;\">\n <!-- Loading indicator when nested steps are being loaded -->\n <div *ngIf=\"hasChild && (!config.nestedSteps || config.nestedSteps.length === 0) && isStepLoading()\" \n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-py-2 cqa-px-3\">\n <svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M7 1A6 6 0 0 1 13 7\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n <span class=\"cqa-text-[11px] cqa-leading-[13px] cqa-text-[#737373]\">Loading nested steps...</span>\n </div>\n <ng-container *ngFor=\"let step of config.nestedSteps; index as i\">\n <!-- Wrapper to show skeleton while step-renderer is loading -->\n <div\n class=\"cqa-step-renderer-wrapper\"\n [attr.id]=\"'exc-' + step.id\"\n [class.loaded]=\"!isNestedStepLoading(step)\">\n <!-- Loading skeleton overlay -->\n <!-- <div *ngIf=\"isNestedStepLoading(step)\" class=\"cqa-step-skeleton-overlay\">\n <div class=\"cqa-step-skeleton cqa-mx-3 cqa-my-1\"></div>\n </div> -->\n <!-- Use step-renderer for all nested steps to avoid circular dependencies -->\n <!-- The step-renderer will dynamically load the appropriate component and pass handlers -->\n <cqa-step-renderer \n [step]=\"step\"\n [stepNumber]=\"stepNumber + '.' + (i + 1)\"\n [onExpandHandler]=\"onExpandHandler\"\n [getConditionBranchesHandler]=\"getConditionBranchesHandler\"\n [onConditionBranchClickHandler]=\"onConditionBranchClickHandler\"\n [isStepLoadingHandler]=\"isStepLoadingHandler\"\n [isStepExpandedHandler]=\"isStepExpandedHandler\"\n [convertMsToSecondsHandler]=\"convertMsToSecondsHandler\"\n [formatFailureDetailsHandler]=\"formatFailureDetailsHandler\"\n [getSelfHealAnalysisHandler]=\"getSelfHealAnalysisHandler\"\n [getLoopIterationsHandler]=\"getLoopIterationsHandler\"\n [getApiAssertionsHandler]=\"getApiAssertionsHandler\"\n [formatActionsHandler]=\"formatActionsHandler\"\n [onViewAllIterationsHandler]=\"onViewAllIterationsHandler\"\n [onMakeCurrentBaselineHandler]=\"onMakeCurrentBaselineHandler\"\n [onUploadBaselineHandler]=\"onUploadBaselineHandler\"\n [getSelfHealLoadingStatesHandler]=\"getSelfHealLoadingStatesHandler\"\n [onAnalyzeHandler]=\"onAnalyzeHandler\"\n [onViewFullLogsHandler]=\"onViewFullLogsHandler\"\n [onSelfHealActionHandler]=\"onSelfHealActionHandler\"\n [onStepClickHandler]=\"onStepClickHandler\"\n [onJsonPathCopiedHandler]=\"onJsonPathCopiedHandler\"\n [onDownloadHandler]=\"onDownloadHandler\"\n [onFilePathCopiedHandler]=\"onFilePathCopiedHandler\"\n [onTextCopiedHandler]=\"onTextCopiedHandler\"\n [jumpToTimestampHandler]=\"jumpToTimestampHandler\"\n [downloadingStepId]=\"downloadingStepId\"\n [isUploadingBaseline]=\"isUploadingBaseline\"\n [isMakingCurrentBaseline]=\"isMakingCurrentBaseline\"\n [selectedIterationId]=\"step?.selectedIterationId || ''\"\n [isLive]=\"isLive\"\n [isDebug]=\"isDebug\"\n [debugPointSet]=\"getDebugPointSetHandler ? getDebugPointSetHandler(step) : debugPointSet\"\n [getDebugPointSetHandler]=\"getDebugPointSetHandler\"\n [onDebugPointChangeHandler]=\"onDebugPointChangeHandler\"\n [onEditStepHandler]=\"onEditStepHandler\"\n [addStepMenuOptions]=\"getAddStepMenuOptionsForNested ? getAddStepMenuOptionsForNested(step) : addStepMenuOptions\"\n [onAddStepOptionSelectHandler]=\"onAddStepOptionSelectHandler\"\n [stepMoreMenuOptions]=\"getStepMoreMenuOptionsForNested ? getStepMoreMenuOptionsForNested(step) : stepMoreMenuOptions\"\n [onStepMoreOptionSelectHandler]=\"onStepMoreOptionSelectHandler\"\n [getAddStepMenuOptionsForNested]=\"getAddStepMenuOptionsForNested\"\n [getStepMoreMenuOptionsForNested]=\"getStepMoreMenuOptionsForNested\"\n (componentReady)=\"markStepLoaded(step)\">\n </cqa-step-renderer>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- View All Iterations Link -->\n <div *ngIf=\"config.showViewAllIterations && !isLive\" class=\"cqa-flex cqa-justify-end cqa-px-3 cqa-py-[10px]\">\n <a href=\"#\" (click)=\"onViewAllIterationsClick($event)\" class=\"cqa-text-[10px] cqa-leading-[15px] cqa-no-underline cqa-text-primary cqa-font-semibold cqa-flex cqa-items-center cqa-gap-1\">\n View all iterations\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M7.63636 11.267L6.75852 10.3977L9.38778 7.76847H3V6.49858H9.38778L6.75852 3.87358L7.63636 3L11.7699 7.13352L7.63636 11.267Z\" fill=\"#3F43EE\"/></svg>\n </a>\n </div>\n\n <!-- Self Heal Analysis -->\n <cqa-self-heal-analysis \n *ngIf=\"selfHealAnalysis\"\n [id]=\"step?.testStepId\"\n [originalLocator]=\"selfHealAnalysis.originalLocator\"\n [healedLocator]=\"selfHealAnalysis.healedLocator\"\n [confidence]=\"selfHealAnalysis.confidence\"\n [healMethod]=\"selfHealAnalysis.healMethod\"\n [isLoadingAccept]=\"getSelfHealLoadingStatesHandler ? getSelfHealLoadingStatesHandler().isLoadingAccept?.[step?.testStepId] : false\"\n [isLoadingModifyAccept]=\"getSelfHealLoadingStatesHandler ? getSelfHealLoadingStatesHandler().isLoadingModifyAccept?.[step?.testStepId] : false\"\n (action)=\"onSelfHealAction($event)\">\n </cqa-self-heal-analysis>\n\n <!-- Timing Breakdown -->\n <div *ngIf=\"config.timingBreakdown\" class=\"cqa-flex cqa-items-center cqa-justify-end cqa-gap-5 cqa-pt-1.5 cqa-px-4 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF]\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <span>Timing breakdown</span>\n </div>\n <span class=\"cqa-text-dialog-muted cqa-flex cqa-items-center cqa-gap-3\">\n <div>\n App <span class=\"cqa-text-gray-700\">{{ formatDuration(config.timingBreakdown.app) }}</span>\n </div>\n <div><svg width=\"1\" height=\"11\" viewBox=\"0 0 1 11\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M-3.8147e-06 10.32V-7.15256e-07H0.959996V10.32H-3.8147e-06Z\" fill=\"#E5E7EB\"/></svg></div>\n <div>\n Tool <span class=\"cqa-text-gray-700\">{{ formatDuration(config.timingBreakdown.tool) }}</span>\n </div>\n </span>\n </div>\n </div>\n\n <!-- View More Failed Step Button - shown when expanded and failure details exist -->\n <div *ngIf=\"showViewMoreButton\" class=\"cqa-mt-2 cqa-px-4\">\n <cqa-view-more-failed-step-button\n [timingBreakdown]=\"timingBreakdown\"\n [subSteps]=\"getSubStepsForFailedStep()\"\n [failureDetails]=\"failureDetails\"\n [isExpanded]=\"showFailedStepDetails\"\n (viewMoreClick)=\"onViewMoreFailedStepClick($event)\">\n </cqa-view-more-failed-step-button>\n </div>\n\n <!-- Updated Failed Step Component - shown when button is clicked -->\n <div *ngIf=\"showViewMoreButton &&showFailedStepDetails && failureDetails\" class=\"cqa-mt-2 cqa-px-4\">\n <cqa-updated-failed-step\n [testStepResultId]=\"testStepResultId\"\n [timingBreakdown]=\"timingBreakdown\"\n [expanded]=\"true\"\n [subSteps]=\"getSubStepsForFailedStep()\"\n [failureDetails]=\"failureDetails\"\n [reasoning]=\"reasoning\"\n [confidence]=\"confidence\"\n [isUploadingBaseline]=\"isUploadingBaseline\"\n [isMakingCurrentBaseline]=\"isMakingCurrentBaseline\"\n [isLive]=\"isLive\"\n (makeCurrentBaseline)=\"onMakeCurrentBaseline($event)\"\n (uploadBaseline)=\"onUploadBaseline($event)\"\n (analyze)=\"onAnalyze()\"\n (viewFullLogs)=\"onViewFullLogs()\">\n </cqa-updated-failed-step>\n </div>\n</div>\n", components: [{ type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i2$1.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { type: i2$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { type: StepRendererComponent, selector: "cqa-step-renderer", inputs: ["step", "onExpandHandler", "getConditionBranchesHandler", "isStepLoadingHandler", "isStepExpandedHandler", "convertMsToSecondsHandler", "formatFailureDetailsHandler", "getSelfHealAnalysisHandler", "onMakeCurrentBaselineHandler", "onUploadBaselineHandler", "onAnalyzeHandler", "onViewFullLogsHandler", "onSelfHealActionHandler", "getSelfHealLoadingStatesHandler", "isUploadingBaseline", "isMakingCurrentBaseline", "selectedIterationId", "getLoopIterationsHandler", "getApiAssertionsHandler", "formatActionsHandler", "onViewAllIterationsHandler", "onConditionBranchClickHandler", "onStepClickHandler", "onJsonPathCopiedHandler", "onDownloadHandler", "onFilePathCopiedHandler", "onTextCopiedHandler", "jumpToTimestampHandler", "downloadingStepId", "isLive", "isDebug", "debugPointSet", "getDebugPointSetHandler", "onDebugPointChangeHandler", "onEditStepHandler", "addStepMenuOptions", "onAddStepOptionSelectHandler", "stepMoreMenuOptions", "onStepMoreOptionSelectHandler", "getAddStepMenuOptionsForNested", "getStepMoreMenuOptionsForNested", "stepNumber"], outputs: ["addStepOptionSelect", "stepMoreOptionSelect", "componentReady"] }, { type: SelfHealAnalysisComponent, selector: "cqa-self-heal-analysis", inputs: ["id", "originalLocator", "healedLocator", "confidence", "healMethod", "isLoadingAccept", "isLoadingModifyAccept"], outputs: ["action"] }, { type: ViewMoreFailedStepButtonComponent, selector: "cqa-view-more-failed-step-button", inputs: ["timingBreakdown", "subSteps", "failureDetails", "isExpanded"], outputs: ["viewMoreClick"] }, { type: UpdatedFailedStepComponent, selector: "cqa-updated-failed-step", inputs: ["timingBreakdown", "testStepResultId", "expanded", "subSteps", "failureDetails", "reasoning", "confidence", "isUploadingBaseline", "isMakingCurrentBaseline", "isLive"], outputs: ["makeCurrentBaseline", "uploadBaseline", "analyze", "viewFullLogs"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { type: i2$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }] });
|
|
10718
|
+
LoopStepComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: LoopStepComponent, selector: "cqa-loop-step", inputs: { id: "id", testStepResultId: "testStepResultId", stepNumber: "stepNumber", title: "title", status: "status", duration: "duration", timingBreakdown: "timingBreakdown", expanded: "expanded", loopType: "loopType", iterations: "iterations", selectedIterationId: "selectedIterationId", defaultIteration: "defaultIteration", nestedSteps: "nestedSteps", showViewAllIterations: "showViewAllIterations", hasChild: "hasChild", isLive: "isLive", isLoading: "isLoading", stepDeleted: "stepDeleted", isDebug: "isDebug", debugPointSet: "debugPointSet", getDebugPointSetHandler: "getDebugPointSetHandler", onDebugPointChangeHandler: "onDebugPointChangeHandler", addStepMenuOptions: "addStepMenuOptions", stepMoreMenuOptions: "stepMoreMenuOptions", onExpandHandler: "onExpandHandler", onEditStepHandler: "onEditStepHandler", onAddStepOptionSelectHandler: "onAddStepOptionSelectHandler", onStepMoreOptionSelectHandler: "onStepMoreOptionSelectHandler", getAddStepMenuOptionsForNested: "getAddStepMenuOptionsForNested", getStepMoreMenuOptionsForNested: "getStepMoreMenuOptionsForNested", getConditionBranchesHandler: "getConditionBranchesHandler", onConditionBranchClickHandler: "onConditionBranchClickHandler", isStepLoadingHandler: "isStepLoadingHandler", isStepExpandedHandler: "isStepExpandedHandler", convertMsToSecondsHandler: "convertMsToSecondsHandler", formatFailureDetailsHandler: "formatFailureDetailsHandler", getSelfHealAnalysisHandler: "getSelfHealAnalysisHandler", onMakeCurrentBaselineHandler: "onMakeCurrentBaselineHandler", onUploadBaselineHandler: "onUploadBaselineHandler", onAnalyzeHandler: "onAnalyzeHandler", onViewFullLogsHandler: "onViewFullLogsHandler", onSelfHealActionHandler: "onSelfHealActionHandler", getSelfHealLoadingStatesHandler: "getSelfHealLoadingStatesHandler", getLoopIterationsHandler: "getLoopIterationsHandler", getApiAssertionsHandler: "getApiAssertionsHandler", formatActionsHandler: "formatActionsHandler", onViewAllIterationsHandler: "onViewAllIterationsHandler", onStepClickHandler: "onStepClickHandler", onJsonPathCopiedHandler: "onJsonPathCopiedHandler", onDownloadHandler: "onDownloadHandler", onFilePathCopiedHandler: "onFilePathCopiedHandler", onTextCopiedHandler: "onTextCopiedHandler", jumpToTimestampHandler: "jumpToTimestampHandler", downloadingStepId: "downloadingStepId", step: "step", failureDetails: "failureDetails", reasoning: "reasoning", confidence: "confidence", isUploadingBaseline: "isUploadingBaseline", isMakingCurrentBaseline: "isMakingCurrentBaseline", selfHealAnalysis: "selfHealAnalysis", iterationData: "iterationData" }, outputs: { debugPointChange: "debugPointChange", editStep: "editStep", addStepOptionSelect: "addStepOptionSelect", stepMoreOptionSelect: "stepMoreOptionSelect", makeCurrentBaseline: "makeCurrentBaseline", uploadBaseline: "uploadBaseline", analyze: "analyze", viewFullLogs: "viewFullLogs", selfHealAction: "selfHealAction", onExpand: "onExpand", onViewAllIterations: "onViewAllIterations", onIterationChange: "onIterationChange" }, host: { classAttribute: "cqa-ui-root" }, viewQueries: [{ propertyName: "addStepMenuTrigger", first: true, predicate: ["addStepMenuTrigger"], descendants: true }, { propertyName: "stepMoreMenuTrigger", first: true, predicate: ["stepMoreMenuTrigger"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-font-inter\" (click)=\"$event.stopPropagation()\">\n <!-- Header -->\n <div\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-p-2 cqa-cursor-pointer\"\n (click)=\"toggleHeader($event)\">\n <div *ngIf=\"showDebugIcon\" class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer cqa-rounded-full hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" (click)=\"onDebugPointClick($event)\" [attr.aria-label]=\"debugPointSet ? 'Remove debug point' : 'Set debug point'\">\n <svg *ngIf=\"debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" fill=\"#C63535\"/>\n </svg>\n <svg *ngIf=\"!debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" stroke=\"#C63535\" stroke-width=\"1.5\" fill=\"none\"/>\n </svg>\n </button>\n </div>\n <!-- Status Icon -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <!-- Success -->\n <svg *ngIf=\"status.toLowerCase() === 'success'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <!-- Failed -->\n <svg *ngIf=\"status.toLowerCase() === 'failure' || status.toLowerCase() === 'failed'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4 4L8 8M8 4L4 8\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <!-- Pending -->\n <svg *ngIf=\"status.toLowerCase() === 'pending'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <!-- Running -->\n <svg *ngIf=\"status.toLowerCase() === 'running'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#3B82F6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#3B82F6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n \n <span *ngIf=\"status.toLowerCase() === 'skipped'\" class=\"material-symbols-outlined cqa-text-[#9CA3AF] cqa-text-[12px]\">\n skip_next\n </span>\n </div>\n\n <!-- Loop Icon -->\n <div><svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"16\" height=\"16\" rx=\"4\" fill=\"#EBECFD\"/><path d=\"M9.66663 4.66666L11 5.99999L9.66663 7.33332\" stroke=\"#3F43EE\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M5 7.66667V7.33333C5 6.97971 5.14048 6.64057 5.39052 6.39052C5.64057 6.14048 5.97971 6 6.33333 6H11\" stroke=\"#3F43EE\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6.33333 11.3333L5 9.99999L6.33333 8.66666\" stroke=\"#3F43EE\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M11 8.33334V8.66668C11 9.0203 10.8595 9.35944 10.6095 9.60949C10.3594 9.85953 10.0203 10 9.66667 10H5\" stroke=\"#3F43EE\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n\n <!-- Step Number and Title -->\n <div class=\"cqa-flex-1 cqa-flex cqa-items-center cqa-gap-3 cqa-font-inter\">\n <span class=\"cqa-font-semibold cqa-text-[#334155] cqa-text-[14px] cqa-leading-[18px]\" style=\"word-break: break-word;\">\n {{ config?.stepNumber }}. <span [innerHTML]=\"config?.title\"></span>\n </span>\n \n <!-- Loop Type Badges -->\n <span *ngFor=\"let badge of getLoopTypeBadges()\" \n class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-primary cqa-bg-[#EBECFD] cqa-text-[10px] cqa-leading-[15px]\">\n {{ badge }}\n </span>\n <span *ngIf=\"config.stepDeleted\" class=\"cqa-px-1.5 cqa-py-[2px] cqa-rounded-[4px] cqa-text-[10px] cqa-leading-[12px] cqa-font-medium cqa-text-[#B42318] cqa-bg-[#FEF3F2] cqa-border cqa-border-[#FEE4E2]\">\n Deleted\n </span>\n </div>\n\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-font-inter\">\n <span *ngIf=\"selfHealAnalysis\" class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-[#097E53] cqa-bg-[#CFF2E5] cqa-text-[10px] cqa-leading-[15px] cqa-min-w-max cqa-flex cqa-items-center cqa-gap-[6px]\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"9\" height=\"9\" viewBox=\"0 0 9 9\" fill=\"none\">\n <path d=\"M4.50941 0C4.56489 0.0227384 4.58859 0.0782652 4.61131 0.129846C4.62269 0.1599 4.63314 0.190117 4.64329 0.220575C4.64726 0.232247 4.65123 0.243918 4.65532 0.255943C4.70806 0.413005 4.75504 0.571748 4.80229 0.73038C4.81297 0.76619 4.82369 0.801987 4.83442 0.837783C4.88905 1.02004 4.94327 1.2024 4.99719 1.38484C5.00476 1.41047 5.01234 1.43609 5.01992 1.46171C5.04128 1.53395 5.06262 1.60619 5.08383 1.67847C5.12867 1.8312 5.17473 1.98347 5.22378 2.13501C5.22807 2.14827 5.23236 2.16152 5.23677 2.17518C5.3642 2.565 5.54482 2.91437 5.8409 3.21196C5.84823 3.2197 5.85556 3.22744 5.86312 3.23541C5.9895 3.36437 6.15169 3.46771 6.3138 3.55111C6.32206 3.55542 6.33031 3.55974 6.33882 3.56419C6.81587 3.80925 7.38951 3.91704 7.90619 4.0605C8.1326 4.1234 8.3583 4.18829 8.58317 4.25603C8.59897 4.26079 8.61478 4.26554 8.63058 4.27028C8.67784 4.28445 8.725 4.29887 8.77211 4.31347C8.7831 4.31679 8.79408 4.32011 8.80539 4.32353C8.87029 4.34406 8.93239 4.36829 8.98566 4.41027C9.00191 4.44418 9.00191 4.44418 8.99748 4.4781C8.94564 4.52736 8.8942 4.55046 8.82578 4.573C8.816 4.57632 8.80622 4.57965 8.79614 4.58308C8.68061 4.62183 8.56351 4.65575 8.44626 4.68935C8.4222 4.6963 8.39814 4.70326 8.37408 4.71021C8.22571 4.75301 8.07708 4.7949 7.92829 4.83632C7.73232 4.89088 7.53663 4.94634 7.34113 5.00243C7.3091 5.01162 7.27706 5.02078 7.24501 5.02991C7.07671 5.07786 6.90923 5.12753 6.74314 5.18208C6.72937 5.18659 6.71559 5.1911 6.70139 5.19574C6.14511 5.38082 5.7211 5.72609 5.45571 6.23099C5.31263 6.51475 5.22823 6.82161 5.14214 7.12447C5.11884 7.20619 5.09409 7.28745 5.06905 7.36869C5.0494 7.43261 5.0302 7.49663 5.01149 7.56081C5.00926 7.56844 5.00703 7.57608 5.00473 7.58395C4.99394 7.62094 4.98319 7.65793 4.97252 7.69495C4.94519 7.78879 4.91578 7.88187 4.88555 7.97489C4.83191 8.14021 4.7831 8.30674 4.73459 8.4735C4.66144 8.72457 4.66144 8.72457 4.61997 8.84527C4.61721 8.85337 4.61446 8.86147 4.61163 8.86982C4.59649 8.91278 4.58092 8.95233 4.55226 8.9887C4.50867 8.99788 4.50867 8.99788 4.46951 9C4.42473 8.93759 4.39508 8.87711 4.37133 8.80508C4.36787 8.79487 4.36441 8.78466 4.36085 8.77415C4.31684 8.64248 4.27751 8.50946 4.23817 8.37646C4.22916 8.34604 4.22011 8.31564 4.21105 8.28524C4.1436 8.05863 4.07725 7.83174 4.01101 7.60481C3.73507 6.48224 3.73507 6.48224 3.039 5.57466C3.02784 5.56596 3.01669 5.55726 3.00519 5.5483C2.54913 5.19902 1.94834 5.06969 1.39815 4.91813C1.26207 4.88062 1.12605 4.84293 0.990032 4.80523C0.978138 4.80193 0.978138 4.80193 0.966003 4.79857C0.769811 4.74417 0.573674 4.68963 0.378224 4.63283C0.369956 4.63045 0.361688 4.62806 0.353169 4.62561C0.0528989 4.53883 0.0528989 4.53883 0.000646537 4.4781C-0.000831261 4.45054 -0.000831261 4.45054 0.0124689 4.42157C0.0670835 4.3704 0.120077 4.34848 0.19216 4.32619C0.202597 4.32284 0.213034 4.31948 0.223787 4.31603C0.255753 4.30582 0.287788 4.29584 0.319851 4.28592C0.329001 4.28305 0.338151 4.28017 0.347578 4.27722C0.412285 4.25693 0.477225 4.2374 0.542259 4.21809C0.55824 4.21332 0.55824 4.21332 0.574544 4.20846C0.852269 4.12587 1.13181 4.049 1.41126 3.97196C1.6195 3.91455 1.82738 3.85618 2.0346 3.79548C2.04413 3.79271 2.05365 3.78993 2.06346 3.78707C2.5435 3.64696 3.01278 3.44816 3.32274 3.0537C3.32738 3.04785 3.33202 3.042 3.3368 3.03597C3.68197 2.59815 3.81658 2.06572 3.96695 1.54621C4.01643 1.37534 4.06649 1.20464 4.11673 1.03399C4.13064 0.986733 4.14453 0.939471 4.15836 0.892194C4.21394 0.702289 4.27035 0.512642 4.33 0.323864C4.33558 0.306186 4.34114 0.288501 4.34666 0.270807C4.43017 0.00398761 4.43017 0.00398761 4.50941 0Z\" fill=\"#0DBD7D\"/>\n <path d=\"M7.23597 0.554859C7.29024 0.613599 7.30109 0.682631 7.31799 0.757638C7.37436 0.993269 7.43929 1.20993 7.66467 1.34681C7.80371 1.42035 7.96944 1.45381 8.1235 1.48541C8.18854 1.49902 8.24348 1.51709 8.29924 1.55321C8.31181 1.57229 8.31181 1.57229 8.31107 1.60549C8.29814 1.64588 8.28678 1.6589 8.25269 1.68533C8.21543 1.69726 8.21543 1.69726 8.17068 1.70653C8.15375 1.71025 8.13683 1.714 8.11992 1.71779C8.11086 1.7198 8.10181 1.72181 8.09247 1.72388C7.81696 1.78482 7.81696 1.78482 7.57882 1.92273C7.57108 1.92869 7.56333 1.93466 7.55536 1.9408C7.38516 2.08431 7.34916 2.32303 7.29793 2.52301C7.29499 2.53399 7.29206 2.54497 7.28903 2.55629C7.28649 2.56601 7.28395 2.57573 7.28133 2.58575C7.27028 2.61544 7.25881 2.63479 7.23597 2.65754C7.17234 2.66527 7.17234 2.66527 7.14139 2.65754C7.09216 2.62106 7.08114 2.5795 7.06828 2.52365C7.06613 2.51501 7.06398 2.50636 7.06176 2.49745C7.05489 2.46983 7.04824 2.44217 7.04164 2.41449C6.98979 2.19897 6.93126 1.98751 6.72451 1.86118C6.56293 1.77501 6.36646 1.73426 6.18587 1.70136C6.13637 1.69151 6.10802 1.67911 6.07738 1.64012C6.07073 1.60055 6.07073 1.60055 6.07738 1.56098C6.12447 1.51437 6.17402 1.50299 6.23772 1.48891C6.25778 1.48416 6.27784 1.47938 6.29789 1.47456C6.30825 1.47209 6.31861 1.46962 6.32929 1.46707C6.38212 1.45407 6.43443 1.43949 6.48673 1.42462C6.49623 1.42198 6.50573 1.41935 6.51552 1.41663C6.62182 1.38624 6.71356 1.34737 6.79854 1.27836C6.80647 1.27213 6.81439 1.26589 6.82255 1.25946C6.9548 1.14565 6.99974 0.974674 7.04053 0.815134C7.04364 0.803022 7.04675 0.79091 7.04995 0.778432C7.05614 0.754101 7.06222 0.729743 7.06817 0.705359C7.07243 0.688394 7.07243 0.688394 7.07678 0.671086C7.07927 0.660951 7.08175 0.650816 7.08431 0.640373C7.09521 0.608108 7.10952 0.582772 7.12957 0.554859C7.1681 0.536435 7.19515 0.544764 7.23597 0.554859Z\" fill=\"#075F3F\"/>\n <path d=\"M1.79545 6.2471C1.80951 6.24719 1.80951 6.24719 1.82386 6.24729C1.92477 6.25022 1.99304 6.28115 2.06736 6.34601C2.15384 6.43533 2.19377 6.53611 2.1915 6.6565C2.18178 6.75412 2.12158 6.83935 2.04773 6.90533C1.96081 6.97242 1.87313 6.99459 1.76206 6.99149C1.66841 6.98107 1.5803 6.93852 1.51393 6.87451C1.43138 6.76681 1.40725 6.66803 1.41935 6.53537C1.44433 6.43092 1.51637 6.34613 1.6085 6.28666C1.67251 6.25564 1.72399 6.24652 1.79545 6.2471Z\" fill=\"#0DBD7D\"/>\n </svg>\n Self-healed\n </span>\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-rounded-[4px] cqa-py-0.5 cqa-px-1 cqa-bg-[#6366F11A] cqa-ml-1 cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity\" \n *ngIf=\"step?.executedResult?.video_start_time\" \n [matTooltip]=\"'Jump to video time'\" \n matTooltipPosition=\"below\"\n (click)=\"onJumpToTimestamp($event)\">\n <mat-icon class=\"cqa-text-[#636363] !cqa-text-[10px] !cqa-w-[10px] !cqa-h-[10px]\">\n play_arrow\n </mat-icon>\n <span class=\"cqa-text-[8px] cqa-leading-[12px] cqa-font-normal cqa-text-[#636363]\">\n {{ formatDurationClock(step?.executedResult?.video_start_time || 0) }}\n </span>\n </div>\n <div *ngIf=\"isDebug\" class=\"cqa-flex cqa-items-center cqa-gap-0.5 cqa-text-[#9CA3AF]\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Edit\" (click)=\"onEditStep($event)\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">edit</mat-icon>\n </button>\n <button type=\"button\" #addStepMenuTrigger=\"matMenuTrigger\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Add\" [matMenuTriggerFor]=\"addStepMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">add</mat-icon>\n </button>\n <mat-menu #addStepMenu=\"matMenu\" class=\"cqa-add-step-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of addStepMenuOptions\" (click)=\"onAddStepOptionSelect(opt, $event)\">\n {{ opt.label }}\n </button>\n </mat-menu>\n <button type=\"button\" #stepMoreMenuTrigger=\"matMenuTrigger\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"More options\" [matMenuTriggerFor]=\"stepMoreMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">more_vert</mat-icon>\n </button>\n <mat-menu #stepMoreMenu=\"matMenu\" class=\"cqa-step-more-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of stepMoreMenuOptions\" (click)=\"onStepMoreOptionSelect(opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n </div>\n <span class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF]\">\n {{ formatDuration(config.duration) }}\n </span>\n <svg [class.cqa-rotate-180]=\"isExpanded\" class=\"cqa-transition-transform\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M3.5 5L7 8.5L10.5 5\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n </div>\n\n <!-- Expanded Content -->\n <div *ngIf=\"isExpanded\">\n <!-- Iteration Selector -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-px-4 cqa-py-2 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#737373]\" *ngIf=\"!isLive || (isLive && config?.iterations !== undefined)\">\n <label>Iteration</label>\n <div class=\"cqa-relative cqa-w-full cqa-max-w-[156px]\">\n <!-- Status indicator for selected iteration -->\n <div *ngIf=\"selectedIteration && config?.iterations && config?.iterations?.length > 0\" class=\"cqa-absolute cqa-left-[10px] cqa-top-1/2 cqa-transform cqa--translate-y-1/2 cqa-pointer-events-none cqa-z-10\">\n <svg *ngIf=\"selectedIteration.status === 'success'\" width=\"6\" height=\"6\" viewBox=\"0 0 6 6\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"3\" cy=\"3\" r=\"3\" fill=\"#00A63E\"/></svg>\n <svg *ngIf=\"selectedIteration.status === 'failed'\" width=\"6\" height=\"6\" viewBox=\"0 0 6 6\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"3\" cy=\"3\" r=\"3\" fill=\"#EF4444\"/></svg>\n <svg *ngIf=\"selectedIteration.status === 'pending'\" width=\"6\" height=\"6\" viewBox=\"0 0 6 6\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"3\" cy=\"3\" r=\"3\" fill=\"#9CA3AF\"/></svg>\n <svg *ngIf=\"selectedIteration.status === 'running'\" width=\"6\" height=\"6\" viewBox=\"0 0 6 6\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"3\" cy=\"3\" r=\"3\" fill=\"#3B82F6\"/></svg>\n </div>\n <select\n class=\"cqa-pl-[22px] cqa-pr-6 cqa-py-[5px] cqa-w-full cqa-border cqa-border-[#E5E5E5] cqa-rounded-md cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-[#FAFAFA] cqa-text-black-100 cqa-appearance-none\"\n [(ngModel)]=\"selectedIteration\"\n (ngModelChange)=\"handleIterationChange($event)\"\n [compareWith]=\"compareIteration\"\n [disabled]=\"(isLive && (status === 'running' || status === 'RUNNING'))\">\n <option *ngIf=\"!config?.iterations || config?.iterations?.length === 0\" value=\"\" disabled>\n No iterations available\n </option>\n <option *ngFor=\"let iteration of config.iterations\" [ngValue]=\"iteration\">\n {{ getIterationLabel(iteration) }}\n </option>\n </select>\n <!-- Dropdown arrow -->\n <div class=\"cqa-absolute cqa-right-2 cqa-top-1/2 cqa-transform cqa--translate-y-1/2 cqa-pointer-events-none\">\n <svg width=\"10\" height=\"6\" viewBox=\"0 0 10 6\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M1 1L5 5L9 1\" stroke=\"#9CA3AF\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n </div>\n <span class=\"cqa-ml-auto\" *ngIf=\"config?.iterations && config?.iterations?.length > 0\">\n Default: {{ config.defaultIteration === 'last' ? 'last iteration' : 'first iteration' }}\n </span>\n </div>\n\n <!-- Selected Iteration Sub-steps -->\n <div *ngIf=\"selectedIteration && selectedIteration.subSteps\" class=\"cqa-flex cqa-flex-col cqa-gap-1 cqa-py-1 cqa-ml-9\" style=\"border-bottom: '1px solid #F3F4F6'\">\n <!-- Single loop: render all entries in chronological order -->\n <ng-container *ngFor=\"let subStep of (isLive ? processedSubSteps : processedSubStepsForRunResult)\">\n <!-- AI_AUTO_HEAL_SUCCESS/FAILED: render with ai-agent-step style (both live and run result screens) -->\n <cqa-ai-logs-with-reasoning\n *ngIf=\"$any(subStep).isAiAutoHealResult\"\n [status]=\"subStep.status\"\n [text]=\"$any(subStep).text || subStep?.value\"\n [description]=\"$any(subStep).description || subStep?.text || subStep?.value\"\n [reasoning]=\"$any(subStep).reasoning || subStep?.reasoning\"\n [duration]=\"subStep.duration\">\n </cqa-ai-logs-with-reasoning>\n\n <!-- Regular sub-steps -->\n <div\n *ngIf=\"!$any(subStep).isAiAutoHealResult\"\n class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-py-[5.5px] cqa-px-3\">\n \n <!-- Sub-step Status Icon -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'success' || subStep?.status?.toLowerCase() === 'passed'\" >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Failure -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'failure' || subStep?.status?.toLowerCase() === 'failed'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7.5 4.5L4.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 4.5L7.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Pending -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'pending'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Running - Show spinner (also used for active WAIT_FOR_LOCATOR countdown in live mode) -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'running'\">\n <svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n </div>\n\n <div class=\"cqa-flex cqa-items-center\" *ngIf=\"subStep?.status?.toLowerCase() === 'skipped'\">\n <span class=\"material-symbols-outlined cqa-text-[#9CA3AF] cqa-text-[12px]\">\n skip_next\n </span>\n </div>\n\n <!-- Sub-step Description -->\n <span class=\"cqa-flex-1 cqa-text-[13px] cqa-leading-[15px] cqa-text-[#364153]\" style=\"white-space: pre-line; word-break: break-word;\">\n {{ $any(subStep).description || $any(subStep).text }}\n <!-- Countdown for active WAIT_FOR_LOCATOR in live mode -->\n <span *ngIf=\"isLive && $any(subStep).remainingSeconds != null\" class=\"cqa-text-[#F97316] cqa-font-medium cqa-ml-1\">({{ $any(subStep).remainingSeconds }}s remaining)</span>\n </span>\n\n <!-- Sub-step Duration -->\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-metadata-key\">\n {{ formatDuration(subStep.duration) }}\n </span>\n </div>\n </ng-container>\n </div>\n\n <!-- Nested Steps -->\n <div *ngIf=\"hasChild || (config.nestedSteps && config.nestedSteps.length > 0)\" class=\"cqa-ml-9 cqa-pb-1 cqa-nested-steps-container\" style=\"border-bottom: '1px solid #F3F4F6'\">\n <div class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#737373] cqa-py-[2px] cqa-px-3\">Nested steps</div>\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2 cqa-pl-[18px]\" style=\"border-left: 2px solid #C5C7FA;\">\n <!-- Loading indicator when nested steps are being loaded -->\n <div *ngIf=\"hasChild && (!config.nestedSteps || config.nestedSteps.length === 0) && isStepLoading()\" \n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-py-2 cqa-px-3\">\n <svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M7 1A6 6 0 0 1 13 7\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n <span class=\"cqa-text-[11px] cqa-leading-[13px] cqa-text-[#737373]\">Loading nested steps...</span>\n </div>\n <ng-container *ngFor=\"let step of config.nestedSteps; index as i\">\n <!-- Wrapper to show skeleton while step-renderer is loading -->\n <div\n class=\"cqa-step-renderer-wrapper\"\n [attr.id]=\"'exc-' + step.id\"\n [class.loaded]=\"!isNestedStepLoading(step)\">\n <!-- Loading skeleton overlay -->\n <!-- <div *ngIf=\"isNestedStepLoading(step)\" class=\"cqa-step-skeleton-overlay\">\n <div class=\"cqa-step-skeleton cqa-mx-3 cqa-my-1\"></div>\n </div> -->\n <!-- Use step-renderer for all nested steps to avoid circular dependencies -->\n <!-- The step-renderer will dynamically load the appropriate component and pass handlers -->\n <cqa-step-renderer \n [step]=\"step\"\n [stepNumber]=\"stepNumber + '.' + (i + 1)\"\n [onExpandHandler]=\"onExpandHandler\"\n [getConditionBranchesHandler]=\"getConditionBranchesHandler\"\n [onConditionBranchClickHandler]=\"onConditionBranchClickHandler\"\n [isStepLoadingHandler]=\"isStepLoadingHandler\"\n [isStepExpandedHandler]=\"isStepExpandedHandler\"\n [convertMsToSecondsHandler]=\"convertMsToSecondsHandler\"\n [formatFailureDetailsHandler]=\"formatFailureDetailsHandler\"\n [getSelfHealAnalysisHandler]=\"getSelfHealAnalysisHandler\"\n [getLoopIterationsHandler]=\"getLoopIterationsHandler\"\n [getApiAssertionsHandler]=\"getApiAssertionsHandler\"\n [formatActionsHandler]=\"formatActionsHandler\"\n [onViewAllIterationsHandler]=\"onViewAllIterationsHandler\"\n [onMakeCurrentBaselineHandler]=\"onMakeCurrentBaselineHandler\"\n [onUploadBaselineHandler]=\"onUploadBaselineHandler\"\n [getSelfHealLoadingStatesHandler]=\"getSelfHealLoadingStatesHandler\"\n [onAnalyzeHandler]=\"onAnalyzeHandler\"\n [onViewFullLogsHandler]=\"onViewFullLogsHandler\"\n [onSelfHealActionHandler]=\"onSelfHealActionHandler\"\n [onStepClickHandler]=\"onStepClickHandler\"\n [onJsonPathCopiedHandler]=\"onJsonPathCopiedHandler\"\n [onDownloadHandler]=\"onDownloadHandler\"\n [onFilePathCopiedHandler]=\"onFilePathCopiedHandler\"\n [onTextCopiedHandler]=\"onTextCopiedHandler\"\n [jumpToTimestampHandler]=\"jumpToTimestampHandler\"\n [downloadingStepId]=\"downloadingStepId\"\n [isUploadingBaseline]=\"isUploadingBaseline\"\n [isMakingCurrentBaseline]=\"isMakingCurrentBaseline\"\n [selectedIterationId]=\"step?.selectedIterationId || ''\"\n [isLive]=\"isLive\"\n [isDebug]=\"isDebug\"\n [debugPointSet]=\"getDebugPointSetHandler ? getDebugPointSetHandler(step) : debugPointSet\"\n [getDebugPointSetHandler]=\"getDebugPointSetHandler\"\n [onDebugPointChangeHandler]=\"onDebugPointChangeHandler\"\n [onEditStepHandler]=\"onEditStepHandler\"\n [addStepMenuOptions]=\"getAddStepMenuOptionsForNested ? getAddStepMenuOptionsForNested(step) : addStepMenuOptions\"\n [onAddStepOptionSelectHandler]=\"onAddStepOptionSelectHandler\"\n [stepMoreMenuOptions]=\"getStepMoreMenuOptionsForNested ? getStepMoreMenuOptionsForNested(step) : stepMoreMenuOptions\"\n [onStepMoreOptionSelectHandler]=\"onStepMoreOptionSelectHandler\"\n [getAddStepMenuOptionsForNested]=\"getAddStepMenuOptionsForNested\"\n [getStepMoreMenuOptionsForNested]=\"getStepMoreMenuOptionsForNested\"\n (componentReady)=\"markStepLoaded(step)\">\n </cqa-step-renderer>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- View All Iterations Link -->\n <div *ngIf=\"config.showViewAllIterations && !isLive\" class=\"cqa-flex cqa-justify-end cqa-px-3 cqa-py-[10px]\">\n <a href=\"#\" (click)=\"onViewAllIterationsClick($event)\" class=\"cqa-text-[10px] cqa-leading-[15px] cqa-no-underline cqa-text-primary cqa-font-semibold cqa-flex cqa-items-center cqa-gap-1\">\n View all iterations\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M7.63636 11.267L6.75852 10.3977L9.38778 7.76847H3V6.49858H9.38778L6.75852 3.87358L7.63636 3L11.7699 7.13352L7.63636 11.267Z\" fill=\"#3F43EE\"/></svg>\n </a>\n </div>\n\n <!-- Self Heal Analysis -->\n <cqa-self-heal-analysis \n *ngIf=\"selfHealAnalysis\"\n [id]=\"step?.testStepId\"\n [originalLocator]=\"selfHealAnalysis.originalLocator\"\n [healedLocator]=\"selfHealAnalysis.healedLocator\"\n [confidence]=\"selfHealAnalysis.confidence\"\n [healMethod]=\"selfHealAnalysis.healMethod\"\n [isLoadingAccept]=\"getSelfHealLoadingStatesHandler ? getSelfHealLoadingStatesHandler().isLoadingAccept?.[step?.testStepId] : false\"\n [isLoadingModifyAccept]=\"getSelfHealLoadingStatesHandler ? getSelfHealLoadingStatesHandler().isLoadingModifyAccept?.[step?.testStepId] : false\"\n (action)=\"onSelfHealAction($event)\">\n </cqa-self-heal-analysis>\n\n <!-- Timing Breakdown -->\n <div *ngIf=\"config.timingBreakdown\" class=\"cqa-flex cqa-items-center cqa-justify-end cqa-gap-5 cqa-pt-1.5 cqa-px-4 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF]\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <span>Timing breakdown</span>\n </div>\n <span class=\"cqa-text-dialog-muted cqa-flex cqa-items-center cqa-gap-3\">\n <div>\n App <span class=\"cqa-text-gray-700\">{{ formatDuration(config.timingBreakdown.app) }}</span>\n </div>\n <div><svg width=\"1\" height=\"11\" viewBox=\"0 0 1 11\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M-3.8147e-06 10.32V-7.15256e-07H0.959996V10.32H-3.8147e-06Z\" fill=\"#E5E7EB\"/></svg></div>\n <div>\n Tool <span class=\"cqa-text-gray-700\">{{ formatDuration(config.timingBreakdown.tool) }}</span>\n </div>\n </span>\n </div>\n </div>\n\n <!-- View More Failed Step Button - shown when expanded and failure details exist -->\n <div *ngIf=\"showViewMoreButton\" class=\"cqa-mt-2 cqa-px-4\">\n <cqa-view-more-failed-step-button\n [timingBreakdown]=\"timingBreakdown\"\n [subSteps]=\"getSubStepsForFailedStep()\"\n [failureDetails]=\"failureDetails\"\n [isExpanded]=\"showFailedStepDetails\"\n (viewMoreClick)=\"onViewMoreFailedStepClick($event)\">\n </cqa-view-more-failed-step-button>\n </div>\n\n <!-- Updated Failed Step Component - shown when button is clicked -->\n <div *ngIf=\"showViewMoreButton &&showFailedStepDetails && failureDetails\" class=\"cqa-mt-2 cqa-px-4\">\n <cqa-updated-failed-step\n [testStepResultId]=\"testStepResultId\"\n [timingBreakdown]=\"timingBreakdown\"\n [expanded]=\"true\"\n [subSteps]=\"getSubStepsForFailedStep()\"\n [failureDetails]=\"failureDetails\"\n [reasoning]=\"reasoning\"\n [confidence]=\"confidence\"\n [isUploadingBaseline]=\"isUploadingBaseline\"\n [isMakingCurrentBaseline]=\"isMakingCurrentBaseline\"\n [isLive]=\"isLive\"\n (makeCurrentBaseline)=\"onMakeCurrentBaseline($event)\"\n (uploadBaseline)=\"onUploadBaseline($event)\"\n (analyze)=\"onAnalyze()\"\n (viewFullLogs)=\"onViewFullLogs()\">\n </cqa-updated-failed-step>\n </div>\n</div>\n", components: [{ type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i2$1.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { type: i2$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { type: AiLogsWithReasoningComponent, selector: "cqa-ai-logs-with-reasoning", inputs: ["status", "text", "description", "reasoning", "duration"] }, { type: StepRendererComponent, selector: "cqa-step-renderer", inputs: ["step", "onExpandHandler", "getConditionBranchesHandler", "isStepLoadingHandler", "isStepExpandedHandler", "convertMsToSecondsHandler", "formatFailureDetailsHandler", "getSelfHealAnalysisHandler", "onMakeCurrentBaselineHandler", "onUploadBaselineHandler", "onAnalyzeHandler", "onViewFullLogsHandler", "onSelfHealActionHandler", "getSelfHealLoadingStatesHandler", "isUploadingBaseline", "isMakingCurrentBaseline", "selectedIterationId", "getLoopIterationsHandler", "getApiAssertionsHandler", "formatActionsHandler", "onViewAllIterationsHandler", "onConditionBranchClickHandler", "onStepClickHandler", "onJsonPathCopiedHandler", "onDownloadHandler", "onFilePathCopiedHandler", "onTextCopiedHandler", "jumpToTimestampHandler", "downloadingStepId", "isLive", "isDebug", "debugPointSet", "getDebugPointSetHandler", "onDebugPointChangeHandler", "onEditStepHandler", "addStepMenuOptions", "onAddStepOptionSelectHandler", "stepMoreMenuOptions", "onStepMoreOptionSelectHandler", "getAddStepMenuOptionsForNested", "getStepMoreMenuOptionsForNested", "stepNumber"], outputs: ["addStepOptionSelect", "stepMoreOptionSelect", "componentReady"] }, { type: SelfHealAnalysisComponent, selector: "cqa-self-heal-analysis", inputs: ["id", "originalLocator", "healedLocator", "confidence", "healMethod", "isLoadingAccept", "isLoadingModifyAccept"], outputs: ["action"] }, { type: ViewMoreFailedStepButtonComponent, selector: "cqa-view-more-failed-step-button", inputs: ["timingBreakdown", "subSteps", "failureDetails", "isExpanded"], outputs: ["viewMoreClick"] }, { type: UpdatedFailedStepComponent, selector: "cqa-updated-failed-step", inputs: ["timingBreakdown", "testStepResultId", "expanded", "subSteps", "failureDetails", "reasoning", "confidence", "isUploadingBaseline", "isMakingCurrentBaseline", "isLive"], outputs: ["makeCurrentBaseline", "uploadBaseline", "analyze", "viewFullLogs"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { type: i2$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }] });
|
|
10193
10719
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: LoopStepComponent, decorators: [{
|
|
10194
10720
|
type: Component,
|
|
10195
|
-
args: [{ selector: 'cqa-loop-step', host: { class: 'cqa-ui-root' }, template: "<div class=\"cqa-font-inter\" (click)=\"$event.stopPropagation()\">\n <!-- Header -->\n <div\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-p-2 cqa-cursor-pointer\"\n (click)=\"toggleHeader($event)\">\n <div *ngIf=\"showDebugIcon\" class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer cqa-rounded-full hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" (click)=\"onDebugPointClick($event)\" [attr.aria-label]=\"debugPointSet ? 'Remove debug point' : 'Set debug point'\">\n <svg *ngIf=\"debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" fill=\"#C63535\"/>\n </svg>\n <svg *ngIf=\"!debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" stroke=\"#C63535\" stroke-width=\"1.5\" fill=\"none\"/>\n </svg>\n </button>\n </div>\n <!-- Status Icon -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <!-- Success -->\n <svg *ngIf=\"status.toLowerCase() === 'success'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <!-- Failed -->\n <svg *ngIf=\"status.toLowerCase() === 'failure' || status.toLowerCase() === 'failed'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4 4L8 8M8 4L4 8\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <!-- Pending -->\n <svg *ngIf=\"status.toLowerCase() === 'pending'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <!-- Running -->\n <svg *ngIf=\"status.toLowerCase() === 'running'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#3B82F6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#3B82F6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n \n <span *ngIf=\"status.toLowerCase() === 'skipped'\" class=\"material-symbols-outlined cqa-text-[#9CA3AF] cqa-text-[12px]\">\n skip_next\n </span>\n </div>\n\n <!-- Loop Icon -->\n <div><svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"16\" height=\"16\" rx=\"4\" fill=\"#EBECFD\"/><path d=\"M9.66663 4.66666L11 5.99999L9.66663 7.33332\" stroke=\"#3F43EE\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M5 7.66667V7.33333C5 6.97971 5.14048 6.64057 5.39052 6.39052C5.64057 6.14048 5.97971 6 6.33333 6H11\" stroke=\"#3F43EE\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6.33333 11.3333L5 9.99999L6.33333 8.66666\" stroke=\"#3F43EE\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M11 8.33334V8.66668C11 9.0203 10.8595 9.35944 10.6095 9.60949C10.3594 9.85953 10.0203 10 9.66667 10H5\" stroke=\"#3F43EE\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n\n <!-- Step Number and Title -->\n <div class=\"cqa-flex-1 cqa-flex cqa-items-center cqa-gap-3 cqa-font-inter\">\n <span class=\"cqa-font-semibold cqa-text-[#334155] cqa-text-[14px] cqa-leading-[18px]\" style=\"word-break: break-word;\">\n {{ config?.stepNumber }}. <span [innerHTML]=\"config?.title\"></span>\n </span>\n \n <!-- Loop Type Badges -->\n <span *ngFor=\"let badge of getLoopTypeBadges()\" \n class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-primary cqa-bg-[#EBECFD] cqa-text-[10px] cqa-leading-[15px]\">\n {{ badge }}\n </span>\n <span *ngIf=\"config.stepDeleted\" class=\"cqa-px-1.5 cqa-py-[2px] cqa-rounded-[4px] cqa-text-[10px] cqa-leading-[12px] cqa-font-medium cqa-text-[#B42318] cqa-bg-[#FEF3F2] cqa-border cqa-border-[#FEE4E2]\">\n Deleted\n </span>\n </div>\n\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-font-inter\">\n <span *ngIf=\"selfHealAnalysis\" class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-[#097E53] cqa-bg-[#CFF2E5] cqa-text-[10px] cqa-leading-[15px] cqa-min-w-max cqa-flex cqa-items-center cqa-gap-[6px]\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"9\" height=\"9\" viewBox=\"0 0 9 9\" fill=\"none\">\n <path d=\"M4.50941 0C4.56489 0.0227384 4.58859 0.0782652 4.61131 0.129846C4.62269 0.1599 4.63314 0.190117 4.64329 0.220575C4.64726 0.232247 4.65123 0.243918 4.65532 0.255943C4.70806 0.413005 4.75504 0.571748 4.80229 0.73038C4.81297 0.76619 4.82369 0.801987 4.83442 0.837783C4.88905 1.02004 4.94327 1.2024 4.99719 1.38484C5.00476 1.41047 5.01234 1.43609 5.01992 1.46171C5.04128 1.53395 5.06262 1.60619 5.08383 1.67847C5.12867 1.8312 5.17473 1.98347 5.22378 2.13501C5.22807 2.14827 5.23236 2.16152 5.23677 2.17518C5.3642 2.565 5.54482 2.91437 5.8409 3.21196C5.84823 3.2197 5.85556 3.22744 5.86312 3.23541C5.9895 3.36437 6.15169 3.46771 6.3138 3.55111C6.32206 3.55542 6.33031 3.55974 6.33882 3.56419C6.81587 3.80925 7.38951 3.91704 7.90619 4.0605C8.1326 4.1234 8.3583 4.18829 8.58317 4.25603C8.59897 4.26079 8.61478 4.26554 8.63058 4.27028C8.67784 4.28445 8.725 4.29887 8.77211 4.31347C8.7831 4.31679 8.79408 4.32011 8.80539 4.32353C8.87029 4.34406 8.93239 4.36829 8.98566 4.41027C9.00191 4.44418 9.00191 4.44418 8.99748 4.4781C8.94564 4.52736 8.8942 4.55046 8.82578 4.573C8.816 4.57632 8.80622 4.57965 8.79614 4.58308C8.68061 4.62183 8.56351 4.65575 8.44626 4.68935C8.4222 4.6963 8.39814 4.70326 8.37408 4.71021C8.22571 4.75301 8.07708 4.7949 7.92829 4.83632C7.73232 4.89088 7.53663 4.94634 7.34113 5.00243C7.3091 5.01162 7.27706 5.02078 7.24501 5.02991C7.07671 5.07786 6.90923 5.12753 6.74314 5.18208C6.72937 5.18659 6.71559 5.1911 6.70139 5.19574C6.14511 5.38082 5.7211 5.72609 5.45571 6.23099C5.31263 6.51475 5.22823 6.82161 5.14214 7.12447C5.11884 7.20619 5.09409 7.28745 5.06905 7.36869C5.0494 7.43261 5.0302 7.49663 5.01149 7.56081C5.00926 7.56844 5.00703 7.57608 5.00473 7.58395C4.99394 7.62094 4.98319 7.65793 4.97252 7.69495C4.94519 7.78879 4.91578 7.88187 4.88555 7.97489C4.83191 8.14021 4.7831 8.30674 4.73459 8.4735C4.66144 8.72457 4.66144 8.72457 4.61997 8.84527C4.61721 8.85337 4.61446 8.86147 4.61163 8.86982C4.59649 8.91278 4.58092 8.95233 4.55226 8.9887C4.50867 8.99788 4.50867 8.99788 4.46951 9C4.42473 8.93759 4.39508 8.87711 4.37133 8.80508C4.36787 8.79487 4.36441 8.78466 4.36085 8.77415C4.31684 8.64248 4.27751 8.50946 4.23817 8.37646C4.22916 8.34604 4.22011 8.31564 4.21105 8.28524C4.1436 8.05863 4.07725 7.83174 4.01101 7.60481C3.73507 6.48224 3.73507 6.48224 3.039 5.57466C3.02784 5.56596 3.01669 5.55726 3.00519 5.5483C2.54913 5.19902 1.94834 5.06969 1.39815 4.91813C1.26207 4.88062 1.12605 4.84293 0.990032 4.80523C0.978138 4.80193 0.978138 4.80193 0.966003 4.79857C0.769811 4.74417 0.573674 4.68963 0.378224 4.63283C0.369956 4.63045 0.361688 4.62806 0.353169 4.62561C0.0528989 4.53883 0.0528989 4.53883 0.000646537 4.4781C-0.000831261 4.45054 -0.000831261 4.45054 0.0124689 4.42157C0.0670835 4.3704 0.120077 4.34848 0.19216 4.32619C0.202597 4.32284 0.213034 4.31948 0.223787 4.31603C0.255753 4.30582 0.287788 4.29584 0.319851 4.28592C0.329001 4.28305 0.338151 4.28017 0.347578 4.27722C0.412285 4.25693 0.477225 4.2374 0.542259 4.21809C0.55824 4.21332 0.55824 4.21332 0.574544 4.20846C0.852269 4.12587 1.13181 4.049 1.41126 3.97196C1.6195 3.91455 1.82738 3.85618 2.0346 3.79548C2.04413 3.79271 2.05365 3.78993 2.06346 3.78707C2.5435 3.64696 3.01278 3.44816 3.32274 3.0537C3.32738 3.04785 3.33202 3.042 3.3368 3.03597C3.68197 2.59815 3.81658 2.06572 3.96695 1.54621C4.01643 1.37534 4.06649 1.20464 4.11673 1.03399C4.13064 0.986733 4.14453 0.939471 4.15836 0.892194C4.21394 0.702289 4.27035 0.512642 4.33 0.323864C4.33558 0.306186 4.34114 0.288501 4.34666 0.270807C4.43017 0.00398761 4.43017 0.00398761 4.50941 0Z\" fill=\"#0DBD7D\"/>\n <path d=\"M7.23597 0.554859C7.29024 0.613599 7.30109 0.682631 7.31799 0.757638C7.37436 0.993269 7.43929 1.20993 7.66467 1.34681C7.80371 1.42035 7.96944 1.45381 8.1235 1.48541C8.18854 1.49902 8.24348 1.51709 8.29924 1.55321C8.31181 1.57229 8.31181 1.57229 8.31107 1.60549C8.29814 1.64588 8.28678 1.6589 8.25269 1.68533C8.21543 1.69726 8.21543 1.69726 8.17068 1.70653C8.15375 1.71025 8.13683 1.714 8.11992 1.71779C8.11086 1.7198 8.10181 1.72181 8.09247 1.72388C7.81696 1.78482 7.81696 1.78482 7.57882 1.92273C7.57108 1.92869 7.56333 1.93466 7.55536 1.9408C7.38516 2.08431 7.34916 2.32303 7.29793 2.52301C7.29499 2.53399 7.29206 2.54497 7.28903 2.55629C7.28649 2.56601 7.28395 2.57573 7.28133 2.58575C7.27028 2.61544 7.25881 2.63479 7.23597 2.65754C7.17234 2.66527 7.17234 2.66527 7.14139 2.65754C7.09216 2.62106 7.08114 2.5795 7.06828 2.52365C7.06613 2.51501 7.06398 2.50636 7.06176 2.49745C7.05489 2.46983 7.04824 2.44217 7.04164 2.41449C6.98979 2.19897 6.93126 1.98751 6.72451 1.86118C6.56293 1.77501 6.36646 1.73426 6.18587 1.70136C6.13637 1.69151 6.10802 1.67911 6.07738 1.64012C6.07073 1.60055 6.07073 1.60055 6.07738 1.56098C6.12447 1.51437 6.17402 1.50299 6.23772 1.48891C6.25778 1.48416 6.27784 1.47938 6.29789 1.47456C6.30825 1.47209 6.31861 1.46962 6.32929 1.46707C6.38212 1.45407 6.43443 1.43949 6.48673 1.42462C6.49623 1.42198 6.50573 1.41935 6.51552 1.41663C6.62182 1.38624 6.71356 1.34737 6.79854 1.27836C6.80647 1.27213 6.81439 1.26589 6.82255 1.25946C6.9548 1.14565 6.99974 0.974674 7.04053 0.815134C7.04364 0.803022 7.04675 0.79091 7.04995 0.778432C7.05614 0.754101 7.06222 0.729743 7.06817 0.705359C7.07243 0.688394 7.07243 0.688394 7.07678 0.671086C7.07927 0.660951 7.08175 0.650816 7.08431 0.640373C7.09521 0.608108 7.10952 0.582772 7.12957 0.554859C7.1681 0.536435 7.19515 0.544764 7.23597 0.554859Z\" fill=\"#075F3F\"/>\n <path d=\"M1.79545 6.2471C1.80951 6.24719 1.80951 6.24719 1.82386 6.24729C1.92477 6.25022 1.99304 6.28115 2.06736 6.34601C2.15384 6.43533 2.19377 6.53611 2.1915 6.6565C2.18178 6.75412 2.12158 6.83935 2.04773 6.90533C1.96081 6.97242 1.87313 6.99459 1.76206 6.99149C1.66841 6.98107 1.5803 6.93852 1.51393 6.87451C1.43138 6.76681 1.40725 6.66803 1.41935 6.53537C1.44433 6.43092 1.51637 6.34613 1.6085 6.28666C1.67251 6.25564 1.72399 6.24652 1.79545 6.2471Z\" fill=\"#0DBD7D\"/>\n </svg>\n Self-healed\n </span>\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-rounded-[4px] cqa-py-0.5 cqa-px-1 cqa-bg-[#6366F11A] cqa-ml-1 cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity\" \n *ngIf=\"step?.executedResult?.video_start_time\" \n [matTooltip]=\"'Jump to video time'\" \n matTooltipPosition=\"below\"\n (click)=\"onJumpToTimestamp($event)\">\n <mat-icon class=\"cqa-text-[#636363] !cqa-text-[10px] !cqa-w-[10px] !cqa-h-[10px]\">\n play_arrow\n </mat-icon>\n <span class=\"cqa-text-[8px] cqa-leading-[12px] cqa-font-normal cqa-text-[#636363]\">\n {{ formatDurationClock(step?.executedResult?.video_start_time || 0) }}\n </span>\n </div>\n <div *ngIf=\"isDebug\" class=\"cqa-flex cqa-items-center cqa-gap-0.5 cqa-text-[#9CA3AF]\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Edit\" (click)=\"onEditStep($event)\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">edit</mat-icon>\n </button>\n <button type=\"button\" #addStepMenuTrigger=\"matMenuTrigger\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Add\" [matMenuTriggerFor]=\"addStepMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">add</mat-icon>\n </button>\n <mat-menu #addStepMenu=\"matMenu\" class=\"cqa-add-step-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of addStepMenuOptions\" (click)=\"onAddStepOptionSelect(opt, $event)\">\n {{ opt.label }}\n </button>\n </mat-menu>\n <button type=\"button\" #stepMoreMenuTrigger=\"matMenuTrigger\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"More options\" [matMenuTriggerFor]=\"stepMoreMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">more_vert</mat-icon>\n </button>\n <mat-menu #stepMoreMenu=\"matMenu\" class=\"cqa-step-more-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of stepMoreMenuOptions\" (click)=\"onStepMoreOptionSelect(opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n </div>\n <span class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF]\">\n {{ formatDuration(config.duration) }}\n </span>\n <svg [class.cqa-rotate-180]=\"isExpanded\" class=\"cqa-transition-transform\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M3.5 5L7 8.5L10.5 5\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n </div>\n\n <!-- Expanded Content -->\n <div *ngIf=\"isExpanded\">\n <!-- Iteration Selector -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-px-4 cqa-py-2 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#737373]\" *ngIf=\"!isLive || (isLive && config?.iterations !== undefined)\">\n <label>Iteration</label>\n <div class=\"cqa-relative cqa-w-full cqa-max-w-[156px]\">\n <!-- Status indicator for selected iteration -->\n <div *ngIf=\"selectedIteration && config?.iterations && config?.iterations?.length > 0\" class=\"cqa-absolute cqa-left-[10px] cqa-top-1/2 cqa-transform cqa--translate-y-1/2 cqa-pointer-events-none cqa-z-10\">\n <svg *ngIf=\"selectedIteration.status === 'success'\" width=\"6\" height=\"6\" viewBox=\"0 0 6 6\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"3\" cy=\"3\" r=\"3\" fill=\"#00A63E\"/></svg>\n <svg *ngIf=\"selectedIteration.status === 'failed'\" width=\"6\" height=\"6\" viewBox=\"0 0 6 6\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"3\" cy=\"3\" r=\"3\" fill=\"#EF4444\"/></svg>\n <svg *ngIf=\"selectedIteration.status === 'pending'\" width=\"6\" height=\"6\" viewBox=\"0 0 6 6\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"3\" cy=\"3\" r=\"3\" fill=\"#9CA3AF\"/></svg>\n <svg *ngIf=\"selectedIteration.status === 'running'\" width=\"6\" height=\"6\" viewBox=\"0 0 6 6\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"3\" cy=\"3\" r=\"3\" fill=\"#3B82F6\"/></svg>\n </div>\n <select\n class=\"cqa-pl-[22px] cqa-pr-6 cqa-py-[5px] cqa-w-full cqa-border cqa-border-[#E5E5E5] cqa-rounded-md cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-[#FAFAFA] cqa-text-black-100 cqa-appearance-none\"\n [(ngModel)]=\"selectedIteration\"\n (ngModelChange)=\"handleIterationChange($event)\"\n [compareWith]=\"compareIteration\"\n [disabled]=\"(isLive && (status === 'running' || status === 'RUNNING'))\">\n <option *ngIf=\"!config?.iterations || config?.iterations?.length === 0\" value=\"\" disabled>\n No iterations available\n </option>\n <option *ngFor=\"let iteration of config.iterations\" [ngValue]=\"iteration\">\n {{ getIterationLabel(iteration) }}\n </option>\n </select>\n <!-- Dropdown arrow -->\n <div class=\"cqa-absolute cqa-right-2 cqa-top-1/2 cqa-transform cqa--translate-y-1/2 cqa-pointer-events-none\">\n <svg width=\"10\" height=\"6\" viewBox=\"0 0 10 6\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M1 1L5 5L9 1\" stroke=\"#9CA3AF\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n </div>\n <span class=\"cqa-ml-auto\" *ngIf=\"config?.iterations && config?.iterations?.length > 0\">\n Default: {{ config.defaultIteration === 'last' ? 'last iteration' : 'first iteration' }}\n </span>\n </div>\n\n <!-- Selected Iteration Sub-steps -->\n <div *ngIf=\"selectedIteration && selectedIteration.subSteps\" class=\"cqa-flex cqa-flex-col cqa-gap-1 cqa-py-1 cqa-ml-9\" style=\"border-bottom: '1px solid #F3F4F6'\">\n <div\n *ngFor=\"let subStep of selectedIteration.subSteps\"\n class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-py-[5.5px] cqa-px-3\">\n \n <!-- Sub-step Status Icon -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'success' || subStep?.status?.toLowerCase() === 'passed'\" >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Failure -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'failure' || subStep?.status?.toLowerCase() === 'failed'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7.5 4.5L4.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 4.5L7.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Pending -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'pending'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Running - Show spinner -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'running'\">\n <svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n </div>\n\n <div class=\"cqa-flex cqa-items-center\" *ngIf=\"subStep?.status?.toLowerCase() === 'skipped'\">\n <span class=\"material-symbols-outlined cqa-text-[#9CA3AF] cqa-text-[12px]\">\n skip_next\n </span>\n </div>\n\n <!-- Sub-step Description -->\n <span class=\"cqa-flex-1 cqa-text-[13px] cqa-leading-[15px] cqa-text-[#364153]\" style=\"white-space: pre-line; word-break: break-word;\">\n {{ subStep.description }}\n </span>\n\n <!-- Sub-step Duration -->\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-metadata-key\">\n {{ formatDuration(subStep.duration) }}\n </span>\n </div>\n </div>\n\n <!-- Nested Steps -->\n <div *ngIf=\"hasChild || (config.nestedSteps && config.nestedSteps.length > 0)\" class=\"cqa-ml-9 cqa-pb-1 cqa-nested-steps-container\" style=\"border-bottom: '1px solid #F3F4F6'\">\n <div class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#737373] cqa-py-[2px] cqa-px-3\">Nested steps</div>\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2 cqa-pl-[18px]\" style=\"border-left: 2px solid #C5C7FA;\">\n <!-- Loading indicator when nested steps are being loaded -->\n <div *ngIf=\"hasChild && (!config.nestedSteps || config.nestedSteps.length === 0) && isStepLoading()\" \n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-py-2 cqa-px-3\">\n <svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M7 1A6 6 0 0 1 13 7\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n <span class=\"cqa-text-[11px] cqa-leading-[13px] cqa-text-[#737373]\">Loading nested steps...</span>\n </div>\n <ng-container *ngFor=\"let step of config.nestedSteps; index as i\">\n <!-- Wrapper to show skeleton while step-renderer is loading -->\n <div\n class=\"cqa-step-renderer-wrapper\"\n [attr.id]=\"'exc-' + step.id\"\n [class.loaded]=\"!isNestedStepLoading(step)\">\n <!-- Loading skeleton overlay -->\n <!-- <div *ngIf=\"isNestedStepLoading(step)\" class=\"cqa-step-skeleton-overlay\">\n <div class=\"cqa-step-skeleton cqa-mx-3 cqa-my-1\"></div>\n </div> -->\n <!-- Use step-renderer for all nested steps to avoid circular dependencies -->\n <!-- The step-renderer will dynamically load the appropriate component and pass handlers -->\n <cqa-step-renderer \n [step]=\"step\"\n [stepNumber]=\"stepNumber + '.' + (i + 1)\"\n [onExpandHandler]=\"onExpandHandler\"\n [getConditionBranchesHandler]=\"getConditionBranchesHandler\"\n [onConditionBranchClickHandler]=\"onConditionBranchClickHandler\"\n [isStepLoadingHandler]=\"isStepLoadingHandler\"\n [isStepExpandedHandler]=\"isStepExpandedHandler\"\n [convertMsToSecondsHandler]=\"convertMsToSecondsHandler\"\n [formatFailureDetailsHandler]=\"formatFailureDetailsHandler\"\n [getSelfHealAnalysisHandler]=\"getSelfHealAnalysisHandler\"\n [getLoopIterationsHandler]=\"getLoopIterationsHandler\"\n [getApiAssertionsHandler]=\"getApiAssertionsHandler\"\n [formatActionsHandler]=\"formatActionsHandler\"\n [onViewAllIterationsHandler]=\"onViewAllIterationsHandler\"\n [onMakeCurrentBaselineHandler]=\"onMakeCurrentBaselineHandler\"\n [onUploadBaselineHandler]=\"onUploadBaselineHandler\"\n [getSelfHealLoadingStatesHandler]=\"getSelfHealLoadingStatesHandler\"\n [onAnalyzeHandler]=\"onAnalyzeHandler\"\n [onViewFullLogsHandler]=\"onViewFullLogsHandler\"\n [onSelfHealActionHandler]=\"onSelfHealActionHandler\"\n [onStepClickHandler]=\"onStepClickHandler\"\n [onJsonPathCopiedHandler]=\"onJsonPathCopiedHandler\"\n [onDownloadHandler]=\"onDownloadHandler\"\n [onFilePathCopiedHandler]=\"onFilePathCopiedHandler\"\n [onTextCopiedHandler]=\"onTextCopiedHandler\"\n [jumpToTimestampHandler]=\"jumpToTimestampHandler\"\n [downloadingStepId]=\"downloadingStepId\"\n [isUploadingBaseline]=\"isUploadingBaseline\"\n [isMakingCurrentBaseline]=\"isMakingCurrentBaseline\"\n [selectedIterationId]=\"step?.selectedIterationId || ''\"\n [isLive]=\"isLive\"\n [isDebug]=\"isDebug\"\n [debugPointSet]=\"getDebugPointSetHandler ? getDebugPointSetHandler(step) : debugPointSet\"\n [getDebugPointSetHandler]=\"getDebugPointSetHandler\"\n [onDebugPointChangeHandler]=\"onDebugPointChangeHandler\"\n [onEditStepHandler]=\"onEditStepHandler\"\n [addStepMenuOptions]=\"getAddStepMenuOptionsForNested ? getAddStepMenuOptionsForNested(step) : addStepMenuOptions\"\n [onAddStepOptionSelectHandler]=\"onAddStepOptionSelectHandler\"\n [stepMoreMenuOptions]=\"getStepMoreMenuOptionsForNested ? getStepMoreMenuOptionsForNested(step) : stepMoreMenuOptions\"\n [onStepMoreOptionSelectHandler]=\"onStepMoreOptionSelectHandler\"\n [getAddStepMenuOptionsForNested]=\"getAddStepMenuOptionsForNested\"\n [getStepMoreMenuOptionsForNested]=\"getStepMoreMenuOptionsForNested\"\n (componentReady)=\"markStepLoaded(step)\">\n </cqa-step-renderer>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- View All Iterations Link -->\n <div *ngIf=\"config.showViewAllIterations && !isLive\" class=\"cqa-flex cqa-justify-end cqa-px-3 cqa-py-[10px]\">\n <a href=\"#\" (click)=\"onViewAllIterationsClick($event)\" class=\"cqa-text-[10px] cqa-leading-[15px] cqa-no-underline cqa-text-primary cqa-font-semibold cqa-flex cqa-items-center cqa-gap-1\">\n View all iterations\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M7.63636 11.267L6.75852 10.3977L9.38778 7.76847H3V6.49858H9.38778L6.75852 3.87358L7.63636 3L11.7699 7.13352L7.63636 11.267Z\" fill=\"#3F43EE\"/></svg>\n </a>\n </div>\n\n <!-- Self Heal Analysis -->\n <cqa-self-heal-analysis \n *ngIf=\"selfHealAnalysis\"\n [id]=\"step?.testStepId\"\n [originalLocator]=\"selfHealAnalysis.originalLocator\"\n [healedLocator]=\"selfHealAnalysis.healedLocator\"\n [confidence]=\"selfHealAnalysis.confidence\"\n [healMethod]=\"selfHealAnalysis.healMethod\"\n [isLoadingAccept]=\"getSelfHealLoadingStatesHandler ? getSelfHealLoadingStatesHandler().isLoadingAccept?.[step?.testStepId] : false\"\n [isLoadingModifyAccept]=\"getSelfHealLoadingStatesHandler ? getSelfHealLoadingStatesHandler().isLoadingModifyAccept?.[step?.testStepId] : false\"\n (action)=\"onSelfHealAction($event)\">\n </cqa-self-heal-analysis>\n\n <!-- Timing Breakdown -->\n <div *ngIf=\"config.timingBreakdown\" class=\"cqa-flex cqa-items-center cqa-justify-end cqa-gap-5 cqa-pt-1.5 cqa-px-4 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF]\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <span>Timing breakdown</span>\n </div>\n <span class=\"cqa-text-dialog-muted cqa-flex cqa-items-center cqa-gap-3\">\n <div>\n App <span class=\"cqa-text-gray-700\">{{ formatDuration(config.timingBreakdown.app) }}</span>\n </div>\n <div><svg width=\"1\" height=\"11\" viewBox=\"0 0 1 11\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M-3.8147e-06 10.32V-7.15256e-07H0.959996V10.32H-3.8147e-06Z\" fill=\"#E5E7EB\"/></svg></div>\n <div>\n Tool <span class=\"cqa-text-gray-700\">{{ formatDuration(config.timingBreakdown.tool) }}</span>\n </div>\n </span>\n </div>\n </div>\n\n <!-- View More Failed Step Button - shown when expanded and failure details exist -->\n <div *ngIf=\"showViewMoreButton\" class=\"cqa-mt-2 cqa-px-4\">\n <cqa-view-more-failed-step-button\n [timingBreakdown]=\"timingBreakdown\"\n [subSteps]=\"getSubStepsForFailedStep()\"\n [failureDetails]=\"failureDetails\"\n [isExpanded]=\"showFailedStepDetails\"\n (viewMoreClick)=\"onViewMoreFailedStepClick($event)\">\n </cqa-view-more-failed-step-button>\n </div>\n\n <!-- Updated Failed Step Component - shown when button is clicked -->\n <div *ngIf=\"showViewMoreButton &&showFailedStepDetails && failureDetails\" class=\"cqa-mt-2 cqa-px-4\">\n <cqa-updated-failed-step\n [testStepResultId]=\"testStepResultId\"\n [timingBreakdown]=\"timingBreakdown\"\n [expanded]=\"true\"\n [subSteps]=\"getSubStepsForFailedStep()\"\n [failureDetails]=\"failureDetails\"\n [reasoning]=\"reasoning\"\n [confidence]=\"confidence\"\n [isUploadingBaseline]=\"isUploadingBaseline\"\n [isMakingCurrentBaseline]=\"isMakingCurrentBaseline\"\n [isLive]=\"isLive\"\n (makeCurrentBaseline)=\"onMakeCurrentBaseline($event)\"\n (uploadBaseline)=\"onUploadBaseline($event)\"\n (analyze)=\"onAnalyze()\"\n (viewFullLogs)=\"onViewFullLogs()\">\n </cqa-updated-failed-step>\n </div>\n</div>\n" }]
|
|
10721
|
+
args: [{ selector: 'cqa-loop-step', host: { class: 'cqa-ui-root' }, template: "<div class=\"cqa-font-inter\" (click)=\"$event.stopPropagation()\">\n <!-- Header -->\n <div\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-p-2 cqa-cursor-pointer\"\n (click)=\"toggleHeader($event)\">\n <div *ngIf=\"showDebugIcon\" class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer cqa-rounded-full hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" (click)=\"onDebugPointClick($event)\" [attr.aria-label]=\"debugPointSet ? 'Remove debug point' : 'Set debug point'\">\n <svg *ngIf=\"debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" fill=\"#C63535\"/>\n </svg>\n <svg *ngIf=\"!debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" stroke=\"#C63535\" stroke-width=\"1.5\" fill=\"none\"/>\n </svg>\n </button>\n </div>\n <!-- Status Icon -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <!-- Success -->\n <svg *ngIf=\"status.toLowerCase() === 'success'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <!-- Failed -->\n <svg *ngIf=\"status.toLowerCase() === 'failure' || status.toLowerCase() === 'failed'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4 4L8 8M8 4L4 8\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <!-- Pending -->\n <svg *ngIf=\"status.toLowerCase() === 'pending'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <!-- Running -->\n <svg *ngIf=\"status.toLowerCase() === 'running'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#3B82F6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#3B82F6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n \n <span *ngIf=\"status.toLowerCase() === 'skipped'\" class=\"material-symbols-outlined cqa-text-[#9CA3AF] cqa-text-[12px]\">\n skip_next\n </span>\n </div>\n\n <!-- Loop Icon -->\n <div><svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"16\" height=\"16\" rx=\"4\" fill=\"#EBECFD\"/><path d=\"M9.66663 4.66666L11 5.99999L9.66663 7.33332\" stroke=\"#3F43EE\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M5 7.66667V7.33333C5 6.97971 5.14048 6.64057 5.39052 6.39052C5.64057 6.14048 5.97971 6 6.33333 6H11\" stroke=\"#3F43EE\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6.33333 11.3333L5 9.99999L6.33333 8.66666\" stroke=\"#3F43EE\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M11 8.33334V8.66668C11 9.0203 10.8595 9.35944 10.6095 9.60949C10.3594 9.85953 10.0203 10 9.66667 10H5\" stroke=\"#3F43EE\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n\n <!-- Step Number and Title -->\n <div class=\"cqa-flex-1 cqa-flex cqa-items-center cqa-gap-3 cqa-font-inter\">\n <span class=\"cqa-font-semibold cqa-text-[#334155] cqa-text-[14px] cqa-leading-[18px]\" style=\"word-break: break-word;\">\n {{ config?.stepNumber }}. <span [innerHTML]=\"config?.title\"></span>\n </span>\n \n <!-- Loop Type Badges -->\n <span *ngFor=\"let badge of getLoopTypeBadges()\" \n class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-primary cqa-bg-[#EBECFD] cqa-text-[10px] cqa-leading-[15px]\">\n {{ badge }}\n </span>\n <span *ngIf=\"config.stepDeleted\" class=\"cqa-px-1.5 cqa-py-[2px] cqa-rounded-[4px] cqa-text-[10px] cqa-leading-[12px] cqa-font-medium cqa-text-[#B42318] cqa-bg-[#FEF3F2] cqa-border cqa-border-[#FEE4E2]\">\n Deleted\n </span>\n </div>\n\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-font-inter\">\n <span *ngIf=\"selfHealAnalysis\" class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-[#097E53] cqa-bg-[#CFF2E5] cqa-text-[10px] cqa-leading-[15px] cqa-min-w-max cqa-flex cqa-items-center cqa-gap-[6px]\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"9\" height=\"9\" viewBox=\"0 0 9 9\" fill=\"none\">\n <path d=\"M4.50941 0C4.56489 0.0227384 4.58859 0.0782652 4.61131 0.129846C4.62269 0.1599 4.63314 0.190117 4.64329 0.220575C4.64726 0.232247 4.65123 0.243918 4.65532 0.255943C4.70806 0.413005 4.75504 0.571748 4.80229 0.73038C4.81297 0.76619 4.82369 0.801987 4.83442 0.837783C4.88905 1.02004 4.94327 1.2024 4.99719 1.38484C5.00476 1.41047 5.01234 1.43609 5.01992 1.46171C5.04128 1.53395 5.06262 1.60619 5.08383 1.67847C5.12867 1.8312 5.17473 1.98347 5.22378 2.13501C5.22807 2.14827 5.23236 2.16152 5.23677 2.17518C5.3642 2.565 5.54482 2.91437 5.8409 3.21196C5.84823 3.2197 5.85556 3.22744 5.86312 3.23541C5.9895 3.36437 6.15169 3.46771 6.3138 3.55111C6.32206 3.55542 6.33031 3.55974 6.33882 3.56419C6.81587 3.80925 7.38951 3.91704 7.90619 4.0605C8.1326 4.1234 8.3583 4.18829 8.58317 4.25603C8.59897 4.26079 8.61478 4.26554 8.63058 4.27028C8.67784 4.28445 8.725 4.29887 8.77211 4.31347C8.7831 4.31679 8.79408 4.32011 8.80539 4.32353C8.87029 4.34406 8.93239 4.36829 8.98566 4.41027C9.00191 4.44418 9.00191 4.44418 8.99748 4.4781C8.94564 4.52736 8.8942 4.55046 8.82578 4.573C8.816 4.57632 8.80622 4.57965 8.79614 4.58308C8.68061 4.62183 8.56351 4.65575 8.44626 4.68935C8.4222 4.6963 8.39814 4.70326 8.37408 4.71021C8.22571 4.75301 8.07708 4.7949 7.92829 4.83632C7.73232 4.89088 7.53663 4.94634 7.34113 5.00243C7.3091 5.01162 7.27706 5.02078 7.24501 5.02991C7.07671 5.07786 6.90923 5.12753 6.74314 5.18208C6.72937 5.18659 6.71559 5.1911 6.70139 5.19574C6.14511 5.38082 5.7211 5.72609 5.45571 6.23099C5.31263 6.51475 5.22823 6.82161 5.14214 7.12447C5.11884 7.20619 5.09409 7.28745 5.06905 7.36869C5.0494 7.43261 5.0302 7.49663 5.01149 7.56081C5.00926 7.56844 5.00703 7.57608 5.00473 7.58395C4.99394 7.62094 4.98319 7.65793 4.97252 7.69495C4.94519 7.78879 4.91578 7.88187 4.88555 7.97489C4.83191 8.14021 4.7831 8.30674 4.73459 8.4735C4.66144 8.72457 4.66144 8.72457 4.61997 8.84527C4.61721 8.85337 4.61446 8.86147 4.61163 8.86982C4.59649 8.91278 4.58092 8.95233 4.55226 8.9887C4.50867 8.99788 4.50867 8.99788 4.46951 9C4.42473 8.93759 4.39508 8.87711 4.37133 8.80508C4.36787 8.79487 4.36441 8.78466 4.36085 8.77415C4.31684 8.64248 4.27751 8.50946 4.23817 8.37646C4.22916 8.34604 4.22011 8.31564 4.21105 8.28524C4.1436 8.05863 4.07725 7.83174 4.01101 7.60481C3.73507 6.48224 3.73507 6.48224 3.039 5.57466C3.02784 5.56596 3.01669 5.55726 3.00519 5.5483C2.54913 5.19902 1.94834 5.06969 1.39815 4.91813C1.26207 4.88062 1.12605 4.84293 0.990032 4.80523C0.978138 4.80193 0.978138 4.80193 0.966003 4.79857C0.769811 4.74417 0.573674 4.68963 0.378224 4.63283C0.369956 4.63045 0.361688 4.62806 0.353169 4.62561C0.0528989 4.53883 0.0528989 4.53883 0.000646537 4.4781C-0.000831261 4.45054 -0.000831261 4.45054 0.0124689 4.42157C0.0670835 4.3704 0.120077 4.34848 0.19216 4.32619C0.202597 4.32284 0.213034 4.31948 0.223787 4.31603C0.255753 4.30582 0.287788 4.29584 0.319851 4.28592C0.329001 4.28305 0.338151 4.28017 0.347578 4.27722C0.412285 4.25693 0.477225 4.2374 0.542259 4.21809C0.55824 4.21332 0.55824 4.21332 0.574544 4.20846C0.852269 4.12587 1.13181 4.049 1.41126 3.97196C1.6195 3.91455 1.82738 3.85618 2.0346 3.79548C2.04413 3.79271 2.05365 3.78993 2.06346 3.78707C2.5435 3.64696 3.01278 3.44816 3.32274 3.0537C3.32738 3.04785 3.33202 3.042 3.3368 3.03597C3.68197 2.59815 3.81658 2.06572 3.96695 1.54621C4.01643 1.37534 4.06649 1.20464 4.11673 1.03399C4.13064 0.986733 4.14453 0.939471 4.15836 0.892194C4.21394 0.702289 4.27035 0.512642 4.33 0.323864C4.33558 0.306186 4.34114 0.288501 4.34666 0.270807C4.43017 0.00398761 4.43017 0.00398761 4.50941 0Z\" fill=\"#0DBD7D\"/>\n <path d=\"M7.23597 0.554859C7.29024 0.613599 7.30109 0.682631 7.31799 0.757638C7.37436 0.993269 7.43929 1.20993 7.66467 1.34681C7.80371 1.42035 7.96944 1.45381 8.1235 1.48541C8.18854 1.49902 8.24348 1.51709 8.29924 1.55321C8.31181 1.57229 8.31181 1.57229 8.31107 1.60549C8.29814 1.64588 8.28678 1.6589 8.25269 1.68533C8.21543 1.69726 8.21543 1.69726 8.17068 1.70653C8.15375 1.71025 8.13683 1.714 8.11992 1.71779C8.11086 1.7198 8.10181 1.72181 8.09247 1.72388C7.81696 1.78482 7.81696 1.78482 7.57882 1.92273C7.57108 1.92869 7.56333 1.93466 7.55536 1.9408C7.38516 2.08431 7.34916 2.32303 7.29793 2.52301C7.29499 2.53399 7.29206 2.54497 7.28903 2.55629C7.28649 2.56601 7.28395 2.57573 7.28133 2.58575C7.27028 2.61544 7.25881 2.63479 7.23597 2.65754C7.17234 2.66527 7.17234 2.66527 7.14139 2.65754C7.09216 2.62106 7.08114 2.5795 7.06828 2.52365C7.06613 2.51501 7.06398 2.50636 7.06176 2.49745C7.05489 2.46983 7.04824 2.44217 7.04164 2.41449C6.98979 2.19897 6.93126 1.98751 6.72451 1.86118C6.56293 1.77501 6.36646 1.73426 6.18587 1.70136C6.13637 1.69151 6.10802 1.67911 6.07738 1.64012C6.07073 1.60055 6.07073 1.60055 6.07738 1.56098C6.12447 1.51437 6.17402 1.50299 6.23772 1.48891C6.25778 1.48416 6.27784 1.47938 6.29789 1.47456C6.30825 1.47209 6.31861 1.46962 6.32929 1.46707C6.38212 1.45407 6.43443 1.43949 6.48673 1.42462C6.49623 1.42198 6.50573 1.41935 6.51552 1.41663C6.62182 1.38624 6.71356 1.34737 6.79854 1.27836C6.80647 1.27213 6.81439 1.26589 6.82255 1.25946C6.9548 1.14565 6.99974 0.974674 7.04053 0.815134C7.04364 0.803022 7.04675 0.79091 7.04995 0.778432C7.05614 0.754101 7.06222 0.729743 7.06817 0.705359C7.07243 0.688394 7.07243 0.688394 7.07678 0.671086C7.07927 0.660951 7.08175 0.650816 7.08431 0.640373C7.09521 0.608108 7.10952 0.582772 7.12957 0.554859C7.1681 0.536435 7.19515 0.544764 7.23597 0.554859Z\" fill=\"#075F3F\"/>\n <path d=\"M1.79545 6.2471C1.80951 6.24719 1.80951 6.24719 1.82386 6.24729C1.92477 6.25022 1.99304 6.28115 2.06736 6.34601C2.15384 6.43533 2.19377 6.53611 2.1915 6.6565C2.18178 6.75412 2.12158 6.83935 2.04773 6.90533C1.96081 6.97242 1.87313 6.99459 1.76206 6.99149C1.66841 6.98107 1.5803 6.93852 1.51393 6.87451C1.43138 6.76681 1.40725 6.66803 1.41935 6.53537C1.44433 6.43092 1.51637 6.34613 1.6085 6.28666C1.67251 6.25564 1.72399 6.24652 1.79545 6.2471Z\" fill=\"#0DBD7D\"/>\n </svg>\n Self-healed\n </span>\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-rounded-[4px] cqa-py-0.5 cqa-px-1 cqa-bg-[#6366F11A] cqa-ml-1 cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity\" \n *ngIf=\"step?.executedResult?.video_start_time\" \n [matTooltip]=\"'Jump to video time'\" \n matTooltipPosition=\"below\"\n (click)=\"onJumpToTimestamp($event)\">\n <mat-icon class=\"cqa-text-[#636363] !cqa-text-[10px] !cqa-w-[10px] !cqa-h-[10px]\">\n play_arrow\n </mat-icon>\n <span class=\"cqa-text-[8px] cqa-leading-[12px] cqa-font-normal cqa-text-[#636363]\">\n {{ formatDurationClock(step?.executedResult?.video_start_time || 0) }}\n </span>\n </div>\n <div *ngIf=\"isDebug\" class=\"cqa-flex cqa-items-center cqa-gap-0.5 cqa-text-[#9CA3AF]\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Edit\" (click)=\"onEditStep($event)\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">edit</mat-icon>\n </button>\n <button type=\"button\" #addStepMenuTrigger=\"matMenuTrigger\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Add\" [matMenuTriggerFor]=\"addStepMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">add</mat-icon>\n </button>\n <mat-menu #addStepMenu=\"matMenu\" class=\"cqa-add-step-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of addStepMenuOptions\" (click)=\"onAddStepOptionSelect(opt, $event)\">\n {{ opt.label }}\n </button>\n </mat-menu>\n <button type=\"button\" #stepMoreMenuTrigger=\"matMenuTrigger\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"More options\" [matMenuTriggerFor]=\"stepMoreMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">more_vert</mat-icon>\n </button>\n <mat-menu #stepMoreMenu=\"matMenu\" class=\"cqa-step-more-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of stepMoreMenuOptions\" (click)=\"onStepMoreOptionSelect(opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n </div>\n <span class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF]\">\n {{ formatDuration(config.duration) }}\n </span>\n <svg [class.cqa-rotate-180]=\"isExpanded\" class=\"cqa-transition-transform\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M3.5 5L7 8.5L10.5 5\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n </div>\n\n <!-- Expanded Content -->\n <div *ngIf=\"isExpanded\">\n <!-- Iteration Selector -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-px-4 cqa-py-2 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#737373]\" *ngIf=\"!isLive || (isLive && config?.iterations !== undefined)\">\n <label>Iteration</label>\n <div class=\"cqa-relative cqa-w-full cqa-max-w-[156px]\">\n <!-- Status indicator for selected iteration -->\n <div *ngIf=\"selectedIteration && config?.iterations && config?.iterations?.length > 0\" class=\"cqa-absolute cqa-left-[10px] cqa-top-1/2 cqa-transform cqa--translate-y-1/2 cqa-pointer-events-none cqa-z-10\">\n <svg *ngIf=\"selectedIteration.status === 'success'\" width=\"6\" height=\"6\" viewBox=\"0 0 6 6\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"3\" cy=\"3\" r=\"3\" fill=\"#00A63E\"/></svg>\n <svg *ngIf=\"selectedIteration.status === 'failed'\" width=\"6\" height=\"6\" viewBox=\"0 0 6 6\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"3\" cy=\"3\" r=\"3\" fill=\"#EF4444\"/></svg>\n <svg *ngIf=\"selectedIteration.status === 'pending'\" width=\"6\" height=\"6\" viewBox=\"0 0 6 6\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"3\" cy=\"3\" r=\"3\" fill=\"#9CA3AF\"/></svg>\n <svg *ngIf=\"selectedIteration.status === 'running'\" width=\"6\" height=\"6\" viewBox=\"0 0 6 6\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"3\" cy=\"3\" r=\"3\" fill=\"#3B82F6\"/></svg>\n </div>\n <select\n class=\"cqa-pl-[22px] cqa-pr-6 cqa-py-[5px] cqa-w-full cqa-border cqa-border-[#E5E5E5] cqa-rounded-md cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-bg-[#FAFAFA] cqa-text-black-100 cqa-appearance-none\"\n [(ngModel)]=\"selectedIteration\"\n (ngModelChange)=\"handleIterationChange($event)\"\n [compareWith]=\"compareIteration\"\n [disabled]=\"(isLive && (status === 'running' || status === 'RUNNING'))\">\n <option *ngIf=\"!config?.iterations || config?.iterations?.length === 0\" value=\"\" disabled>\n No iterations available\n </option>\n <option *ngFor=\"let iteration of config.iterations\" [ngValue]=\"iteration\">\n {{ getIterationLabel(iteration) }}\n </option>\n </select>\n <!-- Dropdown arrow -->\n <div class=\"cqa-absolute cqa-right-2 cqa-top-1/2 cqa-transform cqa--translate-y-1/2 cqa-pointer-events-none\">\n <svg width=\"10\" height=\"6\" viewBox=\"0 0 10 6\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M1 1L5 5L9 1\" stroke=\"#9CA3AF\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n </div>\n <span class=\"cqa-ml-auto\" *ngIf=\"config?.iterations && config?.iterations?.length > 0\">\n Default: {{ config.defaultIteration === 'last' ? 'last iteration' : 'first iteration' }}\n </span>\n </div>\n\n <!-- Selected Iteration Sub-steps -->\n <div *ngIf=\"selectedIteration && selectedIteration.subSteps\" class=\"cqa-flex cqa-flex-col cqa-gap-1 cqa-py-1 cqa-ml-9\" style=\"border-bottom: '1px solid #F3F4F6'\">\n <!-- Single loop: render all entries in chronological order -->\n <ng-container *ngFor=\"let subStep of (isLive ? processedSubSteps : processedSubStepsForRunResult)\">\n <!-- AI_AUTO_HEAL_SUCCESS/FAILED: render with ai-agent-step style (both live and run result screens) -->\n <cqa-ai-logs-with-reasoning\n *ngIf=\"$any(subStep).isAiAutoHealResult\"\n [status]=\"subStep.status\"\n [text]=\"$any(subStep).text || subStep?.value\"\n [description]=\"$any(subStep).description || subStep?.text || subStep?.value\"\n [reasoning]=\"$any(subStep).reasoning || subStep?.reasoning\"\n [duration]=\"subStep.duration\">\n </cqa-ai-logs-with-reasoning>\n\n <!-- Regular sub-steps -->\n <div\n *ngIf=\"!$any(subStep).isAiAutoHealResult\"\n class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-py-[5.5px] cqa-px-3\">\n \n <!-- Sub-step Status Icon -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'success' || subStep?.status?.toLowerCase() === 'passed'\" >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Failure -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'failure' || subStep?.status?.toLowerCase() === 'failed'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7.5 4.5L4.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 4.5L7.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Pending -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'pending'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Running - Show spinner (also used for active WAIT_FOR_LOCATOR countdown in live mode) -->\n <div *ngIf=\"subStep?.status?.toLowerCase() === 'running'\">\n <svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n </div>\n\n <div class=\"cqa-flex cqa-items-center\" *ngIf=\"subStep?.status?.toLowerCase() === 'skipped'\">\n <span class=\"material-symbols-outlined cqa-text-[#9CA3AF] cqa-text-[12px]\">\n skip_next\n </span>\n </div>\n\n <!-- Sub-step Description -->\n <span class=\"cqa-flex-1 cqa-text-[13px] cqa-leading-[15px] cqa-text-[#364153]\" style=\"white-space: pre-line; word-break: break-word;\">\n {{ $any(subStep).description || $any(subStep).text }}\n <!-- Countdown for active WAIT_FOR_LOCATOR in live mode -->\n <span *ngIf=\"isLive && $any(subStep).remainingSeconds != null\" class=\"cqa-text-[#F97316] cqa-font-medium cqa-ml-1\">({{ $any(subStep).remainingSeconds }}s remaining)</span>\n </span>\n\n <!-- Sub-step Duration -->\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-metadata-key\">\n {{ formatDuration(subStep.duration) }}\n </span>\n </div>\n </ng-container>\n </div>\n\n <!-- Nested Steps -->\n <div *ngIf=\"hasChild || (config.nestedSteps && config.nestedSteps.length > 0)\" class=\"cqa-ml-9 cqa-pb-1 cqa-nested-steps-container\" style=\"border-bottom: '1px solid #F3F4F6'\">\n <div class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#737373] cqa-py-[2px] cqa-px-3\">Nested steps</div>\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2 cqa-pl-[18px]\" style=\"border-left: 2px solid #C5C7FA;\">\n <!-- Loading indicator when nested steps are being loaded -->\n <div *ngIf=\"hasChild && (!config.nestedSteps || config.nestedSteps.length === 0) && isStepLoading()\" \n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-py-2 cqa-px-3\">\n <svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M7 1A6 6 0 0 1 13 7\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n <span class=\"cqa-text-[11px] cqa-leading-[13px] cqa-text-[#737373]\">Loading nested steps...</span>\n </div>\n <ng-container *ngFor=\"let step of config.nestedSteps; index as i\">\n <!-- Wrapper to show skeleton while step-renderer is loading -->\n <div\n class=\"cqa-step-renderer-wrapper\"\n [attr.id]=\"'exc-' + step.id\"\n [class.loaded]=\"!isNestedStepLoading(step)\">\n <!-- Loading skeleton overlay -->\n <!-- <div *ngIf=\"isNestedStepLoading(step)\" class=\"cqa-step-skeleton-overlay\">\n <div class=\"cqa-step-skeleton cqa-mx-3 cqa-my-1\"></div>\n </div> -->\n <!-- Use step-renderer for all nested steps to avoid circular dependencies -->\n <!-- The step-renderer will dynamically load the appropriate component and pass handlers -->\n <cqa-step-renderer \n [step]=\"step\"\n [stepNumber]=\"stepNumber + '.' + (i + 1)\"\n [onExpandHandler]=\"onExpandHandler\"\n [getConditionBranchesHandler]=\"getConditionBranchesHandler\"\n [onConditionBranchClickHandler]=\"onConditionBranchClickHandler\"\n [isStepLoadingHandler]=\"isStepLoadingHandler\"\n [isStepExpandedHandler]=\"isStepExpandedHandler\"\n [convertMsToSecondsHandler]=\"convertMsToSecondsHandler\"\n [formatFailureDetailsHandler]=\"formatFailureDetailsHandler\"\n [getSelfHealAnalysisHandler]=\"getSelfHealAnalysisHandler\"\n [getLoopIterationsHandler]=\"getLoopIterationsHandler\"\n [getApiAssertionsHandler]=\"getApiAssertionsHandler\"\n [formatActionsHandler]=\"formatActionsHandler\"\n [onViewAllIterationsHandler]=\"onViewAllIterationsHandler\"\n [onMakeCurrentBaselineHandler]=\"onMakeCurrentBaselineHandler\"\n [onUploadBaselineHandler]=\"onUploadBaselineHandler\"\n [getSelfHealLoadingStatesHandler]=\"getSelfHealLoadingStatesHandler\"\n [onAnalyzeHandler]=\"onAnalyzeHandler\"\n [onViewFullLogsHandler]=\"onViewFullLogsHandler\"\n [onSelfHealActionHandler]=\"onSelfHealActionHandler\"\n [onStepClickHandler]=\"onStepClickHandler\"\n [onJsonPathCopiedHandler]=\"onJsonPathCopiedHandler\"\n [onDownloadHandler]=\"onDownloadHandler\"\n [onFilePathCopiedHandler]=\"onFilePathCopiedHandler\"\n [onTextCopiedHandler]=\"onTextCopiedHandler\"\n [jumpToTimestampHandler]=\"jumpToTimestampHandler\"\n [downloadingStepId]=\"downloadingStepId\"\n [isUploadingBaseline]=\"isUploadingBaseline\"\n [isMakingCurrentBaseline]=\"isMakingCurrentBaseline\"\n [selectedIterationId]=\"step?.selectedIterationId || ''\"\n [isLive]=\"isLive\"\n [isDebug]=\"isDebug\"\n [debugPointSet]=\"getDebugPointSetHandler ? getDebugPointSetHandler(step) : debugPointSet\"\n [getDebugPointSetHandler]=\"getDebugPointSetHandler\"\n [onDebugPointChangeHandler]=\"onDebugPointChangeHandler\"\n [onEditStepHandler]=\"onEditStepHandler\"\n [addStepMenuOptions]=\"getAddStepMenuOptionsForNested ? getAddStepMenuOptionsForNested(step) : addStepMenuOptions\"\n [onAddStepOptionSelectHandler]=\"onAddStepOptionSelectHandler\"\n [stepMoreMenuOptions]=\"getStepMoreMenuOptionsForNested ? getStepMoreMenuOptionsForNested(step) : stepMoreMenuOptions\"\n [onStepMoreOptionSelectHandler]=\"onStepMoreOptionSelectHandler\"\n [getAddStepMenuOptionsForNested]=\"getAddStepMenuOptionsForNested\"\n [getStepMoreMenuOptionsForNested]=\"getStepMoreMenuOptionsForNested\"\n (componentReady)=\"markStepLoaded(step)\">\n </cqa-step-renderer>\n </div>\n </ng-container>\n </div>\n </div>\n\n <!-- View All Iterations Link -->\n <div *ngIf=\"config.showViewAllIterations && !isLive\" class=\"cqa-flex cqa-justify-end cqa-px-3 cqa-py-[10px]\">\n <a href=\"#\" (click)=\"onViewAllIterationsClick($event)\" class=\"cqa-text-[10px] cqa-leading-[15px] cqa-no-underline cqa-text-primary cqa-font-semibold cqa-flex cqa-items-center cqa-gap-1\">\n View all iterations\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M7.63636 11.267L6.75852 10.3977L9.38778 7.76847H3V6.49858H9.38778L6.75852 3.87358L7.63636 3L11.7699 7.13352L7.63636 11.267Z\" fill=\"#3F43EE\"/></svg>\n </a>\n </div>\n\n <!-- Self Heal Analysis -->\n <cqa-self-heal-analysis \n *ngIf=\"selfHealAnalysis\"\n [id]=\"step?.testStepId\"\n [originalLocator]=\"selfHealAnalysis.originalLocator\"\n [healedLocator]=\"selfHealAnalysis.healedLocator\"\n [confidence]=\"selfHealAnalysis.confidence\"\n [healMethod]=\"selfHealAnalysis.healMethod\"\n [isLoadingAccept]=\"getSelfHealLoadingStatesHandler ? getSelfHealLoadingStatesHandler().isLoadingAccept?.[step?.testStepId] : false\"\n [isLoadingModifyAccept]=\"getSelfHealLoadingStatesHandler ? getSelfHealLoadingStatesHandler().isLoadingModifyAccept?.[step?.testStepId] : false\"\n (action)=\"onSelfHealAction($event)\">\n </cqa-self-heal-analysis>\n\n <!-- Timing Breakdown -->\n <div *ngIf=\"config.timingBreakdown\" class=\"cqa-flex cqa-items-center cqa-justify-end cqa-gap-5 cqa-pt-1.5 cqa-px-4 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF]\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <span>Timing breakdown</span>\n </div>\n <span class=\"cqa-text-dialog-muted cqa-flex cqa-items-center cqa-gap-3\">\n <div>\n App <span class=\"cqa-text-gray-700\">{{ formatDuration(config.timingBreakdown.app) }}</span>\n </div>\n <div><svg width=\"1\" height=\"11\" viewBox=\"0 0 1 11\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M-3.8147e-06 10.32V-7.15256e-07H0.959996V10.32H-3.8147e-06Z\" fill=\"#E5E7EB\"/></svg></div>\n <div>\n Tool <span class=\"cqa-text-gray-700\">{{ formatDuration(config.timingBreakdown.tool) }}</span>\n </div>\n </span>\n </div>\n </div>\n\n <!-- View More Failed Step Button - shown when expanded and failure details exist -->\n <div *ngIf=\"showViewMoreButton\" class=\"cqa-mt-2 cqa-px-4\">\n <cqa-view-more-failed-step-button\n [timingBreakdown]=\"timingBreakdown\"\n [subSteps]=\"getSubStepsForFailedStep()\"\n [failureDetails]=\"failureDetails\"\n [isExpanded]=\"showFailedStepDetails\"\n (viewMoreClick)=\"onViewMoreFailedStepClick($event)\">\n </cqa-view-more-failed-step-button>\n </div>\n\n <!-- Updated Failed Step Component - shown when button is clicked -->\n <div *ngIf=\"showViewMoreButton &&showFailedStepDetails && failureDetails\" class=\"cqa-mt-2 cqa-px-4\">\n <cqa-updated-failed-step\n [testStepResultId]=\"testStepResultId\"\n [timingBreakdown]=\"timingBreakdown\"\n [expanded]=\"true\"\n [subSteps]=\"getSubStepsForFailedStep()\"\n [failureDetails]=\"failureDetails\"\n [reasoning]=\"reasoning\"\n [confidence]=\"confidence\"\n [isUploadingBaseline]=\"isUploadingBaseline\"\n [isMakingCurrentBaseline]=\"isMakingCurrentBaseline\"\n [isLive]=\"isLive\"\n (makeCurrentBaseline)=\"onMakeCurrentBaseline($event)\"\n (uploadBaseline)=\"onUploadBaseline($event)\"\n (analyze)=\"onAnalyze()\"\n (viewFullLogs)=\"onViewFullLogs()\">\n </cqa-updated-failed-step>\n </div>\n</div>\n" }]
|
|
10196
10722
|
}], propDecorators: { id: [{
|
|
10197
10723
|
type: Input
|
|
10198
10724
|
}], testStepResultId: [{
|
|
@@ -11634,6 +12160,15 @@ class ApiStepComponent extends BaseStepComponent {
|
|
|
11634
12160
|
this.showFailedStepDetails = false;
|
|
11635
12161
|
this.userManuallyClosed = false;
|
|
11636
12162
|
this.showRequestSummaryCopied = false;
|
|
12163
|
+
// Processed initial actions for live mode WAIT_FOR_LOCATOR countdown grouping
|
|
12164
|
+
this.processedInitialActions = [];
|
|
12165
|
+
this.lastProcessedIndex = 0;
|
|
12166
|
+
this.waitLocatorGroupEntry = null;
|
|
12167
|
+
this.countdownIntervalId = null;
|
|
12168
|
+
// AI_AUTO_HEAL grouping: show loading until AI_AUTO_HEAL_SUCCESS or AI_AUTO_HEAL_FAILED
|
|
12169
|
+
this.aiAutoHealGroupEntry = null;
|
|
12170
|
+
// Processed initial actions for run result screen (filter and split AI_AUTO_HEAL_SUCCESS/FAILED)
|
|
12171
|
+
this.processedInitialActionsForRunResult = [];
|
|
11637
12172
|
this.showRequestHeadersCopied = false;
|
|
11638
12173
|
this.showResponseHeadersCopied = false;
|
|
11639
12174
|
this.showRequestBodyCopied = false;
|
|
@@ -11651,6 +12186,14 @@ class ApiStepComponent extends BaseStepComponent {
|
|
|
11651
12186
|
if (this.expanded !== undefined) {
|
|
11652
12187
|
this.isExpanded = this.expanded;
|
|
11653
12188
|
}
|
|
12189
|
+
// Initialize live initial actions processing for WAIT_FOR_LOCATOR grouping
|
|
12190
|
+
if (this.isLive && this.initialActions && this.initialActions.length > 0) {
|
|
12191
|
+
this.processLiveInitialActions();
|
|
12192
|
+
}
|
|
12193
|
+
else if (!this.isLive && this.initialActions && this.initialActions.length > 0) {
|
|
12194
|
+
// Process for run result screen: filter and split AI_AUTO_HEAL_SUCCESS/FAILED
|
|
12195
|
+
this.processInitialActionsForRunResult();
|
|
12196
|
+
}
|
|
11654
12197
|
}
|
|
11655
12198
|
ngOnChanges(changes) {
|
|
11656
12199
|
var _a;
|
|
@@ -11670,6 +12213,13 @@ class ApiStepComponent extends BaseStepComponent {
|
|
|
11670
12213
|
if (changes['initialActions']) {
|
|
11671
12214
|
const previousActionsCount = ((_a = changes['initialActions'].previousValue) === null || _a === void 0 ? void 0 : _a.length) || 0;
|
|
11672
12215
|
const currentActionsCount = (this.initialActions || []).length;
|
|
12216
|
+
// Process live initial actions
|
|
12217
|
+
if (this.isLive) {
|
|
12218
|
+
this.processLiveInitialActions();
|
|
12219
|
+
}
|
|
12220
|
+
else {
|
|
12221
|
+
this.processInitialActionsForRunResult();
|
|
12222
|
+
}
|
|
11673
12223
|
// Auto-expand if step is running and new initialActions are added (logs coming in)
|
|
11674
12224
|
if (!changes['initialActions'].firstChange &&
|
|
11675
12225
|
this.status === 'running' &&
|
|
@@ -12091,6 +12641,14 @@ class ApiStepComponent extends BaseStepComponent {
|
|
|
12091
12641
|
expanded: this.expanded,
|
|
12092
12642
|
};
|
|
12093
12643
|
}
|
|
12644
|
+
ngDoCheck() {
|
|
12645
|
+
if (!this.isLive)
|
|
12646
|
+
return;
|
|
12647
|
+
const currentLength = (this.initialActions || []).length;
|
|
12648
|
+
if (currentLength !== this.lastProcessedIndex) {
|
|
12649
|
+
this.processLiveInitialActions();
|
|
12650
|
+
}
|
|
12651
|
+
}
|
|
12094
12652
|
ngOnDestroy() {
|
|
12095
12653
|
// Clean up timeouts to prevent memory leaks
|
|
12096
12654
|
if (this.requestSummaryCopiedTimeout) {
|
|
@@ -12108,6 +12666,135 @@ class ApiStepComponent extends BaseStepComponent {
|
|
|
12108
12666
|
if (this.responseBodyCopiedTimeout) {
|
|
12109
12667
|
clearTimeout(this.responseBodyCopiedTimeout);
|
|
12110
12668
|
}
|
|
12669
|
+
this.clearCountdownTimer();
|
|
12670
|
+
}
|
|
12671
|
+
processLiveInitialActions() {
|
|
12672
|
+
var _a, _b, _c, _d;
|
|
12673
|
+
const allInitialActions = (this.initialActions || []);
|
|
12674
|
+
// Reset if initialActions were cleared or replaced with fewer entries
|
|
12675
|
+
if (allInitialActions.length < this.lastProcessedIndex) {
|
|
12676
|
+
this.resetLiveProcessing();
|
|
12677
|
+
}
|
|
12678
|
+
for (let i = this.lastProcessedIndex; i < allInitialActions.length; i++) {
|
|
12679
|
+
const action = allInitialActions[i];
|
|
12680
|
+
const uiType = (action === null || action === void 0 ? void 0 : action.uiType) || (action === null || action === void 0 ? void 0 : action.type) || '';
|
|
12681
|
+
const status = ((action === null || action === void 0 ? void 0 : action.status) || '').toLowerCase();
|
|
12682
|
+
if (uiType === 'WAIT_FOR_LOCATOR') {
|
|
12683
|
+
// Create a single grouped entry with a countdown; absorbs FIND_LOCATOR and LOCATOR_FOUND
|
|
12684
|
+
const timeoutSeconds = typeof action.value === 'number'
|
|
12685
|
+
? action.value
|
|
12686
|
+
: (action.value ? parseFloat(action.value) : 30);
|
|
12687
|
+
this.clearCountdownTimer();
|
|
12688
|
+
this.waitLocatorGroupEntry = Object.assign(Object.assign({}, action), { remainingSeconds: timeoutSeconds, status: 'running' });
|
|
12689
|
+
this.processedInitialActions.push(this.waitLocatorGroupEntry);
|
|
12690
|
+
// Tick down every second
|
|
12691
|
+
this.countdownIntervalId = setInterval(() => {
|
|
12692
|
+
if (this.waitLocatorGroupEntry) {
|
|
12693
|
+
this.waitLocatorGroupEntry.remainingSeconds = Math.max(0, this.waitLocatorGroupEntry.remainingSeconds - 1);
|
|
12694
|
+
if (this.waitLocatorGroupEntry.remainingSeconds <= 0) {
|
|
12695
|
+
this.waitLocatorGroupEntry.status = 'failed';
|
|
12696
|
+
this.waitLocatorGroupEntry.remainingSeconds = null;
|
|
12697
|
+
this.clearCountdownTimer();
|
|
12698
|
+
this.waitLocatorGroupEntry = null;
|
|
12699
|
+
}
|
|
12700
|
+
}
|
|
12701
|
+
}, 1000);
|
|
12702
|
+
}
|
|
12703
|
+
else if (uiType === 'FIND_LOCATOR') {
|
|
12704
|
+
if (status === 'failed' || status === 'failure') {
|
|
12705
|
+
// Abort countdown, replace group entry with this failed log
|
|
12706
|
+
if (this.waitLocatorGroupEntry) {
|
|
12707
|
+
this.processedInitialActions = this.processedInitialActions.filter(entry => entry !== this.waitLocatorGroupEntry);
|
|
12708
|
+
this.clearCountdownTimer();
|
|
12709
|
+
this.waitLocatorGroupEntry = null;
|
|
12710
|
+
}
|
|
12711
|
+
this.processedInitialActions.push(Object.assign(Object.assign({}, action), { status: 'failed' }));
|
|
12712
|
+
}
|
|
12713
|
+
else if (this.waitLocatorGroupEntry) {
|
|
12714
|
+
// Update the single group entry's text so the user sees progress
|
|
12715
|
+
const newText = action.description || action.text || action.title;
|
|
12716
|
+
if (newText)
|
|
12717
|
+
this.waitLocatorGroupEntry.description = newText;
|
|
12718
|
+
}
|
|
12719
|
+
}
|
|
12720
|
+
else if (uiType === 'LOCATOR_FOUND') {
|
|
12721
|
+
if (status === 'failed' || status === 'failure') {
|
|
12722
|
+
// Abort countdown, replace group entry with this failed log
|
|
12723
|
+
if (this.waitLocatorGroupEntry) {
|
|
12724
|
+
this.processedInitialActions = this.processedInitialActions.filter(entry => entry !== this.waitLocatorGroupEntry);
|
|
12725
|
+
this.clearCountdownTimer();
|
|
12726
|
+
this.waitLocatorGroupEntry = null;
|
|
12727
|
+
}
|
|
12728
|
+
this.processedInitialActions.push(Object.assign(Object.assign({}, action), { status: 'failed' }));
|
|
12729
|
+
}
|
|
12730
|
+
else {
|
|
12731
|
+
// Sequence complete – update group entry to show LOCATOR_FOUND text as success
|
|
12732
|
+
if (this.waitLocatorGroupEntry) {
|
|
12733
|
+
const newText = action.description || action.text || action.title;
|
|
12734
|
+
if (newText)
|
|
12735
|
+
this.waitLocatorGroupEntry.description = newText;
|
|
12736
|
+
this.waitLocatorGroupEntry.status = 'success';
|
|
12737
|
+
this.waitLocatorGroupEntry.remainingSeconds = null;
|
|
12738
|
+
this.clearCountdownTimer();
|
|
12739
|
+
this.waitLocatorGroupEntry = null;
|
|
12740
|
+
}
|
|
12741
|
+
else {
|
|
12742
|
+
// No active group – push LOCATOR_FOUND normally
|
|
12743
|
+
this.processedInitialActions.push(Object.assign({}, action));
|
|
12744
|
+
}
|
|
12745
|
+
}
|
|
12746
|
+
}
|
|
12747
|
+
else if (uiType === 'AI_AUTO_HEAL') {
|
|
12748
|
+
// Add single loading entry; will be replaced by AI_AUTO_HEAL_SUCCESS or AI_AUTO_HEAL_FAILED
|
|
12749
|
+
this.aiAutoHealGroupEntry = Object.assign(Object.assign({}, action), { description: action.description || action.text || 'AI auto-heal started', status: 'running', uiType: 'AI_AUTO_HEAL' });
|
|
12750
|
+
this.processedInitialActions.push(this.aiAutoHealGroupEntry);
|
|
12751
|
+
}
|
|
12752
|
+
else if (uiType === 'AI_AUTO_HEAL_SUCCESS' || uiType === 'AI_AUTO_HEAL_FAILED') {
|
|
12753
|
+
// Remove loading entry and add TWO separate entries: value and reasoning (like AI_ANSWER)
|
|
12754
|
+
if (this.aiAutoHealGroupEntry) {
|
|
12755
|
+
this.processedInitialActions = this.processedInitialActions.filter(entry => entry !== this.aiAutoHealGroupEntry);
|
|
12756
|
+
this.aiAutoHealGroupEntry = null;
|
|
12757
|
+
}
|
|
12758
|
+
const isSuccess = uiType === 'AI_AUTO_HEAL_SUCCESS';
|
|
12759
|
+
const value = (_b = (_a = action.value) !== null && _a !== void 0 ? _a : action.text) !== null && _b !== void 0 ? _b : '';
|
|
12760
|
+
const reasoning = (_d = (_c = action.reasoning) !== null && _c !== void 0 ? _c : action.Reasoning) !== null && _d !== void 0 ? _d : '';
|
|
12761
|
+
const baseDuration = action.duration || 0;
|
|
12762
|
+
const finalStatus = isSuccess ? 'success' : 'failed';
|
|
12763
|
+
// First entry: value/description
|
|
12764
|
+
const valueDescription = action.text || action.description || (isSuccess
|
|
12765
|
+
? `AI auto-heal successful. New locator: ${value}`
|
|
12766
|
+
: `AI auto-heal failed for element: ${value}`);
|
|
12767
|
+
this.processedInitialActions.push(Object.assign(Object.assign({}, action), { description: valueDescription, value: value, reasoning: null, status: finalStatus, uiType: 'AI_AUTO_HEAL_VALUE', type: 'AI_AUTO_HEAL_VALUE', duration: baseDuration, isAiAutoHealResult: true }));
|
|
12768
|
+
// Second entry: reasoning (only if present)
|
|
12769
|
+
if (reasoning) {
|
|
12770
|
+
this.processedInitialActions.push(Object.assign(Object.assign({}, action), { description: reasoning, value: null, reasoning: reasoning, status: finalStatus, uiType: 'AI_AUTO_HEAL_REASONING', type: 'AI_AUTO_HEAL_REASONING', duration: baseDuration, isAiAutoHealResult: true }));
|
|
12771
|
+
}
|
|
12772
|
+
}
|
|
12773
|
+
else {
|
|
12774
|
+
// Any failed log while a countdown is active – resolve it as failed
|
|
12775
|
+
if ((status === 'failed' || status === 'failure') && this.waitLocatorGroupEntry) {
|
|
12776
|
+
this.waitLocatorGroupEntry.status = 'failed';
|
|
12777
|
+
this.waitLocatorGroupEntry.remainingSeconds = null;
|
|
12778
|
+
this.clearCountdownTimer();
|
|
12779
|
+
this.waitLocatorGroupEntry = null;
|
|
12780
|
+
}
|
|
12781
|
+
this.processedInitialActions.push(action);
|
|
12782
|
+
}
|
|
12783
|
+
}
|
|
12784
|
+
this.lastProcessedIndex = allInitialActions.length;
|
|
12785
|
+
}
|
|
12786
|
+
resetLiveProcessing() {
|
|
12787
|
+
this.clearCountdownTimer();
|
|
12788
|
+
this.processedInitialActions = [];
|
|
12789
|
+
this.lastProcessedIndex = 0;
|
|
12790
|
+
this.waitLocatorGroupEntry = null;
|
|
12791
|
+
this.aiAutoHealGroupEntry = null;
|
|
12792
|
+
}
|
|
12793
|
+
clearCountdownTimer() {
|
|
12794
|
+
if (this.countdownIntervalId !== null) {
|
|
12795
|
+
clearInterval(this.countdownIntervalId);
|
|
12796
|
+
this.countdownIntervalId = null;
|
|
12797
|
+
}
|
|
12111
12798
|
}
|
|
12112
12799
|
onJumpToTimestamp(event) {
|
|
12113
12800
|
var _a, _b, _c, _d, _e;
|
|
@@ -12122,12 +12809,41 @@ class ApiStepComponent extends BaseStepComponent {
|
|
|
12122
12809
|
}
|
|
12123
12810
|
}
|
|
12124
12811
|
}
|
|
12812
|
+
processInitialActionsForRunResult() {
|
|
12813
|
+
var _a, _b, _c, _d;
|
|
12814
|
+
const allInitialActions = (this.initialActions || []);
|
|
12815
|
+
this.processedInitialActionsForRunResult = [];
|
|
12816
|
+
for (const action of allInitialActions) {
|
|
12817
|
+
const uiType = (action === null || action === void 0 ? void 0 : action.uiType) || (action === null || action === void 0 ? void 0 : action.type) || '';
|
|
12818
|
+
// Split AI_AUTO_HEAL_SUCCESS/FAILED into two entries
|
|
12819
|
+
if (uiType === 'AI_AUTO_HEAL_SUCCESS' || uiType === 'AI_AUTO_HEAL_FAILED') {
|
|
12820
|
+
const isSuccess = uiType === 'AI_AUTO_HEAL_SUCCESS';
|
|
12821
|
+
const value = (_b = (_a = action.value) !== null && _a !== void 0 ? _a : action.text) !== null && _b !== void 0 ? _b : '';
|
|
12822
|
+
const reasoning = (_d = (_c = action.reasoning) !== null && _c !== void 0 ? _c : action.Reasoning) !== null && _d !== void 0 ? _d : '';
|
|
12823
|
+
const baseDuration = action.duration || 0;
|
|
12824
|
+
const finalStatus = isSuccess ? 'success' : 'failed';
|
|
12825
|
+
// First entry: value/description
|
|
12826
|
+
const valueDescription = (isSuccess
|
|
12827
|
+
? `AI auto-heal successful. New locator: ${value}`
|
|
12828
|
+
: `AI auto-heal failed for element: ${value}`);
|
|
12829
|
+
this.processedInitialActionsForRunResult.push(Object.assign(Object.assign({}, action), { description: valueDescription, value: value, reasoning: null, status: finalStatus, uiType: 'AI_AUTO_HEAL_VALUE', type: 'AI_AUTO_HEAL_VALUE', duration: baseDuration, isAiAutoHealResult: true }));
|
|
12830
|
+
// Second entry: reasoning (only if present)
|
|
12831
|
+
if (reasoning) {
|
|
12832
|
+
this.processedInitialActionsForRunResult.push(Object.assign(Object.assign({}, action), { description: reasoning, value: null, reasoning: reasoning, status: finalStatus, uiType: 'AI_AUTO_HEAL_REASONING', type: 'AI_AUTO_HEAL_REASONING', duration: baseDuration, isAiAutoHealResult: true }));
|
|
12833
|
+
}
|
|
12834
|
+
}
|
|
12835
|
+
else {
|
|
12836
|
+
// All other logs pass through as-is
|
|
12837
|
+
this.processedInitialActionsForRunResult.push(action);
|
|
12838
|
+
}
|
|
12839
|
+
}
|
|
12840
|
+
}
|
|
12125
12841
|
}
|
|
12126
12842
|
ApiStepComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ApiStepComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
12127
|
-
ApiStepComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: ApiStepComponent, selector: "cqa-api-step", inputs: { id: "id", testStepResultId: "testStepResultId", stepNumber: "stepNumber", title: "title", status: "status", duration: "duration", timingBreakdown: "timingBreakdown", expanded: "expanded", method: "method", endpoint: "endpoint", statusCode: "statusCode", responseTime: "responseTime", requestBody: "requestBody", responseBody: "responseBody", requestHeaders: "requestHeaders", responseHeaders: "responseHeaders", assertions: "assertions", initialActions: "initialActions", isDebug: "isDebug", debugPointSet: "debugPointSet", addStepMenuOptions: "addStepMenuOptions", stepMoreMenuOptions: "stepMoreMenuOptions", failureDetails: "failureDetails", reasoning: "reasoning", confidence: "confidence", stepDeleted: "stepDeleted", isUploadingBaseline: "isUploadingBaseline", isMakingCurrentBaseline: "isMakingCurrentBaseline", isLive: "isLive", selfHealAnalysis: "selfHealAnalysis", getSelfHealLoadingStatesHandler: "getSelfHealLoadingStatesHandler", onStepClickHandler: "onStepClickHandler", onJsonPathCopiedHandler: "onJsonPathCopiedHandler", jumpToTimestampHandler: "jumpToTimestampHandler", step: "step" }, outputs: { debugPointChange: "debugPointChange", editStep: "editStep", addStepOptionSelect: "addStepOptionSelect", stepMoreOptionSelect: "stepMoreOptionSelect", makeCurrentBaseline: "makeCurrentBaseline", uploadBaseline: "uploadBaseline", analyze: "analyze", viewFullLogs: "viewFullLogs", selfHealAction: "selfHealAction", jsonPathCopied: "jsonPathCopied" }, host: { classAttribute: "cqa-ui-root" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-font-inter\" (click)=\"$event.stopPropagation()\">\n <!-- Header -->\n <div\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-p-2 cqa-cursor-pointer\"\n (click)=\"toggleHeader($event)\">\n <div *ngIf=\"showDebugIcon\" class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer cqa-rounded-full hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" (click)=\"onDebugPointClick($event)\" [attr.aria-label]=\"debugPointSet ? 'Remove debug point' : 'Set debug point'\">\n <svg *ngIf=\"debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" fill=\"#C63535\"/>\n </svg>\n <svg *ngIf=\"!debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" stroke=\"#C63535\" stroke-width=\"1.5\" fill=\"none\"/>\n </svg>\n </button>\n </div>\n <!-- Status Icon -->\n \n <div *ngIf=\"status.toLowerCase() === 'success'\" ><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <div *ngIf=\"status.toLowerCase() === 'failure' || status.toLowerCase() === 'failed'\"><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7.5 4.5L4.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 4.5L7.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <div *ngIf=\"status.toLowerCase() === 'pending'\"><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <div *ngIf=\"status.toLowerCase() === 'running'\"><svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/><path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/></svg></div>\n <!-- Skipped -->\n <div *ngIf=\"status.toLowerCase() === 'skipped'\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"12px\" viewBox=\"0 -960 960 960\" width=\"12px\" fill=\"#1f1f1f\"><path d=\"M660-240v-480h80v480h-80Zm-440 0v-480l360 240-360 240Zm80-240Zm0 90 136-90-136-90v180Z\"/></svg>\n </div>\n <!-- API Icon -->\n <div><svg width=\"20\" height=\"16\" viewBox=\"0 0 20 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"20\" height=\"16\" rx=\"4\" fill=\"#EDE9FE\"/><path d=\"M8 6.5L9.5 8L8 9.5M10.5 9.5H12M6.5 12H13.5C13.7652 12 14.0196 11.8946 14.2071 11.7071C14.3946 11.5196 14.5 11.2652 14.5 11V5C14.5 4.73478 14.3946 4.48043 14.2071 4.29289C14.0196 4.10536 13.7652 4 13.5 4H6.5C6.23478 4 5.98043 4.10536 5.79289 4.29289C5.60536 4.48043 5.5 4.73478 5.5 5V11C5.5 11.2652 5.60536 11.5196 5.79289 11.7071C5.98043 11.8946 6.23478 12 6.5 12Z\" stroke=\"#7F22FE\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n\n <!-- Step Number and Title -->\n <div class=\"cqa-flex-1 cqa-flex cqa-items-center cqa-gap-3 cqa-font-inter\">\n <span class=\"cqa-font-semibold cqa-text-[#334155] cqa-text-[14px] cqa-leading-[18px]\" style=\"word-break: break-word;\">\n {{ config?.stepNumber }}. <span [innerHTML]=\"config.title\"></span>\n </span>\n <span class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-[#7008E7] cqa-bg-[#EDE9FE] cqa-text-[10px] cqa-leading-[15px]\">\n API\n </span>\n <span class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-[#008236] cqa-bg-[#DCFCE7] cqa-text-[10px] cqa-leading-[15px]\">\n {{ config.method }}\n </span>\n <span *ngIf=\"config.stepDeleted\" class=\"cqa-px-1.5 cqa-py-[2px] cqa-rounded-[4px] cqa-text-[10px] cqa-leading-[12px] cqa-font-medium cqa-text-[#B42318] cqa-bg-[#FEF3F2] cqa-border cqa-border-[#FEE4E2]\">\n Deleted\n </span>\n </div>\n\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-font-inter\">\n <span *ngIf=\"selfHealAnalysis\" class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-[#097E53] cqa-bg-[#CFF2E5] cqa-text-[10px] cqa-leading-[15px] cqa-min-w-max cqa-flex cqa-items-center cqa-gap-[6px]\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"9\" height=\"9\" viewBox=\"0 0 9 9\" fill=\"none\">\n <path d=\"M4.50941 0C4.56489 0.0227384 4.58859 0.0782652 4.61131 0.129846C4.62269 0.1599 4.63314 0.190117 4.64329 0.220575C4.64726 0.232247 4.65123 0.243918 4.65532 0.255943C4.70806 0.413005 4.75504 0.571748 4.80229 0.73038C4.81297 0.76619 4.82369 0.801987 4.83442 0.837783C4.88905 1.02004 4.94327 1.2024 4.99719 1.38484C5.00476 1.41047 5.01234 1.43609 5.01992 1.46171C5.04128 1.53395 5.06262 1.60619 5.08383 1.67847C5.12867 1.8312 5.17473 1.98347 5.22378 2.13501C5.22807 2.14827 5.23236 2.16152 5.23677 2.17518C5.3642 2.565 5.54482 2.91437 5.8409 3.21196C5.84823 3.2197 5.85556 3.22744 5.86312 3.23541C5.9895 3.36437 6.15169 3.46771 6.3138 3.55111C6.32206 3.55542 6.33031 3.55974 6.33882 3.56419C6.81587 3.80925 7.38951 3.91704 7.90619 4.0605C8.1326 4.1234 8.3583 4.18829 8.58317 4.25603C8.59897 4.26079 8.61478 4.26554 8.63058 4.27028C8.67784 4.28445 8.725 4.29887 8.77211 4.31347C8.7831 4.31679 8.79408 4.32011 8.80539 4.32353C8.87029 4.34406 8.93239 4.36829 8.98566 4.41027C9.00191 4.44418 9.00191 4.44418 8.99748 4.4781C8.94564 4.52736 8.8942 4.55046 8.82578 4.573C8.816 4.57632 8.80622 4.57965 8.79614 4.58308C8.68061 4.62183 8.56351 4.65575 8.44626 4.68935C8.4222 4.6963 8.39814 4.70326 8.37408 4.71021C8.22571 4.75301 8.07708 4.7949 7.92829 4.83632C7.73232 4.89088 7.53663 4.94634 7.34113 5.00243C7.3091 5.01162 7.27706 5.02078 7.24501 5.02991C7.07671 5.07786 6.90923 5.12753 6.74314 5.18208C6.72937 5.18659 6.71559 5.1911 6.70139 5.19574C6.14511 5.38082 5.7211 5.72609 5.45571 6.23099C5.31263 6.51475 5.22823 6.82161 5.14214 7.12447C5.11884 7.20619 5.09409 7.28745 5.06905 7.36869C5.0494 7.43261 5.0302 7.49663 5.01149 7.56081C5.00926 7.56844 5.00703 7.57608 5.00473 7.58395C4.99394 7.62094 4.98319 7.65793 4.97252 7.69495C4.94519 7.78879 4.91578 7.88187 4.88555 7.97489C4.83191 8.14021 4.7831 8.30674 4.73459 8.4735C4.66144 8.72457 4.66144 8.72457 4.61997 8.84527C4.61721 8.85337 4.61446 8.86147 4.61163 8.86982C4.59649 8.91278 4.58092 8.95233 4.55226 8.9887C4.50867 8.99788 4.50867 8.99788 4.46951 9C4.42473 8.93759 4.39508 8.87711 4.37133 8.80508C4.36787 8.79487 4.36441 8.78466 4.36085 8.77415C4.31684 8.64248 4.27751 8.50946 4.23817 8.37646C4.22916 8.34604 4.22011 8.31564 4.21105 8.28524C4.1436 8.05863 4.07725 7.83174 4.01101 7.60481C3.73507 6.48224 3.73507 6.48224 3.039 5.57466C3.02784 5.56596 3.01669 5.55726 3.00519 5.5483C2.54913 5.19902 1.94834 5.06969 1.39815 4.91813C1.26207 4.88062 1.12605 4.84293 0.990032 4.80523C0.978138 4.80193 0.978138 4.80193 0.966003 4.79857C0.769811 4.74417 0.573674 4.68963 0.378224 4.63283C0.369956 4.63045 0.361688 4.62806 0.353169 4.62561C0.0528989 4.53883 0.0528989 4.53883 0.000646537 4.4781C-0.000831261 4.45054 -0.000831261 4.45054 0.0124689 4.42157C0.0670835 4.3704 0.120077 4.34848 0.19216 4.32619C0.202597 4.32284 0.213034 4.31948 0.223787 4.31603C0.255753 4.30582 0.287788 4.29584 0.319851 4.28592C0.329001 4.28305 0.338151 4.28017 0.347578 4.27722C0.412285 4.25693 0.477225 4.2374 0.542259 4.21809C0.55824 4.21332 0.55824 4.21332 0.574544 4.20846C0.852269 4.12587 1.13181 4.049 1.41126 3.97196C1.6195 3.91455 1.82738 3.85618 2.0346 3.79548C2.04413 3.79271 2.05365 3.78993 2.06346 3.78707C2.5435 3.64696 3.01278 3.44816 3.32274 3.0537C3.32738 3.04785 3.33202 3.042 3.3368 3.03597C3.68197 2.59815 3.81658 2.06572 3.96695 1.54621C4.01643 1.37534 4.06649 1.20464 4.11673 1.03399C4.13064 0.986733 4.14453 0.939471 4.15836 0.892194C4.21394 0.702289 4.27035 0.512642 4.33 0.323864C4.33558 0.306186 4.34114 0.288501 4.34666 0.270807C4.43017 0.00398761 4.43017 0.00398761 4.50941 0Z\" fill=\"#0DBD7D\"/>\n <path d=\"M7.23597 0.554859C7.29024 0.613599 7.30109 0.682631 7.31799 0.757638C7.37436 0.993269 7.43929 1.20993 7.66467 1.34681C7.80371 1.42035 7.96944 1.45381 8.1235 1.48541C8.18854 1.49902 8.24348 1.51709 8.29924 1.55321C8.31181 1.57229 8.31181 1.57229 8.31107 1.60549C8.29814 1.64588 8.28678 1.6589 8.25269 1.68533C8.21543 1.69726 8.21543 1.69726 8.17068 1.70653C8.15375 1.71025 8.13683 1.714 8.11992 1.71779C8.11086 1.7198 8.10181 1.72181 8.09247 1.72388C7.81696 1.78482 7.81696 1.78482 7.57882 1.92273C7.57108 1.92869 7.56333 1.93466 7.55536 1.9408C7.38516 2.08431 7.34916 2.32303 7.29793 2.52301C7.29499 2.53399 7.29206 2.54497 7.28903 2.55629C7.28649 2.56601 7.28395 2.57573 7.28133 2.58575C7.27028 2.61544 7.25881 2.63479 7.23597 2.65754C7.17234 2.66527 7.17234 2.66527 7.14139 2.65754C7.09216 2.62106 7.08114 2.5795 7.06828 2.52365C7.06613 2.51501 7.06398 2.50636 7.06176 2.49745C7.05489 2.46983 7.04824 2.44217 7.04164 2.41449C6.98979 2.19897 6.93126 1.98751 6.72451 1.86118C6.56293 1.77501 6.36646 1.73426 6.18587 1.70136C6.13637 1.69151 6.10802 1.67911 6.07738 1.64012C6.07073 1.60055 6.07073 1.60055 6.07738 1.56098C6.12447 1.51437 6.17402 1.50299 6.23772 1.48891C6.25778 1.48416 6.27784 1.47938 6.29789 1.47456C6.30825 1.47209 6.31861 1.46962 6.32929 1.46707C6.38212 1.45407 6.43443 1.43949 6.48673 1.42462C6.49623 1.42198 6.50573 1.41935 6.51552 1.41663C6.62182 1.38624 6.71356 1.34737 6.79854 1.27836C6.80647 1.27213 6.81439 1.26589 6.82255 1.25946C6.9548 1.14565 6.99974 0.974674 7.04053 0.815134C7.04364 0.803022 7.04675 0.79091 7.04995 0.778432C7.05614 0.754101 7.06222 0.729743 7.06817 0.705359C7.07243 0.688394 7.07243 0.688394 7.07678 0.671086C7.07927 0.660951 7.08175 0.650816 7.08431 0.640373C7.09521 0.608108 7.10952 0.582772 7.12957 0.554859C7.1681 0.536435 7.19515 0.544764 7.23597 0.554859Z\" fill=\"#075F3F\"/>\n <path d=\"M1.79545 6.2471C1.80951 6.24719 1.80951 6.24719 1.82386 6.24729C1.92477 6.25022 1.99304 6.28115 2.06736 6.34601C2.15384 6.43533 2.19377 6.53611 2.1915 6.6565C2.18178 6.75412 2.12158 6.83935 2.04773 6.90533C1.96081 6.97242 1.87313 6.99459 1.76206 6.99149C1.66841 6.98107 1.5803 6.93852 1.51393 6.87451C1.43138 6.76681 1.40725 6.66803 1.41935 6.53537C1.44433 6.43092 1.51637 6.34613 1.6085 6.28666C1.67251 6.25564 1.72399 6.24652 1.79545 6.2471Z\" fill=\"#0DBD7D\"/>\n </svg>\n Self-healed\n </span>\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-rounded-[4px] cqa-py-0.5 cqa-px-1 cqa-bg-[#6366F11A] cqa-ml-1 cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity\" \n *ngIf=\"step?.executedResult?.video_start_time\" \n [matTooltip]=\"'Jump to video time'\" \n matTooltipPosition=\"below\"\n (click)=\"onJumpToTimestamp($event)\">\n <mat-icon class=\"cqa-text-[#636363] !cqa-text-[10px] !cqa-w-[10px] !cqa-h-[10px]\">\n play_arrow\n </mat-icon>\n <span class=\"cqa-text-[8px] cqa-leading-[12px] cqa-font-normal cqa-text-[#636363]\">\n {{ formatDurationClock(step?.executedResult?.video_start_time || 0) }}\n </span>\n </div>\n <div *ngIf=\"isDebug\" class=\"cqa-flex cqa-items-center cqa-gap-0.5 cqa-text-[#9CA3AF]\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Edit\" (click)=\"onEditStep($event)\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">edit</mat-icon>\n </button>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Add\" [matMenuTriggerFor]=\"addStepMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">add</mat-icon>\n </button>\n <mat-menu #addStepMenu=\"matMenu\" class=\"cqa-add-step-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of addStepMenuOptions\" (click)=\"onAddStepOptionSelect(opt, $event)\">\n {{ opt.label }}\n </button>\n </mat-menu>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"More options\" [matMenuTriggerFor]=\"stepMoreMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">more_vert</mat-icon>\n </button>\n <mat-menu #stepMoreMenu=\"matMenu\" class=\"cqa-step-more-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of stepMoreMenuOptions\" (click)=\"onStepMoreOptionSelect(opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n </div>\n <span class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF]\">\n {{ formatDuration(config.duration) }}\n </span>\n <svg [class.cqa-rotate-180]=\"isExpanded\" class=\"cqa-transition-transform\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M3.5 5L7 8.5L10.5 5\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n </div>\n\n <!-- Expanded Content -->\n <div *ngIf=\"isExpanded\">\n <!-- Initial Actions -->\n <div *ngIf=\"config.initialActions && config.initialActions.length > 0\" class=\"cqa-flex cqa-flex-col cqa-gap-1 cqa-ml-9\">\n <div\n *ngFor=\"let action of config.initialActions\"\n class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-py-[5.5px] cqa-px-3\">\n \n <div *ngIf=\"action?.status?.toLowerCase() === 'success' || action?.status?.toLowerCase() === 'passed'\" >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Failure -->\n <div *ngIf=\"action?.status?.toLowerCase() === 'failure' || action?.status?.toLowerCase() === 'failed'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7.5 4.5L4.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 4.5L7.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Pending -->\n <div *ngIf=\"action?.status?.toLowerCase() === 'pending'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Running - Show spinner -->\n <div *ngIf=\"action?.status?.toLowerCase() === 'running'\">\n <svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n </div>\n\n\n <span class=\"cqa-flex-1 cqa-text-[13px] cqa-leading-[15px] cqa-text-[#364153]\" style=\"white-space: pre-line;\">{{ action.description }}</span>\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-metadata-key\">{{ formatDuration(action.duration) }}</span>\n </div>\n </div>\n\n <!-- Request Summary Card -->\n <div *ngIf=\"!isLive\" class=\"cqa-bg-[#FFFEF9] cqa-mt-1.5 cqa-ml-9 cqa-mr-6 cqa-p-4\" style=\"border-top: 1px solid #E4E4E4;\">\n \n <div class=\"cqa-bg-[#FCFCFC] cqa-rounded-lg cqa-p-3\" style=\"border: 1px solid #EDE9FE\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-mb-3 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\">\n <span>Request Summary</span>\n <div class=\"cqa-relative\">\n <button (click)=\"copyRequestSummary()\" class=\"cqa-flex cqa-items-center cqa-gap-1 p-0\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 4H5C4.44772 4 4 4.44772 4 5V10C4 10.5523 4.44772 11 5 11H10C10.5523 11 11 10.5523 11 10V5C11 4.44772 10.5523 4 10 4Z\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M2 8C1.45 8 1 7.55 1 7V2C1 1.45 1.45 1 2 1H7C7.55 1 8 1.45 8 2\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n Copy\n </button>\n <!-- Copied Tooltip -->\n <div \n *ngIf=\"showRequestSummaryCopied\" \n class=\"cqa-absolute cqa-right-0 cqa-top-full cqa-mt-1 cqa-px-2 cqa-py-1 cqa-bg-[#0B0B0B] cqa-text-white cqa-text-[10px] cqa-rounded cqa-whitespace-nowrap cqa-z-50 cqa-shadow-lg\"\n style=\"animation: fadeInOut 0.2s ease-in-out;\">\n Copied!\n </div>\n </div>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-cursor-pointer\" (dblclick)=\"copyRequestSummary()\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <span class=\"cqa-px-1 cqa-py-[2px] cqa-rounded cqa-font-medium cqa-text-[#008236] cqa-bg-[#DCFCE7] cqa-text-[10px] cqa-leading-[15px]\">\n {{ config.method }}\n </span>\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#0B0B0B]\">{{ config.endpoint }}</span>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-3\">\n <span *ngIf=\"config?.statusCode === 200 || config?.statusCode === 201\" class=\"cqa-flex cqa-items-center cqa-gap-1.5 cqa-px-1 cqa-py-[2px] cqa-rounded cqa-font-medium cqa-text-[#00A63E] cqa-bg-[#DCFCE7] cqa-text-[10px] cqa-leading-[15px]\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 3L4.5 8.5L2 6\" stroke=\"#00A63E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path></svg>\n {{ config.statusCode }}\n </span>\n <span *ngIf=\"config?.statusCode && config?.statusCode !== 200 && config?.statusCode !== 201\" class=\"cqa-flex cqa-items-center cqa-gap-1.5 cqa-px-1 cqa-py-[2px] cqa-rounded cqa-font-medium cqa-text-[#E7000B] cqa-bg-[#FFE2E2] cqa-text-[10px] cqa-leading-[15px]\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.5 3.5L3.5 10.5\" stroke=\"#E7000B\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M3.5 3.5L10.5 10.5\" stroke=\"#E7000B\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n {{ config.statusCode }}\n </span>\n <div class=\"cqa-flex cqa-items-center cqa-gap-1.5 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\" *ngIf=\"config?.responseTime\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6.99999 12.8334C10.2217 12.8334 12.8333 10.2217 12.8333 7.00008C12.8333 3.77842 10.2217 1.16675 6.99999 1.16675C3.77833 1.16675 1.16666 3.77842 1.16666 7.00008C1.16666 10.2217 3.77833 12.8334 6.99999 12.8334Z\" stroke=\"#636363\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7 3.5V7L9.33333 8.16667\" stroke=\"#636363\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <span>{{ config.responseTime }}ms</span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Request/Response Headers -->\n <div class=\"cqa-grid cqa-grid-cols-2 cqa-gap-3 cqa-mt-4\" *ngIf=\"config?.requestHeaders || config?.responseHeaders\">\n <!-- Request Headers -->\n <div class=\"cqa-bg-[#FCFCFC] cqa-rounded-lg cqa-p-3 cqa-flex cqa-flex-col\" style=\"border: 1px solid #EDE9FE\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2 cqa-mb-2\">\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\">Request Headers</span>\n <div class=\"cqa-relative\">\n <button (click)=\"copyRequestHeaders()\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 4H5C4.44772 4 4 4.44772 4 5V10C4 10.5523 4.44772 11 5 11H10C10.5523 11 11 10.5523 11 10V5C11 4.44772 10.5523 4 10 4Z\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M2 8C1.45 8 1 7.55 1 7V2C1 1.45 1.45 1 2 1H7C7.55 1 8 1.45 8 2\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </button>\n <!-- Copied Tooltip -->\n <div \n *ngIf=\"showRequestHeadersCopied\" \n class=\"cqa-absolute cqa-right-0 cqa-top-full cqa-mt-1 cqa-px-2 cqa-py-1 cqa-bg-[#0B0B0B] cqa-text-white cqa-text-[10px] cqa-rounded cqa-whitespace-nowrap cqa-z-50 cqa-shadow-lg\"\n style=\"animation: fadeInOut 0.2s ease-in-out;\">\n Copied\n </div>\n </div>\n </div>\n <pre *ngIf=\"config.requestHeaders\" class=\"cqa-h-full cqa-text-[12px] cqa-text-[#0B0B0B] cqa-bg-[#F8F8F8] cqa-p-2 cqa-m-0 cqa-rounded cqa-overflow-auto cqa-max-h-[114px] cqa-cursor-pointer\" style=\"scrollbar-width: thin;\" (dblclick)=\"copyJsonPath($event, config.requestHeaders, 'requestHeaders')\">{{ formatJson(config.requestHeaders) }}</pre>\n </div>\n\n <!-- Response Headers -->\n <div class=\"cqa-bg-[#FCFCFC] cqa-rounded-lg cqa-p-3 cqa-flex cqa-flex-col\" style=\"border: 1px solid #EDE9FE\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-mb-2\">\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\">Response Headers</span>\n <div class=\"cqa-relative\">\n <button (click)=\"copyResponseHeaders()\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 4H5C4.44772 4 4 4.44772 4 5V10C4 10.5523 4.44772 11 5 11H10C10.5523 11 11 10.5523 11 10V5C11 4.44772 10.5523 4 10 4Z\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M2 8C1.45 8 1 7.55 1 7V2C1 1.45 1.45 1 2 1H7C7.55 1 8 1.45 8 2\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </button>\n <!-- Copied Tooltip -->\n <div \n *ngIf=\"showResponseHeadersCopied\" \n class=\"cqa-absolute cqa-right-0 cqa-top-full cqa-mt-1 cqa-px-2 cqa-py-1 cqa-bg-[#0B0B0B] cqa-text-white cqa-text-[10px] cqa-rounded cqa-whitespace-nowrap cqa-z-50 cqa-shadow-lg\"\n style=\"animation: fadeInOut 0.2s ease-in-out;\">\n Copied\n </div>\n </div>\n </div>\n <pre *ngIf=\"config.responseHeaders\" [ngClass]=\"{'cqa-bg-[#FEF2F2] cqa-text-[#C10007]': config.statusCode >= 400}\" class=\"cqa-h-full cqa-text-[12px] cqa-p-2 cqa-m-0 cqa-rounded cqa-overflow-auto cqa-max-h-[114px] cqa-cursor-pointer\" style=\"scrollbar-width: thin;\" (dblclick)=\"copyJsonPath($event, config.responseHeaders, 'responseHeaders')\">{{ formatJson(config.responseHeaders) }}</pre>\n </div>\n </div>\n\n <!-- Request/Response Bodies -->\n <div class=\"cqa-grid cqa-grid-cols-2 cqa-gap-3 cqa-mt-4\" *ngIf=\"config?.requestBody || config?.responseBody\">\n <!-- Request Body -->\n <div class=\"cqa-bg-[#FCFCFC] cqa-rounded-lg cqa-p-3 cqa-flex cqa-flex-col\" style=\"border: 1px solid #EDE9FE\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2 cqa-mb-2\">\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\">Request Body</span>\n <div class=\"cqa-relative\">\n <button (click)=\"copyRequestBody()\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 4H5C4.44772 4 4 4.44772 4 5V10C4 10.5523 4.44772 11 5 11H10C10.5523 11 11 10.5523 11 10V5C11 4.44772 10.5523 4 10 4Z\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M2 8C1.45 8 1 7.55 1 7V2C1 1.45 1.45 1 2 1H7C7.55 1 8 1.45 8 2\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </button>\n <!-- Copied Tooltip -->\n <div \n *ngIf=\"showRequestBodyCopied\" \n class=\"cqa-absolute cqa-right-0 cqa-top-full cqa-mt-1 cqa-px-2 cqa-py-1 cqa-bg-[#0B0B0B] cqa-text-white cqa-text-[10px] cqa-rounded cqa-whitespace-nowrap cqa-z-50 cqa-shadow-lg\"\n style=\"animation: fadeInOut 0.2s ease-in-out;\">\n Copied\n </div>\n </div>\n </div>\n <pre *ngIf=\"config.requestBody\" class=\"cqa-h-full cqa-text-[12px] cqa-text-[#0B0B0B] cqa-bg-[#F8F8F8] cqa-p-2 cqa-m-0 cqa-rounded cqa-overflow-auto cqa-max-h-[114px] cqa-cursor-pointer\" style=\"scrollbar-width: thin;\" (dblclick)=\"copyJsonPath($event, config.requestBody, 'requestBody')\">{{ formatJson(config.requestBody) }}</pre>\n </div>\n\n <!-- Response Body -->\n <div class=\"cqa-bg-[#FCFCFC] cqa-rounded-lg cqa-p-3 cqa-flex cqa-flex-col\" style=\"border: 1px solid #EDE9FE\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-mb-2\">\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\">Response Body</span>\n <div class=\"cqa-relative\">\n <button (click)=\"copyResponseBody()\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 4H5C4.44772 4 4 4.44772 4 5V10C4 10.5523 4.44772 11 5 11H10C10.5523 11 11 10.5523 11 10V5C11 4.44772 10.5523 4 10 4Z\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M2 8C1.45 8 1 7.55 1 7V2C1 1.45 1.45 1 2 1H7C7.55 1 8 1.45 8 2\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </button>\n <!-- Copied Tooltip -->\n <div \n *ngIf=\"showResponseBodyCopied\" \n class=\"cqa-absolute cqa-right-0 cqa-top-full cqa-mt-1 cqa-px-2 cqa-py-1 cqa-bg-[#0B0B0B] cqa-text-white cqa-text-[10px] cqa-rounded cqa-whitespace-nowrap cqa-z-50 cqa-shadow-lg\"\n style=\"animation: fadeInOut 0.2s ease-in-out;\">\n Copied\n </div>\n </div>\n </div>\n <pre *ngIf=\"config.responseBody\" [ngClass]=\"{'cqa-bg-[#FEF2F2] cqa-text-[#C10007]': config.statusCode >= 400}\" class=\"cqa-h-full cqa-text-[12px] cqa-p-2 cqa-m-0 cqa-rounded cqa-overflow-auto cqa-max-h-[114px] cqa-cursor-pointer\" style=\"scrollbar-width: thin;\" (dblclick)=\"copyJsonPath($event, config.responseBody, 'responseBody')\">{{ formatJson(config.responseBody) }}</pre>\n </div>\n </div>\n\n <!-- Assertions -->\n <div *ngIf=\"config.assertions && config.assertions.length > 0\" class=\"cqa-bg-[#FCFCFC] cqa-rounded-lg cqa-p-3 cqa-flex cqa-flex-col cqa-mt-4\" style=\"border: 1px solid #EDE9FE\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2 cqa-mb-3\">\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\">Assertions</span>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium\">\n <span class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-text-[#00A63E]\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 3L4.5 8.5L2 6\" stroke=\"#00A63E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n {{ getPassedAssertions() }} passed\n </span>\n <span class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-text-[#E7000B]\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M9 3L3 9\" stroke=\"#E7000B\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M3 3L9 9\" stroke=\"#E7000B\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n {{ getFailedAssertions() }} failed\n </span>\n </div>\n </div>\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <div\n *ngFor=\"let assertion of config.assertions\"\n class=\"cqa-flex cqa-justify-between cqa-gap-2 cqa-flex-wrap cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363] cqa-px-3 cqa-py-1 cqa-rounded-md cqa-items-center\"\n [ngStyle]=\"{\n 'background-color': assertion.status === 'passed' ? '#ECFDF3' : '#FEF2F2',\n 'border': assertion.status === 'passed'\n ? '1px solid #A7F3D0'\n : '1px solid #FFC9C9'\n }\"\n >\n <div class=\"cqa-flex-1 cqa-flex cqa-items-center cqa-gap-2\">\n <div>\n <!-- Passed -->\n <ng-container *ngIf=\"assertion.status === 'passed'; else failedIcon\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"20\" height=\"20\" rx=\"10\" fill=\"#DCFCE7\"/><path d=\"M14 7L8.5 12.5L6 10\" stroke=\"#00A63E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </ng-container>\n \n <!-- Failed -->\n <ng-template #failedIcon>\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"20\" height=\"20\" rx=\"10\" fill=\"#FFE2E2\"/><path d=\"M13 7L7 13\" stroke=\"#E7000B\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7 7L13 13\" stroke=\"#E7000B\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </ng-template>\n </div>\n <div class=\"cqa-text-[12px] cqa-leading-[15px]\" \n [ngClass]=\"{\n 'cqa-text-[#9F0712]': assertion.status !== 'passed',\n 'cqa-text-[#016630]': assertion.status === 'passed'\n }\"\n >\n {{ assertion.description }}\n </div>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-4 cqa-max-w-[200px]\">\n <div>\n <span>Expected:</span>\n <span style=\"word-break: break-word;\" [ngClass]=\"assertion.status === 'passed' ? 'cqa-text-[#008236]' : 'cqa-text-[#0B0B0B]'\">\n {{ assertion.expected }}\n </span>\n </div>\n <div>\n <span>Actual:</span>\n <span style=\"word-break: break-word;\" [ngClass]=\"assertion.status === 'passed' ? 'cqa-text-green-600' : 'cqa-text-[#E7000B]'\">\n {{ assertion.actual }}\n </span>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Self Heal Analysis -->\n <cqa-self-heal-analysis \n *ngIf=\"selfHealAnalysis\" \n [id]=\"step?.testStepId\"\n [originalLocator]=\"selfHealAnalysis.originalLocator\"\n [healedLocator]=\"selfHealAnalysis.healedLocator\"\n [confidence]=\"selfHealAnalysis.confidence\"\n [healMethod]=\"selfHealAnalysis.healMethod\"\n [isLoadingAccept]=\"getSelfHealLoadingStatesHandler ? getSelfHealLoadingStatesHandler().isLoadingAccept?.[step?.testStepId] : false\"\n [isLoadingModifyAccept]=\"getSelfHealLoadingStatesHandler ? getSelfHealLoadingStatesHandler().isLoadingModifyAccept?.[step?.testStepId] : false\"\n (action)=\"onSelfHealAction($event)\">\n </cqa-self-heal-analysis>\n\n <!-- Timing Breakdown -->\n <div *ngIf=\"config.timingBreakdown\" class=\"cqa-flex cqa-items-center cqa-justify-end cqa-gap-5 cqa-pt-1.5 cqa-px-4 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF]\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <span>Timing breakdown</span>\n </div>\n <span class=\"cqa-text-dialog-muted cqa-flex cqa-items-center cqa-gap-3\">\n <div>\n App <span class=\"cqa-text-gray-700\">{{ formatDuration(config.timingBreakdown.app) }}</span>\n </div>\n <div><svg width=\"1\" height=\"11\" viewBox=\"0 0 1 11\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M-3.8147e-06 10.32V-7.15256e-07H0.959996V10.32H-3.8147e-06Z\" fill=\"#E5E7EB\"/></svg></div>\n <div>\n Tool <span class=\"cqa-text-gray-700\">{{ formatDuration(config.timingBreakdown.tool) }}</span>\n </div>\n </span>\n </div>\n </div>\n\n <!-- View More Failed Step Button - shown when expanded and failure details exist -->\n <div *ngIf=\"showViewMoreButton\" class=\"cqa-mt-2 cqa-px-4\">\n <cqa-view-more-failed-step-button\n [timingBreakdown]=\"timingBreakdown\"\n [subSteps]=\"getSubStepsForFailedStep()\"\n [failureDetails]=\"failureDetails\"\n [isExpanded]=\"showFailedStepDetails\"\n (viewMoreClick)=\"onViewMoreFailedStepClick($event)\">\n </cqa-view-more-failed-step-button>\n </div>\n\n <!-- Updated Failed Step Component - shown when button is clicked -->\n <div *ngIf=\"showViewMoreButton && showFailedStepDetails && failureDetails\" class=\"cqa-mt-2 cqa-px-4\">\n <cqa-updated-failed-step\n [testStepResultId]=\"testStepResultId\"\n [timingBreakdown]=\"timingBreakdown\"\n [expanded]=\"true\"\n [subSteps]=\"getSubStepsForFailedStep()\"\n [failureDetails]=\"failureDetails\"\n [reasoning]=\"reasoning\"\n [confidence]=\"confidence\"\n [isUploadingBaseline]=\"isUploadingBaseline\"\n [isMakingCurrentBaseline]=\"isMakingCurrentBaseline\"\n [isLive]=\"isLive\"\n (makeCurrentBaseline)=\"onMakeCurrentBaseline($event)\"\n (uploadBaseline)=\"onUploadBaseline($event)\"\n (analyze)=\"onAnalyze()\"\n (viewFullLogs)=\"onViewFullLogs()\">\n </cqa-updated-failed-step>\n </div>\n</div>\n", components: [{ type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i2$1.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { type: i2$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { type: SelfHealAnalysisComponent, selector: "cqa-self-heal-analysis", inputs: ["id", "originalLocator", "healedLocator", "confidence", "healMethod", "isLoadingAccept", "isLoadingModifyAccept"], outputs: ["action"] }, { type: ViewMoreFailedStepButtonComponent, selector: "cqa-view-more-failed-step-button", inputs: ["timingBreakdown", "subSteps", "failureDetails", "isExpanded"], outputs: ["viewMoreClick"] }, { type: UpdatedFailedStepComponent, selector: "cqa-updated-failed-step", inputs: ["timingBreakdown", "testStepResultId", "expanded", "subSteps", "failureDetails", "reasoning", "confidence", "isUploadingBaseline", "isMakingCurrentBaseline", "isLive"], outputs: ["makeCurrentBaseline", "uploadBaseline", "analyze", "viewFullLogs"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { type: i2$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
|
|
12843
|
+
ApiStepComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: ApiStepComponent, selector: "cqa-api-step", inputs: { id: "id", testStepResultId: "testStepResultId", stepNumber: "stepNumber", title: "title", status: "status", duration: "duration", timingBreakdown: "timingBreakdown", expanded: "expanded", method: "method", endpoint: "endpoint", statusCode: "statusCode", responseTime: "responseTime", requestBody: "requestBody", responseBody: "responseBody", requestHeaders: "requestHeaders", responseHeaders: "responseHeaders", assertions: "assertions", initialActions: "initialActions", isDebug: "isDebug", debugPointSet: "debugPointSet", addStepMenuOptions: "addStepMenuOptions", stepMoreMenuOptions: "stepMoreMenuOptions", failureDetails: "failureDetails", reasoning: "reasoning", confidence: "confidence", stepDeleted: "stepDeleted", isUploadingBaseline: "isUploadingBaseline", isMakingCurrentBaseline: "isMakingCurrentBaseline", isLive: "isLive", selfHealAnalysis: "selfHealAnalysis", getSelfHealLoadingStatesHandler: "getSelfHealLoadingStatesHandler", onStepClickHandler: "onStepClickHandler", onJsonPathCopiedHandler: "onJsonPathCopiedHandler", jumpToTimestampHandler: "jumpToTimestampHandler", step: "step" }, outputs: { debugPointChange: "debugPointChange", editStep: "editStep", addStepOptionSelect: "addStepOptionSelect", stepMoreOptionSelect: "stepMoreOptionSelect", makeCurrentBaseline: "makeCurrentBaseline", uploadBaseline: "uploadBaseline", analyze: "analyze", viewFullLogs: "viewFullLogs", selfHealAction: "selfHealAction", jsonPathCopied: "jsonPathCopied" }, host: { classAttribute: "cqa-ui-root" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-font-inter\" (click)=\"$event.stopPropagation()\">\n <!-- Header -->\n <div\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-p-2 cqa-cursor-pointer\"\n (click)=\"toggleHeader($event)\">\n <div *ngIf=\"showDebugIcon\" class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer cqa-rounded-full hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" (click)=\"onDebugPointClick($event)\" [attr.aria-label]=\"debugPointSet ? 'Remove debug point' : 'Set debug point'\">\n <svg *ngIf=\"debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" fill=\"#C63535\"/>\n </svg>\n <svg *ngIf=\"!debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" stroke=\"#C63535\" stroke-width=\"1.5\" fill=\"none\"/>\n </svg>\n </button>\n </div>\n <!-- Status Icon -->\n \n <div *ngIf=\"status.toLowerCase() === 'success'\" ><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <div *ngIf=\"status.toLowerCase() === 'failure' || status.toLowerCase() === 'failed'\"><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7.5 4.5L4.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 4.5L7.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <div *ngIf=\"status.toLowerCase() === 'pending'\"><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <div *ngIf=\"status.toLowerCase() === 'running'\"><svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/><path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/></svg></div>\n <!-- Skipped -->\n <div *ngIf=\"status.toLowerCase() === 'skipped'\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"12px\" viewBox=\"0 -960 960 960\" width=\"12px\" fill=\"#1f1f1f\"><path d=\"M660-240v-480h80v480h-80Zm-440 0v-480l360 240-360 240Zm80-240Zm0 90 136-90-136-90v180Z\"/></svg>\n </div>\n <!-- API Icon -->\n <div><svg width=\"20\" height=\"16\" viewBox=\"0 0 20 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"20\" height=\"16\" rx=\"4\" fill=\"#EDE9FE\"/><path d=\"M8 6.5L9.5 8L8 9.5M10.5 9.5H12M6.5 12H13.5C13.7652 12 14.0196 11.8946 14.2071 11.7071C14.3946 11.5196 14.5 11.2652 14.5 11V5C14.5 4.73478 14.3946 4.48043 14.2071 4.29289C14.0196 4.10536 13.7652 4 13.5 4H6.5C6.23478 4 5.98043 4.10536 5.79289 4.29289C5.60536 4.48043 5.5 4.73478 5.5 5V11C5.5 11.2652 5.60536 11.5196 5.79289 11.7071C5.98043 11.8946 6.23478 12 6.5 12Z\" stroke=\"#7F22FE\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n\n <!-- Step Number and Title -->\n <div class=\"cqa-flex-1 cqa-flex cqa-items-center cqa-gap-3 cqa-font-inter\">\n <span class=\"cqa-font-semibold cqa-text-[#334155] cqa-text-[14px] cqa-leading-[18px]\" style=\"word-break: break-word;\">\n {{ config?.stepNumber }}. <span [innerHTML]=\"config.title\"></span>\n </span>\n <span class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-[#7008E7] cqa-bg-[#EDE9FE] cqa-text-[10px] cqa-leading-[15px]\">\n API\n </span>\n <span class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-[#008236] cqa-bg-[#DCFCE7] cqa-text-[10px] cqa-leading-[15px]\">\n {{ config.method }}\n </span>\n <span *ngIf=\"config.stepDeleted\" class=\"cqa-px-1.5 cqa-py-[2px] cqa-rounded-[4px] cqa-text-[10px] cqa-leading-[12px] cqa-font-medium cqa-text-[#B42318] cqa-bg-[#FEF3F2] cqa-border cqa-border-[#FEE4E2]\">\n Deleted\n </span>\n </div>\n\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-font-inter\">\n <span *ngIf=\"selfHealAnalysis\" class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-[#097E53] cqa-bg-[#CFF2E5] cqa-text-[10px] cqa-leading-[15px] cqa-min-w-max cqa-flex cqa-items-center cqa-gap-[6px]\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"9\" height=\"9\" viewBox=\"0 0 9 9\" fill=\"none\">\n <path d=\"M4.50941 0C4.56489 0.0227384 4.58859 0.0782652 4.61131 0.129846C4.62269 0.1599 4.63314 0.190117 4.64329 0.220575C4.64726 0.232247 4.65123 0.243918 4.65532 0.255943C4.70806 0.413005 4.75504 0.571748 4.80229 0.73038C4.81297 0.76619 4.82369 0.801987 4.83442 0.837783C4.88905 1.02004 4.94327 1.2024 4.99719 1.38484C5.00476 1.41047 5.01234 1.43609 5.01992 1.46171C5.04128 1.53395 5.06262 1.60619 5.08383 1.67847C5.12867 1.8312 5.17473 1.98347 5.22378 2.13501C5.22807 2.14827 5.23236 2.16152 5.23677 2.17518C5.3642 2.565 5.54482 2.91437 5.8409 3.21196C5.84823 3.2197 5.85556 3.22744 5.86312 3.23541C5.9895 3.36437 6.15169 3.46771 6.3138 3.55111C6.32206 3.55542 6.33031 3.55974 6.33882 3.56419C6.81587 3.80925 7.38951 3.91704 7.90619 4.0605C8.1326 4.1234 8.3583 4.18829 8.58317 4.25603C8.59897 4.26079 8.61478 4.26554 8.63058 4.27028C8.67784 4.28445 8.725 4.29887 8.77211 4.31347C8.7831 4.31679 8.79408 4.32011 8.80539 4.32353C8.87029 4.34406 8.93239 4.36829 8.98566 4.41027C9.00191 4.44418 9.00191 4.44418 8.99748 4.4781C8.94564 4.52736 8.8942 4.55046 8.82578 4.573C8.816 4.57632 8.80622 4.57965 8.79614 4.58308C8.68061 4.62183 8.56351 4.65575 8.44626 4.68935C8.4222 4.6963 8.39814 4.70326 8.37408 4.71021C8.22571 4.75301 8.07708 4.7949 7.92829 4.83632C7.73232 4.89088 7.53663 4.94634 7.34113 5.00243C7.3091 5.01162 7.27706 5.02078 7.24501 5.02991C7.07671 5.07786 6.90923 5.12753 6.74314 5.18208C6.72937 5.18659 6.71559 5.1911 6.70139 5.19574C6.14511 5.38082 5.7211 5.72609 5.45571 6.23099C5.31263 6.51475 5.22823 6.82161 5.14214 7.12447C5.11884 7.20619 5.09409 7.28745 5.06905 7.36869C5.0494 7.43261 5.0302 7.49663 5.01149 7.56081C5.00926 7.56844 5.00703 7.57608 5.00473 7.58395C4.99394 7.62094 4.98319 7.65793 4.97252 7.69495C4.94519 7.78879 4.91578 7.88187 4.88555 7.97489C4.83191 8.14021 4.7831 8.30674 4.73459 8.4735C4.66144 8.72457 4.66144 8.72457 4.61997 8.84527C4.61721 8.85337 4.61446 8.86147 4.61163 8.86982C4.59649 8.91278 4.58092 8.95233 4.55226 8.9887C4.50867 8.99788 4.50867 8.99788 4.46951 9C4.42473 8.93759 4.39508 8.87711 4.37133 8.80508C4.36787 8.79487 4.36441 8.78466 4.36085 8.77415C4.31684 8.64248 4.27751 8.50946 4.23817 8.37646C4.22916 8.34604 4.22011 8.31564 4.21105 8.28524C4.1436 8.05863 4.07725 7.83174 4.01101 7.60481C3.73507 6.48224 3.73507 6.48224 3.039 5.57466C3.02784 5.56596 3.01669 5.55726 3.00519 5.5483C2.54913 5.19902 1.94834 5.06969 1.39815 4.91813C1.26207 4.88062 1.12605 4.84293 0.990032 4.80523C0.978138 4.80193 0.978138 4.80193 0.966003 4.79857C0.769811 4.74417 0.573674 4.68963 0.378224 4.63283C0.369956 4.63045 0.361688 4.62806 0.353169 4.62561C0.0528989 4.53883 0.0528989 4.53883 0.000646537 4.4781C-0.000831261 4.45054 -0.000831261 4.45054 0.0124689 4.42157C0.0670835 4.3704 0.120077 4.34848 0.19216 4.32619C0.202597 4.32284 0.213034 4.31948 0.223787 4.31603C0.255753 4.30582 0.287788 4.29584 0.319851 4.28592C0.329001 4.28305 0.338151 4.28017 0.347578 4.27722C0.412285 4.25693 0.477225 4.2374 0.542259 4.21809C0.55824 4.21332 0.55824 4.21332 0.574544 4.20846C0.852269 4.12587 1.13181 4.049 1.41126 3.97196C1.6195 3.91455 1.82738 3.85618 2.0346 3.79548C2.04413 3.79271 2.05365 3.78993 2.06346 3.78707C2.5435 3.64696 3.01278 3.44816 3.32274 3.0537C3.32738 3.04785 3.33202 3.042 3.3368 3.03597C3.68197 2.59815 3.81658 2.06572 3.96695 1.54621C4.01643 1.37534 4.06649 1.20464 4.11673 1.03399C4.13064 0.986733 4.14453 0.939471 4.15836 0.892194C4.21394 0.702289 4.27035 0.512642 4.33 0.323864C4.33558 0.306186 4.34114 0.288501 4.34666 0.270807C4.43017 0.00398761 4.43017 0.00398761 4.50941 0Z\" fill=\"#0DBD7D\"/>\n <path d=\"M7.23597 0.554859C7.29024 0.613599 7.30109 0.682631 7.31799 0.757638C7.37436 0.993269 7.43929 1.20993 7.66467 1.34681C7.80371 1.42035 7.96944 1.45381 8.1235 1.48541C8.18854 1.49902 8.24348 1.51709 8.29924 1.55321C8.31181 1.57229 8.31181 1.57229 8.31107 1.60549C8.29814 1.64588 8.28678 1.6589 8.25269 1.68533C8.21543 1.69726 8.21543 1.69726 8.17068 1.70653C8.15375 1.71025 8.13683 1.714 8.11992 1.71779C8.11086 1.7198 8.10181 1.72181 8.09247 1.72388C7.81696 1.78482 7.81696 1.78482 7.57882 1.92273C7.57108 1.92869 7.56333 1.93466 7.55536 1.9408C7.38516 2.08431 7.34916 2.32303 7.29793 2.52301C7.29499 2.53399 7.29206 2.54497 7.28903 2.55629C7.28649 2.56601 7.28395 2.57573 7.28133 2.58575C7.27028 2.61544 7.25881 2.63479 7.23597 2.65754C7.17234 2.66527 7.17234 2.66527 7.14139 2.65754C7.09216 2.62106 7.08114 2.5795 7.06828 2.52365C7.06613 2.51501 7.06398 2.50636 7.06176 2.49745C7.05489 2.46983 7.04824 2.44217 7.04164 2.41449C6.98979 2.19897 6.93126 1.98751 6.72451 1.86118C6.56293 1.77501 6.36646 1.73426 6.18587 1.70136C6.13637 1.69151 6.10802 1.67911 6.07738 1.64012C6.07073 1.60055 6.07073 1.60055 6.07738 1.56098C6.12447 1.51437 6.17402 1.50299 6.23772 1.48891C6.25778 1.48416 6.27784 1.47938 6.29789 1.47456C6.30825 1.47209 6.31861 1.46962 6.32929 1.46707C6.38212 1.45407 6.43443 1.43949 6.48673 1.42462C6.49623 1.42198 6.50573 1.41935 6.51552 1.41663C6.62182 1.38624 6.71356 1.34737 6.79854 1.27836C6.80647 1.27213 6.81439 1.26589 6.82255 1.25946C6.9548 1.14565 6.99974 0.974674 7.04053 0.815134C7.04364 0.803022 7.04675 0.79091 7.04995 0.778432C7.05614 0.754101 7.06222 0.729743 7.06817 0.705359C7.07243 0.688394 7.07243 0.688394 7.07678 0.671086C7.07927 0.660951 7.08175 0.650816 7.08431 0.640373C7.09521 0.608108 7.10952 0.582772 7.12957 0.554859C7.1681 0.536435 7.19515 0.544764 7.23597 0.554859Z\" fill=\"#075F3F\"/>\n <path d=\"M1.79545 6.2471C1.80951 6.24719 1.80951 6.24719 1.82386 6.24729C1.92477 6.25022 1.99304 6.28115 2.06736 6.34601C2.15384 6.43533 2.19377 6.53611 2.1915 6.6565C2.18178 6.75412 2.12158 6.83935 2.04773 6.90533C1.96081 6.97242 1.87313 6.99459 1.76206 6.99149C1.66841 6.98107 1.5803 6.93852 1.51393 6.87451C1.43138 6.76681 1.40725 6.66803 1.41935 6.53537C1.44433 6.43092 1.51637 6.34613 1.6085 6.28666C1.67251 6.25564 1.72399 6.24652 1.79545 6.2471Z\" fill=\"#0DBD7D\"/>\n </svg>\n Self-healed\n </span>\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-rounded-[4px] cqa-py-0.5 cqa-px-1 cqa-bg-[#6366F11A] cqa-ml-1 cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity\" \n *ngIf=\"step?.executedResult?.video_start_time\" \n [matTooltip]=\"'Jump to video time'\" \n matTooltipPosition=\"below\"\n (click)=\"onJumpToTimestamp($event)\">\n <mat-icon class=\"cqa-text-[#636363] !cqa-text-[10px] !cqa-w-[10px] !cqa-h-[10px]\">\n play_arrow\n </mat-icon>\n <span class=\"cqa-text-[8px] cqa-leading-[12px] cqa-font-normal cqa-text-[#636363]\">\n {{ formatDurationClock(step?.executedResult?.video_start_time || 0) }}\n </span>\n </div>\n <div *ngIf=\"isDebug\" class=\"cqa-flex cqa-items-center cqa-gap-0.5 cqa-text-[#9CA3AF]\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Edit\" (click)=\"onEditStep($event)\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">edit</mat-icon>\n </button>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Add\" [matMenuTriggerFor]=\"addStepMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">add</mat-icon>\n </button>\n <mat-menu #addStepMenu=\"matMenu\" class=\"cqa-add-step-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of addStepMenuOptions\" (click)=\"onAddStepOptionSelect(opt, $event)\">\n {{ opt.label }}\n </button>\n </mat-menu>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"More options\" [matMenuTriggerFor]=\"stepMoreMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">more_vert</mat-icon>\n </button>\n <mat-menu #stepMoreMenu=\"matMenu\" class=\"cqa-step-more-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of stepMoreMenuOptions\" (click)=\"onStepMoreOptionSelect(opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n </div>\n <span class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF]\">\n {{ formatDuration(config.duration) }}\n </span>\n <svg [class.cqa-rotate-180]=\"isExpanded\" class=\"cqa-transition-transform\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M3.5 5L7 8.5L10.5 5\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n </div>\n\n <!-- Expanded Content -->\n <div *ngIf=\"isExpanded\">\n <!-- Initial Actions -->\n <div *ngIf=\"config.initialActions && config.initialActions.length > 0\" class=\"cqa-flex cqa-flex-col cqa-gap-1 cqa-ml-9\">\n <!-- Single loop: render all entries in chronological order -->\n <ng-container *ngFor=\"let action of (isLive ? processedInitialActions : processedInitialActionsForRunResult)\">\n <!-- AI_AUTO_HEAL_SUCCESS/FAILED: render with ai-agent-step style (both live and run result screens) -->\n <cqa-ai-logs-with-reasoning\n *ngIf=\"$any(action).isAiAutoHealResult\"\n [status]=\"action.status\"\n [text]=\"$any(action).text || action?.value\"\n [description]=\"$any(action).description || action?.text || action?.value\"\n [reasoning]=\"$any(action).reasoning || action?.reasoning\"\n [duration]=\"action.duration\">\n </cqa-ai-logs-with-reasoning>\n\n <!-- Regular initial actions -->\n <div\n *ngIf=\"!$any(action).isAiAutoHealResult\"\n class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-py-[5.5px] cqa-px-3\">\n \n <div *ngIf=\"action?.status?.toLowerCase() === 'success' || action?.status?.toLowerCase() === 'passed'\" >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Failure -->\n <div *ngIf=\"action?.status?.toLowerCase() === 'failure' || action?.status?.toLowerCase() === 'failed'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7.5 4.5L4.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 4.5L7.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Pending -->\n <div *ngIf=\"action?.status?.toLowerCase() === 'pending'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Running - Show spinner (also used for active WAIT_FOR_LOCATOR countdown in live mode) -->\n <div *ngIf=\"action?.status?.toLowerCase() === 'running'\">\n <svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n </div>\n\n <!-- Action Description -->\n <span class=\"cqa-flex-1 cqa-text-[13px] cqa-leading-[15px] cqa-text-[#364153]\" style=\"white-space: pre-line; word-break: break-word;\">\n {{ $any(action).description || $any(action).text }}\n <!-- Countdown for active WAIT_FOR_LOCATOR in live mode -->\n <span *ngIf=\"isLive && $any(action).remainingSeconds != null\" class=\"cqa-text-[#F97316] cqa-font-medium cqa-ml-1\">({{ $any(action).remainingSeconds }}s remaining)</span>\n </span>\n\n <!-- Action Duration -->\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-metadata-key\">\n {{ formatDuration(action.duration) }}\n </span>\n </div>\n </ng-container>\n </div>\n\n <!-- Request Summary Card -->\n <div *ngIf=\"!isLive\" class=\"cqa-bg-[#FFFEF9] cqa-mt-1.5 cqa-ml-9 cqa-mr-6 cqa-p-4\" style=\"border-top: 1px solid #E4E4E4;\">\n \n <div class=\"cqa-bg-[#FCFCFC] cqa-rounded-lg cqa-p-3\" style=\"border: 1px solid #EDE9FE\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-mb-3 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\">\n <span>Request Summary</span>\n <div class=\"cqa-relative\">\n <button (click)=\"copyRequestSummary()\" class=\"cqa-flex cqa-items-center cqa-gap-1 p-0\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 4H5C4.44772 4 4 4.44772 4 5V10C4 10.5523 4.44772 11 5 11H10C10.5523 11 11 10.5523 11 10V5C11 4.44772 10.5523 4 10 4Z\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M2 8C1.45 8 1 7.55 1 7V2C1 1.45 1.45 1 2 1H7C7.55 1 8 1.45 8 2\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n Copy\n </button>\n <!-- Copied Tooltip -->\n <div \n *ngIf=\"showRequestSummaryCopied\" \n class=\"cqa-absolute cqa-right-0 cqa-top-full cqa-mt-1 cqa-px-2 cqa-py-1 cqa-bg-[#0B0B0B] cqa-text-white cqa-text-[10px] cqa-rounded cqa-whitespace-nowrap cqa-z-50 cqa-shadow-lg\"\n style=\"animation: fadeInOut 0.2s ease-in-out;\">\n Copied!\n </div>\n </div>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-cursor-pointer\" (dblclick)=\"copyRequestSummary()\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <span class=\"cqa-px-1 cqa-py-[2px] cqa-rounded cqa-font-medium cqa-text-[#008236] cqa-bg-[#DCFCE7] cqa-text-[10px] cqa-leading-[15px]\">\n {{ config.method }}\n </span>\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#0B0B0B]\">{{ config.endpoint }}</span>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-3\">\n <span *ngIf=\"config?.statusCode === 200 || config?.statusCode === 201\" class=\"cqa-flex cqa-items-center cqa-gap-1.5 cqa-px-1 cqa-py-[2px] cqa-rounded cqa-font-medium cqa-text-[#00A63E] cqa-bg-[#DCFCE7] cqa-text-[10px] cqa-leading-[15px]\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 3L4.5 8.5L2 6\" stroke=\"#00A63E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path></svg>\n {{ config.statusCode }}\n </span>\n <span *ngIf=\"config?.statusCode && config?.statusCode !== 200 && config?.statusCode !== 201\" class=\"cqa-flex cqa-items-center cqa-gap-1.5 cqa-px-1 cqa-py-[2px] cqa-rounded cqa-font-medium cqa-text-[#E7000B] cqa-bg-[#FFE2E2] cqa-text-[10px] cqa-leading-[15px]\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.5 3.5L3.5 10.5\" stroke=\"#E7000B\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M3.5 3.5L10.5 10.5\" stroke=\"#E7000B\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n {{ config.statusCode }}\n </span>\n <div class=\"cqa-flex cqa-items-center cqa-gap-1.5 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\" *ngIf=\"config?.responseTime\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6.99999 12.8334C10.2217 12.8334 12.8333 10.2217 12.8333 7.00008C12.8333 3.77842 10.2217 1.16675 6.99999 1.16675C3.77833 1.16675 1.16666 3.77842 1.16666 7.00008C1.16666 10.2217 3.77833 12.8334 6.99999 12.8334Z\" stroke=\"#636363\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7 3.5V7L9.33333 8.16667\" stroke=\"#636363\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <span>{{ config.responseTime }}ms</span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Request/Response Headers -->\n <div class=\"cqa-grid cqa-grid-cols-2 cqa-gap-3 cqa-mt-4\" *ngIf=\"config?.requestHeaders || config?.responseHeaders\">\n <!-- Request Headers -->\n <div class=\"cqa-bg-[#FCFCFC] cqa-rounded-lg cqa-p-3 cqa-flex cqa-flex-col\" style=\"border: 1px solid #EDE9FE\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2 cqa-mb-2\">\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\">Request Headers</span>\n <div class=\"cqa-relative\">\n <button (click)=\"copyRequestHeaders()\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 4H5C4.44772 4 4 4.44772 4 5V10C4 10.5523 4.44772 11 5 11H10C10.5523 11 11 10.5523 11 10V5C11 4.44772 10.5523 4 10 4Z\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M2 8C1.45 8 1 7.55 1 7V2C1 1.45 1.45 1 2 1H7C7.55 1 8 1.45 8 2\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </button>\n <!-- Copied Tooltip -->\n <div \n *ngIf=\"showRequestHeadersCopied\" \n class=\"cqa-absolute cqa-right-0 cqa-top-full cqa-mt-1 cqa-px-2 cqa-py-1 cqa-bg-[#0B0B0B] cqa-text-white cqa-text-[10px] cqa-rounded cqa-whitespace-nowrap cqa-z-50 cqa-shadow-lg\"\n style=\"animation: fadeInOut 0.2s ease-in-out;\">\n Copied\n </div>\n </div>\n </div>\n <pre *ngIf=\"config.requestHeaders\" class=\"cqa-h-full cqa-text-[12px] cqa-text-[#0B0B0B] cqa-bg-[#F8F8F8] cqa-p-2 cqa-m-0 cqa-rounded cqa-overflow-auto cqa-max-h-[114px] cqa-cursor-pointer\" style=\"scrollbar-width: thin;\" (dblclick)=\"copyJsonPath($event, config.requestHeaders, 'requestHeaders')\">{{ formatJson(config.requestHeaders) }}</pre>\n </div>\n\n <!-- Response Headers -->\n <div class=\"cqa-bg-[#FCFCFC] cqa-rounded-lg cqa-p-3 cqa-flex cqa-flex-col\" style=\"border: 1px solid #EDE9FE\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-mb-2\">\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\">Response Headers</span>\n <div class=\"cqa-relative\">\n <button (click)=\"copyResponseHeaders()\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 4H5C4.44772 4 4 4.44772 4 5V10C4 10.5523 4.44772 11 5 11H10C10.5523 11 11 10.5523 11 10V5C11 4.44772 10.5523 4 10 4Z\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M2 8C1.45 8 1 7.55 1 7V2C1 1.45 1.45 1 2 1H7C7.55 1 8 1.45 8 2\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </button>\n <!-- Copied Tooltip -->\n <div \n *ngIf=\"showResponseHeadersCopied\" \n class=\"cqa-absolute cqa-right-0 cqa-top-full cqa-mt-1 cqa-px-2 cqa-py-1 cqa-bg-[#0B0B0B] cqa-text-white cqa-text-[10px] cqa-rounded cqa-whitespace-nowrap cqa-z-50 cqa-shadow-lg\"\n style=\"animation: fadeInOut 0.2s ease-in-out;\">\n Copied\n </div>\n </div>\n </div>\n <pre *ngIf=\"config.responseHeaders\" [ngClass]=\"{'cqa-bg-[#FEF2F2] cqa-text-[#C10007]': config.statusCode >= 400}\" class=\"cqa-h-full cqa-text-[12px] cqa-p-2 cqa-m-0 cqa-rounded cqa-overflow-auto cqa-max-h-[114px] cqa-cursor-pointer\" style=\"scrollbar-width: thin;\" (dblclick)=\"copyJsonPath($event, config.responseHeaders, 'responseHeaders')\">{{ formatJson(config.responseHeaders) }}</pre>\n </div>\n </div>\n\n <!-- Request/Response Bodies -->\n <div class=\"cqa-grid cqa-grid-cols-2 cqa-gap-3 cqa-mt-4\" *ngIf=\"config?.requestBody || config?.responseBody\">\n <!-- Request Body -->\n <div class=\"cqa-bg-[#FCFCFC] cqa-rounded-lg cqa-p-3 cqa-flex cqa-flex-col\" style=\"border: 1px solid #EDE9FE\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2 cqa-mb-2\">\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\">Request Body</span>\n <div class=\"cqa-relative\">\n <button (click)=\"copyRequestBody()\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 4H5C4.44772 4 4 4.44772 4 5V10C4 10.5523 4.44772 11 5 11H10C10.5523 11 11 10.5523 11 10V5C11 4.44772 10.5523 4 10 4Z\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M2 8C1.45 8 1 7.55 1 7V2C1 1.45 1.45 1 2 1H7C7.55 1 8 1.45 8 2\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </button>\n <!-- Copied Tooltip -->\n <div \n *ngIf=\"showRequestBodyCopied\" \n class=\"cqa-absolute cqa-right-0 cqa-top-full cqa-mt-1 cqa-px-2 cqa-py-1 cqa-bg-[#0B0B0B] cqa-text-white cqa-text-[10px] cqa-rounded cqa-whitespace-nowrap cqa-z-50 cqa-shadow-lg\"\n style=\"animation: fadeInOut 0.2s ease-in-out;\">\n Copied\n </div>\n </div>\n </div>\n <pre *ngIf=\"config.requestBody\" class=\"cqa-h-full cqa-text-[12px] cqa-text-[#0B0B0B] cqa-bg-[#F8F8F8] cqa-p-2 cqa-m-0 cqa-rounded cqa-overflow-auto cqa-max-h-[114px] cqa-cursor-pointer\" style=\"scrollbar-width: thin;\" (dblclick)=\"copyJsonPath($event, config.requestBody, 'requestBody')\">{{ formatJson(config.requestBody) }}</pre>\n </div>\n\n <!-- Response Body -->\n <div class=\"cqa-bg-[#FCFCFC] cqa-rounded-lg cqa-p-3 cqa-flex cqa-flex-col\" style=\"border: 1px solid #EDE9FE\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-mb-2\">\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\">Response Body</span>\n <div class=\"cqa-relative\">\n <button (click)=\"copyResponseBody()\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 4H5C4.44772 4 4 4.44772 4 5V10C4 10.5523 4.44772 11 5 11H10C10.5523 11 11 10.5523 11 10V5C11 4.44772 10.5523 4 10 4Z\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M2 8C1.45 8 1 7.55 1 7V2C1 1.45 1.45 1 2 1H7C7.55 1 8 1.45 8 2\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </button>\n <!-- Copied Tooltip -->\n <div \n *ngIf=\"showResponseBodyCopied\" \n class=\"cqa-absolute cqa-right-0 cqa-top-full cqa-mt-1 cqa-px-2 cqa-py-1 cqa-bg-[#0B0B0B] cqa-text-white cqa-text-[10px] cqa-rounded cqa-whitespace-nowrap cqa-z-50 cqa-shadow-lg\"\n style=\"animation: fadeInOut 0.2s ease-in-out;\">\n Copied\n </div>\n </div>\n </div>\n <pre *ngIf=\"config.responseBody\" [ngClass]=\"{'cqa-bg-[#FEF2F2] cqa-text-[#C10007]': config.statusCode >= 400}\" class=\"cqa-h-full cqa-text-[12px] cqa-p-2 cqa-m-0 cqa-rounded cqa-overflow-auto cqa-max-h-[114px] cqa-cursor-pointer\" style=\"scrollbar-width: thin;\" (dblclick)=\"copyJsonPath($event, config.responseBody, 'responseBody')\">{{ formatJson(config.responseBody) }}</pre>\n </div>\n </div>\n\n <!-- Assertions -->\n <div *ngIf=\"config.assertions && config.assertions.length > 0\" class=\"cqa-bg-[#FCFCFC] cqa-rounded-lg cqa-p-3 cqa-flex cqa-flex-col cqa-mt-4\" style=\"border: 1px solid #EDE9FE\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2 cqa-mb-3\">\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\">Assertions</span>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium\">\n <span class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-text-[#00A63E]\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 3L4.5 8.5L2 6\" stroke=\"#00A63E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n {{ getPassedAssertions() }} passed\n </span>\n <span class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-text-[#E7000B]\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M9 3L3 9\" stroke=\"#E7000B\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M3 3L9 9\" stroke=\"#E7000B\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n {{ getFailedAssertions() }} failed\n </span>\n </div>\n </div>\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <div\n *ngFor=\"let assertion of config.assertions\"\n class=\"cqa-flex cqa-justify-between cqa-gap-2 cqa-flex-wrap cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363] cqa-px-3 cqa-py-1 cqa-rounded-md cqa-items-center\"\n [ngStyle]=\"{\n 'background-color': assertion.status === 'passed' ? '#ECFDF3' : '#FEF2F2',\n 'border': assertion.status === 'passed'\n ? '1px solid #A7F3D0'\n : '1px solid #FFC9C9'\n }\"\n >\n <div class=\"cqa-flex-1 cqa-flex cqa-items-center cqa-gap-2\">\n <div>\n <!-- Passed -->\n <ng-container *ngIf=\"assertion.status === 'passed'; else failedIcon\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"20\" height=\"20\" rx=\"10\" fill=\"#DCFCE7\"/><path d=\"M14 7L8.5 12.5L6 10\" stroke=\"#00A63E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </ng-container>\n \n <!-- Failed -->\n <ng-template #failedIcon>\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"20\" height=\"20\" rx=\"10\" fill=\"#FFE2E2\"/><path d=\"M13 7L7 13\" stroke=\"#E7000B\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7 7L13 13\" stroke=\"#E7000B\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </ng-template>\n </div>\n <div class=\"cqa-text-[12px] cqa-leading-[15px]\" \n [ngClass]=\"{\n 'cqa-text-[#9F0712]': assertion.status !== 'passed',\n 'cqa-text-[#016630]': assertion.status === 'passed'\n }\"\n >\n {{ assertion.description }}\n </div>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-4 cqa-max-w-[200px]\">\n <div>\n <span>Expected:</span>\n <span style=\"word-break: break-word;\" [ngClass]=\"assertion.status === 'passed' ? 'cqa-text-[#008236]' : 'cqa-text-[#0B0B0B]'\">\n {{ assertion.expected }}\n </span>\n </div>\n <div>\n <span>Actual:</span>\n <span style=\"word-break: break-word;\" [ngClass]=\"assertion.status === 'passed' ? 'cqa-text-green-600' : 'cqa-text-[#E7000B]'\">\n {{ assertion.actual }}\n </span>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Self Heal Analysis -->\n <cqa-self-heal-analysis \n *ngIf=\"selfHealAnalysis\" \n [id]=\"step?.testStepId\"\n [originalLocator]=\"selfHealAnalysis.originalLocator\"\n [healedLocator]=\"selfHealAnalysis.healedLocator\"\n [confidence]=\"selfHealAnalysis.confidence\"\n [healMethod]=\"selfHealAnalysis.healMethod\"\n [isLoadingAccept]=\"getSelfHealLoadingStatesHandler ? getSelfHealLoadingStatesHandler().isLoadingAccept?.[step?.testStepId] : false\"\n [isLoadingModifyAccept]=\"getSelfHealLoadingStatesHandler ? getSelfHealLoadingStatesHandler().isLoadingModifyAccept?.[step?.testStepId] : false\"\n (action)=\"onSelfHealAction($event)\">\n </cqa-self-heal-analysis>\n\n <!-- Timing Breakdown -->\n <div *ngIf=\"config.timingBreakdown\" class=\"cqa-flex cqa-items-center cqa-justify-end cqa-gap-5 cqa-pt-1.5 cqa-px-4 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF]\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <span>Timing breakdown</span>\n </div>\n <span class=\"cqa-text-dialog-muted cqa-flex cqa-items-center cqa-gap-3\">\n <div>\n App <span class=\"cqa-text-gray-700\">{{ formatDuration(config.timingBreakdown.app) }}</span>\n </div>\n <div><svg width=\"1\" height=\"11\" viewBox=\"0 0 1 11\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M-3.8147e-06 10.32V-7.15256e-07H0.959996V10.32H-3.8147e-06Z\" fill=\"#E5E7EB\"/></svg></div>\n <div>\n Tool <span class=\"cqa-text-gray-700\">{{ formatDuration(config.timingBreakdown.tool) }}</span>\n </div>\n </span>\n </div>\n </div>\n\n <!-- View More Failed Step Button - shown when expanded and failure details exist -->\n <div *ngIf=\"showViewMoreButton\" class=\"cqa-mt-2 cqa-px-4\">\n <cqa-view-more-failed-step-button\n [timingBreakdown]=\"timingBreakdown\"\n [subSteps]=\"getSubStepsForFailedStep()\"\n [failureDetails]=\"failureDetails\"\n [isExpanded]=\"showFailedStepDetails\"\n (viewMoreClick)=\"onViewMoreFailedStepClick($event)\">\n </cqa-view-more-failed-step-button>\n </div>\n\n <!-- Updated Failed Step Component - shown when button is clicked -->\n <div *ngIf=\"showViewMoreButton && showFailedStepDetails && failureDetails\" class=\"cqa-mt-2 cqa-px-4\">\n <cqa-updated-failed-step\n [testStepResultId]=\"testStepResultId\"\n [timingBreakdown]=\"timingBreakdown\"\n [expanded]=\"true\"\n [subSteps]=\"getSubStepsForFailedStep()\"\n [failureDetails]=\"failureDetails\"\n [reasoning]=\"reasoning\"\n [confidence]=\"confidence\"\n [isUploadingBaseline]=\"isUploadingBaseline\"\n [isMakingCurrentBaseline]=\"isMakingCurrentBaseline\"\n [isLive]=\"isLive\"\n (makeCurrentBaseline)=\"onMakeCurrentBaseline($event)\"\n (uploadBaseline)=\"onUploadBaseline($event)\"\n (analyze)=\"onAnalyze()\"\n (viewFullLogs)=\"onViewFullLogs()\">\n </cqa-updated-failed-step>\n </div>\n</div>\n", components: [{ type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i2$1.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { type: i2$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { type: AiLogsWithReasoningComponent, selector: "cqa-ai-logs-with-reasoning", inputs: ["status", "text", "description", "reasoning", "duration"] }, { type: SelfHealAnalysisComponent, selector: "cqa-self-heal-analysis", inputs: ["id", "originalLocator", "healedLocator", "confidence", "healMethod", "isLoadingAccept", "isLoadingModifyAccept"], outputs: ["action"] }, { type: ViewMoreFailedStepButtonComponent, selector: "cqa-view-more-failed-step-button", inputs: ["timingBreakdown", "subSteps", "failureDetails", "isExpanded"], outputs: ["viewMoreClick"] }, { type: UpdatedFailedStepComponent, selector: "cqa-updated-failed-step", inputs: ["timingBreakdown", "testStepResultId", "expanded", "subSteps", "failureDetails", "reasoning", "confidence", "isUploadingBaseline", "isMakingCurrentBaseline", "isLive"], outputs: ["makeCurrentBaseline", "uploadBaseline", "analyze", "viewFullLogs"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i4.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { type: i2$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
|
|
12128
12844
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ApiStepComponent, decorators: [{
|
|
12129
12845
|
type: Component,
|
|
12130
|
-
args: [{ selector: 'cqa-api-step', host: { class: 'cqa-ui-root' }, template: "<div class=\"cqa-font-inter\" (click)=\"$event.stopPropagation()\">\n <!-- Header -->\n <div\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-p-2 cqa-cursor-pointer\"\n (click)=\"toggleHeader($event)\">\n <div *ngIf=\"showDebugIcon\" class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer cqa-rounded-full hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" (click)=\"onDebugPointClick($event)\" [attr.aria-label]=\"debugPointSet ? 'Remove debug point' : 'Set debug point'\">\n <svg *ngIf=\"debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" fill=\"#C63535\"/>\n </svg>\n <svg *ngIf=\"!debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" stroke=\"#C63535\" stroke-width=\"1.5\" fill=\"none\"/>\n </svg>\n </button>\n </div>\n <!-- Status Icon -->\n \n <div *ngIf=\"status.toLowerCase() === 'success'\" ><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <div *ngIf=\"status.toLowerCase() === 'failure' || status.toLowerCase() === 'failed'\"><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7.5 4.5L4.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 4.5L7.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <div *ngIf=\"status.toLowerCase() === 'pending'\"><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <div *ngIf=\"status.toLowerCase() === 'running'\"><svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/><path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/></svg></div>\n <!-- Skipped -->\n <div *ngIf=\"status.toLowerCase() === 'skipped'\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"12px\" viewBox=\"0 -960 960 960\" width=\"12px\" fill=\"#1f1f1f\"><path d=\"M660-240v-480h80v480h-80Zm-440 0v-480l360 240-360 240Zm80-240Zm0 90 136-90-136-90v180Z\"/></svg>\n </div>\n <!-- API Icon -->\n <div><svg width=\"20\" height=\"16\" viewBox=\"0 0 20 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"20\" height=\"16\" rx=\"4\" fill=\"#EDE9FE\"/><path d=\"M8 6.5L9.5 8L8 9.5M10.5 9.5H12M6.5 12H13.5C13.7652 12 14.0196 11.8946 14.2071 11.7071C14.3946 11.5196 14.5 11.2652 14.5 11V5C14.5 4.73478 14.3946 4.48043 14.2071 4.29289C14.0196 4.10536 13.7652 4 13.5 4H6.5C6.23478 4 5.98043 4.10536 5.79289 4.29289C5.60536 4.48043 5.5 4.73478 5.5 5V11C5.5 11.2652 5.60536 11.5196 5.79289 11.7071C5.98043 11.8946 6.23478 12 6.5 12Z\" stroke=\"#7F22FE\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n\n <!-- Step Number and Title -->\n <div class=\"cqa-flex-1 cqa-flex cqa-items-center cqa-gap-3 cqa-font-inter\">\n <span class=\"cqa-font-semibold cqa-text-[#334155] cqa-text-[14px] cqa-leading-[18px]\" style=\"word-break: break-word;\">\n {{ config?.stepNumber }}. <span [innerHTML]=\"config.title\"></span>\n </span>\n <span class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-[#7008E7] cqa-bg-[#EDE9FE] cqa-text-[10px] cqa-leading-[15px]\">\n API\n </span>\n <span class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-[#008236] cqa-bg-[#DCFCE7] cqa-text-[10px] cqa-leading-[15px]\">\n {{ config.method }}\n </span>\n <span *ngIf=\"config.stepDeleted\" class=\"cqa-px-1.5 cqa-py-[2px] cqa-rounded-[4px] cqa-text-[10px] cqa-leading-[12px] cqa-font-medium cqa-text-[#B42318] cqa-bg-[#FEF3F2] cqa-border cqa-border-[#FEE4E2]\">\n Deleted\n </span>\n </div>\n\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-font-inter\">\n <span *ngIf=\"selfHealAnalysis\" class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-[#097E53] cqa-bg-[#CFF2E5] cqa-text-[10px] cqa-leading-[15px] cqa-min-w-max cqa-flex cqa-items-center cqa-gap-[6px]\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"9\" height=\"9\" viewBox=\"0 0 9 9\" fill=\"none\">\n <path d=\"M4.50941 0C4.56489 0.0227384 4.58859 0.0782652 4.61131 0.129846C4.62269 0.1599 4.63314 0.190117 4.64329 0.220575C4.64726 0.232247 4.65123 0.243918 4.65532 0.255943C4.70806 0.413005 4.75504 0.571748 4.80229 0.73038C4.81297 0.76619 4.82369 0.801987 4.83442 0.837783C4.88905 1.02004 4.94327 1.2024 4.99719 1.38484C5.00476 1.41047 5.01234 1.43609 5.01992 1.46171C5.04128 1.53395 5.06262 1.60619 5.08383 1.67847C5.12867 1.8312 5.17473 1.98347 5.22378 2.13501C5.22807 2.14827 5.23236 2.16152 5.23677 2.17518C5.3642 2.565 5.54482 2.91437 5.8409 3.21196C5.84823 3.2197 5.85556 3.22744 5.86312 3.23541C5.9895 3.36437 6.15169 3.46771 6.3138 3.55111C6.32206 3.55542 6.33031 3.55974 6.33882 3.56419C6.81587 3.80925 7.38951 3.91704 7.90619 4.0605C8.1326 4.1234 8.3583 4.18829 8.58317 4.25603C8.59897 4.26079 8.61478 4.26554 8.63058 4.27028C8.67784 4.28445 8.725 4.29887 8.77211 4.31347C8.7831 4.31679 8.79408 4.32011 8.80539 4.32353C8.87029 4.34406 8.93239 4.36829 8.98566 4.41027C9.00191 4.44418 9.00191 4.44418 8.99748 4.4781C8.94564 4.52736 8.8942 4.55046 8.82578 4.573C8.816 4.57632 8.80622 4.57965 8.79614 4.58308C8.68061 4.62183 8.56351 4.65575 8.44626 4.68935C8.4222 4.6963 8.39814 4.70326 8.37408 4.71021C8.22571 4.75301 8.07708 4.7949 7.92829 4.83632C7.73232 4.89088 7.53663 4.94634 7.34113 5.00243C7.3091 5.01162 7.27706 5.02078 7.24501 5.02991C7.07671 5.07786 6.90923 5.12753 6.74314 5.18208C6.72937 5.18659 6.71559 5.1911 6.70139 5.19574C6.14511 5.38082 5.7211 5.72609 5.45571 6.23099C5.31263 6.51475 5.22823 6.82161 5.14214 7.12447C5.11884 7.20619 5.09409 7.28745 5.06905 7.36869C5.0494 7.43261 5.0302 7.49663 5.01149 7.56081C5.00926 7.56844 5.00703 7.57608 5.00473 7.58395C4.99394 7.62094 4.98319 7.65793 4.97252 7.69495C4.94519 7.78879 4.91578 7.88187 4.88555 7.97489C4.83191 8.14021 4.7831 8.30674 4.73459 8.4735C4.66144 8.72457 4.66144 8.72457 4.61997 8.84527C4.61721 8.85337 4.61446 8.86147 4.61163 8.86982C4.59649 8.91278 4.58092 8.95233 4.55226 8.9887C4.50867 8.99788 4.50867 8.99788 4.46951 9C4.42473 8.93759 4.39508 8.87711 4.37133 8.80508C4.36787 8.79487 4.36441 8.78466 4.36085 8.77415C4.31684 8.64248 4.27751 8.50946 4.23817 8.37646C4.22916 8.34604 4.22011 8.31564 4.21105 8.28524C4.1436 8.05863 4.07725 7.83174 4.01101 7.60481C3.73507 6.48224 3.73507 6.48224 3.039 5.57466C3.02784 5.56596 3.01669 5.55726 3.00519 5.5483C2.54913 5.19902 1.94834 5.06969 1.39815 4.91813C1.26207 4.88062 1.12605 4.84293 0.990032 4.80523C0.978138 4.80193 0.978138 4.80193 0.966003 4.79857C0.769811 4.74417 0.573674 4.68963 0.378224 4.63283C0.369956 4.63045 0.361688 4.62806 0.353169 4.62561C0.0528989 4.53883 0.0528989 4.53883 0.000646537 4.4781C-0.000831261 4.45054 -0.000831261 4.45054 0.0124689 4.42157C0.0670835 4.3704 0.120077 4.34848 0.19216 4.32619C0.202597 4.32284 0.213034 4.31948 0.223787 4.31603C0.255753 4.30582 0.287788 4.29584 0.319851 4.28592C0.329001 4.28305 0.338151 4.28017 0.347578 4.27722C0.412285 4.25693 0.477225 4.2374 0.542259 4.21809C0.55824 4.21332 0.55824 4.21332 0.574544 4.20846C0.852269 4.12587 1.13181 4.049 1.41126 3.97196C1.6195 3.91455 1.82738 3.85618 2.0346 3.79548C2.04413 3.79271 2.05365 3.78993 2.06346 3.78707C2.5435 3.64696 3.01278 3.44816 3.32274 3.0537C3.32738 3.04785 3.33202 3.042 3.3368 3.03597C3.68197 2.59815 3.81658 2.06572 3.96695 1.54621C4.01643 1.37534 4.06649 1.20464 4.11673 1.03399C4.13064 0.986733 4.14453 0.939471 4.15836 0.892194C4.21394 0.702289 4.27035 0.512642 4.33 0.323864C4.33558 0.306186 4.34114 0.288501 4.34666 0.270807C4.43017 0.00398761 4.43017 0.00398761 4.50941 0Z\" fill=\"#0DBD7D\"/>\n <path d=\"M7.23597 0.554859C7.29024 0.613599 7.30109 0.682631 7.31799 0.757638C7.37436 0.993269 7.43929 1.20993 7.66467 1.34681C7.80371 1.42035 7.96944 1.45381 8.1235 1.48541C8.18854 1.49902 8.24348 1.51709 8.29924 1.55321C8.31181 1.57229 8.31181 1.57229 8.31107 1.60549C8.29814 1.64588 8.28678 1.6589 8.25269 1.68533C8.21543 1.69726 8.21543 1.69726 8.17068 1.70653C8.15375 1.71025 8.13683 1.714 8.11992 1.71779C8.11086 1.7198 8.10181 1.72181 8.09247 1.72388C7.81696 1.78482 7.81696 1.78482 7.57882 1.92273C7.57108 1.92869 7.56333 1.93466 7.55536 1.9408C7.38516 2.08431 7.34916 2.32303 7.29793 2.52301C7.29499 2.53399 7.29206 2.54497 7.28903 2.55629C7.28649 2.56601 7.28395 2.57573 7.28133 2.58575C7.27028 2.61544 7.25881 2.63479 7.23597 2.65754C7.17234 2.66527 7.17234 2.66527 7.14139 2.65754C7.09216 2.62106 7.08114 2.5795 7.06828 2.52365C7.06613 2.51501 7.06398 2.50636 7.06176 2.49745C7.05489 2.46983 7.04824 2.44217 7.04164 2.41449C6.98979 2.19897 6.93126 1.98751 6.72451 1.86118C6.56293 1.77501 6.36646 1.73426 6.18587 1.70136C6.13637 1.69151 6.10802 1.67911 6.07738 1.64012C6.07073 1.60055 6.07073 1.60055 6.07738 1.56098C6.12447 1.51437 6.17402 1.50299 6.23772 1.48891C6.25778 1.48416 6.27784 1.47938 6.29789 1.47456C6.30825 1.47209 6.31861 1.46962 6.32929 1.46707C6.38212 1.45407 6.43443 1.43949 6.48673 1.42462C6.49623 1.42198 6.50573 1.41935 6.51552 1.41663C6.62182 1.38624 6.71356 1.34737 6.79854 1.27836C6.80647 1.27213 6.81439 1.26589 6.82255 1.25946C6.9548 1.14565 6.99974 0.974674 7.04053 0.815134C7.04364 0.803022 7.04675 0.79091 7.04995 0.778432C7.05614 0.754101 7.06222 0.729743 7.06817 0.705359C7.07243 0.688394 7.07243 0.688394 7.07678 0.671086C7.07927 0.660951 7.08175 0.650816 7.08431 0.640373C7.09521 0.608108 7.10952 0.582772 7.12957 0.554859C7.1681 0.536435 7.19515 0.544764 7.23597 0.554859Z\" fill=\"#075F3F\"/>\n <path d=\"M1.79545 6.2471C1.80951 6.24719 1.80951 6.24719 1.82386 6.24729C1.92477 6.25022 1.99304 6.28115 2.06736 6.34601C2.15384 6.43533 2.19377 6.53611 2.1915 6.6565C2.18178 6.75412 2.12158 6.83935 2.04773 6.90533C1.96081 6.97242 1.87313 6.99459 1.76206 6.99149C1.66841 6.98107 1.5803 6.93852 1.51393 6.87451C1.43138 6.76681 1.40725 6.66803 1.41935 6.53537C1.44433 6.43092 1.51637 6.34613 1.6085 6.28666C1.67251 6.25564 1.72399 6.24652 1.79545 6.2471Z\" fill=\"#0DBD7D\"/>\n </svg>\n Self-healed\n </span>\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-rounded-[4px] cqa-py-0.5 cqa-px-1 cqa-bg-[#6366F11A] cqa-ml-1 cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity\" \n *ngIf=\"step?.executedResult?.video_start_time\" \n [matTooltip]=\"'Jump to video time'\" \n matTooltipPosition=\"below\"\n (click)=\"onJumpToTimestamp($event)\">\n <mat-icon class=\"cqa-text-[#636363] !cqa-text-[10px] !cqa-w-[10px] !cqa-h-[10px]\">\n play_arrow\n </mat-icon>\n <span class=\"cqa-text-[8px] cqa-leading-[12px] cqa-font-normal cqa-text-[#636363]\">\n {{ formatDurationClock(step?.executedResult?.video_start_time || 0) }}\n </span>\n </div>\n <div *ngIf=\"isDebug\" class=\"cqa-flex cqa-items-center cqa-gap-0.5 cqa-text-[#9CA3AF]\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Edit\" (click)=\"onEditStep($event)\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">edit</mat-icon>\n </button>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Add\" [matMenuTriggerFor]=\"addStepMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">add</mat-icon>\n </button>\n <mat-menu #addStepMenu=\"matMenu\" class=\"cqa-add-step-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of addStepMenuOptions\" (click)=\"onAddStepOptionSelect(opt, $event)\">\n {{ opt.label }}\n </button>\n </mat-menu>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"More options\" [matMenuTriggerFor]=\"stepMoreMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">more_vert</mat-icon>\n </button>\n <mat-menu #stepMoreMenu=\"matMenu\" class=\"cqa-step-more-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of stepMoreMenuOptions\" (click)=\"onStepMoreOptionSelect(opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n </div>\n <span class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF]\">\n {{ formatDuration(config.duration) }}\n </span>\n <svg [class.cqa-rotate-180]=\"isExpanded\" class=\"cqa-transition-transform\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M3.5 5L7 8.5L10.5 5\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n </div>\n\n <!-- Expanded Content -->\n <div *ngIf=\"isExpanded\">\n <!-- Initial Actions -->\n <div *ngIf=\"config.initialActions && config.initialActions.length > 0\" class=\"cqa-flex cqa-flex-col cqa-gap-1 cqa-ml-9\">\n <div\n *ngFor=\"let action of config.initialActions\"\n class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-py-[5.5px] cqa-px-3\">\n \n <div *ngIf=\"action?.status?.toLowerCase() === 'success' || action?.status?.toLowerCase() === 'passed'\" >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Failure -->\n <div *ngIf=\"action?.status?.toLowerCase() === 'failure' || action?.status?.toLowerCase() === 'failed'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7.5 4.5L4.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 4.5L7.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Pending -->\n <div *ngIf=\"action?.status?.toLowerCase() === 'pending'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Running - Show spinner -->\n <div *ngIf=\"action?.status?.toLowerCase() === 'running'\">\n <svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n </div>\n\n\n <span class=\"cqa-flex-1 cqa-text-[13px] cqa-leading-[15px] cqa-text-[#364153]\" style=\"white-space: pre-line;\">{{ action.description }}</span>\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-metadata-key\">{{ formatDuration(action.duration) }}</span>\n </div>\n </div>\n\n <!-- Request Summary Card -->\n <div *ngIf=\"!isLive\" class=\"cqa-bg-[#FFFEF9] cqa-mt-1.5 cqa-ml-9 cqa-mr-6 cqa-p-4\" style=\"border-top: 1px solid #E4E4E4;\">\n \n <div class=\"cqa-bg-[#FCFCFC] cqa-rounded-lg cqa-p-3\" style=\"border: 1px solid #EDE9FE\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-mb-3 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\">\n <span>Request Summary</span>\n <div class=\"cqa-relative\">\n <button (click)=\"copyRequestSummary()\" class=\"cqa-flex cqa-items-center cqa-gap-1 p-0\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 4H5C4.44772 4 4 4.44772 4 5V10C4 10.5523 4.44772 11 5 11H10C10.5523 11 11 10.5523 11 10V5C11 4.44772 10.5523 4 10 4Z\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M2 8C1.45 8 1 7.55 1 7V2C1 1.45 1.45 1 2 1H7C7.55 1 8 1.45 8 2\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n Copy\n </button>\n <!-- Copied Tooltip -->\n <div \n *ngIf=\"showRequestSummaryCopied\" \n class=\"cqa-absolute cqa-right-0 cqa-top-full cqa-mt-1 cqa-px-2 cqa-py-1 cqa-bg-[#0B0B0B] cqa-text-white cqa-text-[10px] cqa-rounded cqa-whitespace-nowrap cqa-z-50 cqa-shadow-lg\"\n style=\"animation: fadeInOut 0.2s ease-in-out;\">\n Copied!\n </div>\n </div>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-cursor-pointer\" (dblclick)=\"copyRequestSummary()\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <span class=\"cqa-px-1 cqa-py-[2px] cqa-rounded cqa-font-medium cqa-text-[#008236] cqa-bg-[#DCFCE7] cqa-text-[10px] cqa-leading-[15px]\">\n {{ config.method }}\n </span>\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#0B0B0B]\">{{ config.endpoint }}</span>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-3\">\n <span *ngIf=\"config?.statusCode === 200 || config?.statusCode === 201\" class=\"cqa-flex cqa-items-center cqa-gap-1.5 cqa-px-1 cqa-py-[2px] cqa-rounded cqa-font-medium cqa-text-[#00A63E] cqa-bg-[#DCFCE7] cqa-text-[10px] cqa-leading-[15px]\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 3L4.5 8.5L2 6\" stroke=\"#00A63E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path></svg>\n {{ config.statusCode }}\n </span>\n <span *ngIf=\"config?.statusCode && config?.statusCode !== 200 && config?.statusCode !== 201\" class=\"cqa-flex cqa-items-center cqa-gap-1.5 cqa-px-1 cqa-py-[2px] cqa-rounded cqa-font-medium cqa-text-[#E7000B] cqa-bg-[#FFE2E2] cqa-text-[10px] cqa-leading-[15px]\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.5 3.5L3.5 10.5\" stroke=\"#E7000B\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M3.5 3.5L10.5 10.5\" stroke=\"#E7000B\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n {{ config.statusCode }}\n </span>\n <div class=\"cqa-flex cqa-items-center cqa-gap-1.5 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\" *ngIf=\"config?.responseTime\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6.99999 12.8334C10.2217 12.8334 12.8333 10.2217 12.8333 7.00008C12.8333 3.77842 10.2217 1.16675 6.99999 1.16675C3.77833 1.16675 1.16666 3.77842 1.16666 7.00008C1.16666 10.2217 3.77833 12.8334 6.99999 12.8334Z\" stroke=\"#636363\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7 3.5V7L9.33333 8.16667\" stroke=\"#636363\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <span>{{ config.responseTime }}ms</span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Request/Response Headers -->\n <div class=\"cqa-grid cqa-grid-cols-2 cqa-gap-3 cqa-mt-4\" *ngIf=\"config?.requestHeaders || config?.responseHeaders\">\n <!-- Request Headers -->\n <div class=\"cqa-bg-[#FCFCFC] cqa-rounded-lg cqa-p-3 cqa-flex cqa-flex-col\" style=\"border: 1px solid #EDE9FE\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2 cqa-mb-2\">\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\">Request Headers</span>\n <div class=\"cqa-relative\">\n <button (click)=\"copyRequestHeaders()\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 4H5C4.44772 4 4 4.44772 4 5V10C4 10.5523 4.44772 11 5 11H10C10.5523 11 11 10.5523 11 10V5C11 4.44772 10.5523 4 10 4Z\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M2 8C1.45 8 1 7.55 1 7V2C1 1.45 1.45 1 2 1H7C7.55 1 8 1.45 8 2\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </button>\n <!-- Copied Tooltip -->\n <div \n *ngIf=\"showRequestHeadersCopied\" \n class=\"cqa-absolute cqa-right-0 cqa-top-full cqa-mt-1 cqa-px-2 cqa-py-1 cqa-bg-[#0B0B0B] cqa-text-white cqa-text-[10px] cqa-rounded cqa-whitespace-nowrap cqa-z-50 cqa-shadow-lg\"\n style=\"animation: fadeInOut 0.2s ease-in-out;\">\n Copied\n </div>\n </div>\n </div>\n <pre *ngIf=\"config.requestHeaders\" class=\"cqa-h-full cqa-text-[12px] cqa-text-[#0B0B0B] cqa-bg-[#F8F8F8] cqa-p-2 cqa-m-0 cqa-rounded cqa-overflow-auto cqa-max-h-[114px] cqa-cursor-pointer\" style=\"scrollbar-width: thin;\" (dblclick)=\"copyJsonPath($event, config.requestHeaders, 'requestHeaders')\">{{ formatJson(config.requestHeaders) }}</pre>\n </div>\n\n <!-- Response Headers -->\n <div class=\"cqa-bg-[#FCFCFC] cqa-rounded-lg cqa-p-3 cqa-flex cqa-flex-col\" style=\"border: 1px solid #EDE9FE\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-mb-2\">\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\">Response Headers</span>\n <div class=\"cqa-relative\">\n <button (click)=\"copyResponseHeaders()\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 4H5C4.44772 4 4 4.44772 4 5V10C4 10.5523 4.44772 11 5 11H10C10.5523 11 11 10.5523 11 10V5C11 4.44772 10.5523 4 10 4Z\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M2 8C1.45 8 1 7.55 1 7V2C1 1.45 1.45 1 2 1H7C7.55 1 8 1.45 8 2\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </button>\n <!-- Copied Tooltip -->\n <div \n *ngIf=\"showResponseHeadersCopied\" \n class=\"cqa-absolute cqa-right-0 cqa-top-full cqa-mt-1 cqa-px-2 cqa-py-1 cqa-bg-[#0B0B0B] cqa-text-white cqa-text-[10px] cqa-rounded cqa-whitespace-nowrap cqa-z-50 cqa-shadow-lg\"\n style=\"animation: fadeInOut 0.2s ease-in-out;\">\n Copied\n </div>\n </div>\n </div>\n <pre *ngIf=\"config.responseHeaders\" [ngClass]=\"{'cqa-bg-[#FEF2F2] cqa-text-[#C10007]': config.statusCode >= 400}\" class=\"cqa-h-full cqa-text-[12px] cqa-p-2 cqa-m-0 cqa-rounded cqa-overflow-auto cqa-max-h-[114px] cqa-cursor-pointer\" style=\"scrollbar-width: thin;\" (dblclick)=\"copyJsonPath($event, config.responseHeaders, 'responseHeaders')\">{{ formatJson(config.responseHeaders) }}</pre>\n </div>\n </div>\n\n <!-- Request/Response Bodies -->\n <div class=\"cqa-grid cqa-grid-cols-2 cqa-gap-3 cqa-mt-4\" *ngIf=\"config?.requestBody || config?.responseBody\">\n <!-- Request Body -->\n <div class=\"cqa-bg-[#FCFCFC] cqa-rounded-lg cqa-p-3 cqa-flex cqa-flex-col\" style=\"border: 1px solid #EDE9FE\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2 cqa-mb-2\">\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\">Request Body</span>\n <div class=\"cqa-relative\">\n <button (click)=\"copyRequestBody()\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 4H5C4.44772 4 4 4.44772 4 5V10C4 10.5523 4.44772 11 5 11H10C10.5523 11 11 10.5523 11 10V5C11 4.44772 10.5523 4 10 4Z\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M2 8C1.45 8 1 7.55 1 7V2C1 1.45 1.45 1 2 1H7C7.55 1 8 1.45 8 2\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </button>\n <!-- Copied Tooltip -->\n <div \n *ngIf=\"showRequestBodyCopied\" \n class=\"cqa-absolute cqa-right-0 cqa-top-full cqa-mt-1 cqa-px-2 cqa-py-1 cqa-bg-[#0B0B0B] cqa-text-white cqa-text-[10px] cqa-rounded cqa-whitespace-nowrap cqa-z-50 cqa-shadow-lg\"\n style=\"animation: fadeInOut 0.2s ease-in-out;\">\n Copied\n </div>\n </div>\n </div>\n <pre *ngIf=\"config.requestBody\" class=\"cqa-h-full cqa-text-[12px] cqa-text-[#0B0B0B] cqa-bg-[#F8F8F8] cqa-p-2 cqa-m-0 cqa-rounded cqa-overflow-auto cqa-max-h-[114px] cqa-cursor-pointer\" style=\"scrollbar-width: thin;\" (dblclick)=\"copyJsonPath($event, config.requestBody, 'requestBody')\">{{ formatJson(config.requestBody) }}</pre>\n </div>\n\n <!-- Response Body -->\n <div class=\"cqa-bg-[#FCFCFC] cqa-rounded-lg cqa-p-3 cqa-flex cqa-flex-col\" style=\"border: 1px solid #EDE9FE\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-mb-2\">\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\">Response Body</span>\n <div class=\"cqa-relative\">\n <button (click)=\"copyResponseBody()\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 4H5C4.44772 4 4 4.44772 4 5V10C4 10.5523 4.44772 11 5 11H10C10.5523 11 11 10.5523 11 10V5C11 4.44772 10.5523 4 10 4Z\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M2 8C1.45 8 1 7.55 1 7V2C1 1.45 1.45 1 2 1H7C7.55 1 8 1.45 8 2\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </button>\n <!-- Copied Tooltip -->\n <div \n *ngIf=\"showResponseBodyCopied\" \n class=\"cqa-absolute cqa-right-0 cqa-top-full cqa-mt-1 cqa-px-2 cqa-py-1 cqa-bg-[#0B0B0B] cqa-text-white cqa-text-[10px] cqa-rounded cqa-whitespace-nowrap cqa-z-50 cqa-shadow-lg\"\n style=\"animation: fadeInOut 0.2s ease-in-out;\">\n Copied\n </div>\n </div>\n </div>\n <pre *ngIf=\"config.responseBody\" [ngClass]=\"{'cqa-bg-[#FEF2F2] cqa-text-[#C10007]': config.statusCode >= 400}\" class=\"cqa-h-full cqa-text-[12px] cqa-p-2 cqa-m-0 cqa-rounded cqa-overflow-auto cqa-max-h-[114px] cqa-cursor-pointer\" style=\"scrollbar-width: thin;\" (dblclick)=\"copyJsonPath($event, config.responseBody, 'responseBody')\">{{ formatJson(config.responseBody) }}</pre>\n </div>\n </div>\n\n <!-- Assertions -->\n <div *ngIf=\"config.assertions && config.assertions.length > 0\" class=\"cqa-bg-[#FCFCFC] cqa-rounded-lg cqa-p-3 cqa-flex cqa-flex-col cqa-mt-4\" style=\"border: 1px solid #EDE9FE\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2 cqa-mb-3\">\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\">Assertions</span>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium\">\n <span class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-text-[#00A63E]\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 3L4.5 8.5L2 6\" stroke=\"#00A63E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n {{ getPassedAssertions() }} passed\n </span>\n <span class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-text-[#E7000B]\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M9 3L3 9\" stroke=\"#E7000B\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M3 3L9 9\" stroke=\"#E7000B\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n {{ getFailedAssertions() }} failed\n </span>\n </div>\n </div>\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <div\n *ngFor=\"let assertion of config.assertions\"\n class=\"cqa-flex cqa-justify-between cqa-gap-2 cqa-flex-wrap cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363] cqa-px-3 cqa-py-1 cqa-rounded-md cqa-items-center\"\n [ngStyle]=\"{\n 'background-color': assertion.status === 'passed' ? '#ECFDF3' : '#FEF2F2',\n 'border': assertion.status === 'passed'\n ? '1px solid #A7F3D0'\n : '1px solid #FFC9C9'\n }\"\n >\n <div class=\"cqa-flex-1 cqa-flex cqa-items-center cqa-gap-2\">\n <div>\n <!-- Passed -->\n <ng-container *ngIf=\"assertion.status === 'passed'; else failedIcon\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"20\" height=\"20\" rx=\"10\" fill=\"#DCFCE7\"/><path d=\"M14 7L8.5 12.5L6 10\" stroke=\"#00A63E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </ng-container>\n \n <!-- Failed -->\n <ng-template #failedIcon>\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"20\" height=\"20\" rx=\"10\" fill=\"#FFE2E2\"/><path d=\"M13 7L7 13\" stroke=\"#E7000B\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7 7L13 13\" stroke=\"#E7000B\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </ng-template>\n </div>\n <div class=\"cqa-text-[12px] cqa-leading-[15px]\" \n [ngClass]=\"{\n 'cqa-text-[#9F0712]': assertion.status !== 'passed',\n 'cqa-text-[#016630]': assertion.status === 'passed'\n }\"\n >\n {{ assertion.description }}\n </div>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-4 cqa-max-w-[200px]\">\n <div>\n <span>Expected:</span>\n <span style=\"word-break: break-word;\" [ngClass]=\"assertion.status === 'passed' ? 'cqa-text-[#008236]' : 'cqa-text-[#0B0B0B]'\">\n {{ assertion.expected }}\n </span>\n </div>\n <div>\n <span>Actual:</span>\n <span style=\"word-break: break-word;\" [ngClass]=\"assertion.status === 'passed' ? 'cqa-text-green-600' : 'cqa-text-[#E7000B]'\">\n {{ assertion.actual }}\n </span>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Self Heal Analysis -->\n <cqa-self-heal-analysis \n *ngIf=\"selfHealAnalysis\" \n [id]=\"step?.testStepId\"\n [originalLocator]=\"selfHealAnalysis.originalLocator\"\n [healedLocator]=\"selfHealAnalysis.healedLocator\"\n [confidence]=\"selfHealAnalysis.confidence\"\n [healMethod]=\"selfHealAnalysis.healMethod\"\n [isLoadingAccept]=\"getSelfHealLoadingStatesHandler ? getSelfHealLoadingStatesHandler().isLoadingAccept?.[step?.testStepId] : false\"\n [isLoadingModifyAccept]=\"getSelfHealLoadingStatesHandler ? getSelfHealLoadingStatesHandler().isLoadingModifyAccept?.[step?.testStepId] : false\"\n (action)=\"onSelfHealAction($event)\">\n </cqa-self-heal-analysis>\n\n <!-- Timing Breakdown -->\n <div *ngIf=\"config.timingBreakdown\" class=\"cqa-flex cqa-items-center cqa-justify-end cqa-gap-5 cqa-pt-1.5 cqa-px-4 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF]\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <span>Timing breakdown</span>\n </div>\n <span class=\"cqa-text-dialog-muted cqa-flex cqa-items-center cqa-gap-3\">\n <div>\n App <span class=\"cqa-text-gray-700\">{{ formatDuration(config.timingBreakdown.app) }}</span>\n </div>\n <div><svg width=\"1\" height=\"11\" viewBox=\"0 0 1 11\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M-3.8147e-06 10.32V-7.15256e-07H0.959996V10.32H-3.8147e-06Z\" fill=\"#E5E7EB\"/></svg></div>\n <div>\n Tool <span class=\"cqa-text-gray-700\">{{ formatDuration(config.timingBreakdown.tool) }}</span>\n </div>\n </span>\n </div>\n </div>\n\n <!-- View More Failed Step Button - shown when expanded and failure details exist -->\n <div *ngIf=\"showViewMoreButton\" class=\"cqa-mt-2 cqa-px-4\">\n <cqa-view-more-failed-step-button\n [timingBreakdown]=\"timingBreakdown\"\n [subSteps]=\"getSubStepsForFailedStep()\"\n [failureDetails]=\"failureDetails\"\n [isExpanded]=\"showFailedStepDetails\"\n (viewMoreClick)=\"onViewMoreFailedStepClick($event)\">\n </cqa-view-more-failed-step-button>\n </div>\n\n <!-- Updated Failed Step Component - shown when button is clicked -->\n <div *ngIf=\"showViewMoreButton && showFailedStepDetails && failureDetails\" class=\"cqa-mt-2 cqa-px-4\">\n <cqa-updated-failed-step\n [testStepResultId]=\"testStepResultId\"\n [timingBreakdown]=\"timingBreakdown\"\n [expanded]=\"true\"\n [subSteps]=\"getSubStepsForFailedStep()\"\n [failureDetails]=\"failureDetails\"\n [reasoning]=\"reasoning\"\n [confidence]=\"confidence\"\n [isUploadingBaseline]=\"isUploadingBaseline\"\n [isMakingCurrentBaseline]=\"isMakingCurrentBaseline\"\n [isLive]=\"isLive\"\n (makeCurrentBaseline)=\"onMakeCurrentBaseline($event)\"\n (uploadBaseline)=\"onUploadBaseline($event)\"\n (analyze)=\"onAnalyze()\"\n (viewFullLogs)=\"onViewFullLogs()\">\n </cqa-updated-failed-step>\n </div>\n</div>\n", styles: [] }]
|
|
12846
|
+
args: [{ selector: 'cqa-api-step', host: { class: 'cqa-ui-root' }, template: "<div class=\"cqa-font-inter\" (click)=\"$event.stopPropagation()\">\n <!-- Header -->\n <div\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-p-2 cqa-cursor-pointer\"\n (click)=\"toggleHeader($event)\">\n <div *ngIf=\"showDebugIcon\" class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer cqa-rounded-full hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" (click)=\"onDebugPointClick($event)\" [attr.aria-label]=\"debugPointSet ? 'Remove debug point' : 'Set debug point'\">\n <svg *ngIf=\"debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" fill=\"#C63535\"/>\n </svg>\n <svg *ngIf=\"!debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" stroke=\"#C63535\" stroke-width=\"1.5\" fill=\"none\"/>\n </svg>\n </button>\n </div>\n <!-- Status Icon -->\n \n <div *ngIf=\"status.toLowerCase() === 'success'\" ><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <div *ngIf=\"status.toLowerCase() === 'failure' || status.toLowerCase() === 'failed'\"><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7.5 4.5L4.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 4.5L7.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <div *ngIf=\"status.toLowerCase() === 'pending'\"><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <div *ngIf=\"status.toLowerCase() === 'running'\"><svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/><path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/></svg></div>\n <!-- Skipped -->\n <div *ngIf=\"status.toLowerCase() === 'skipped'\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"12px\" viewBox=\"0 -960 960 960\" width=\"12px\" fill=\"#1f1f1f\"><path d=\"M660-240v-480h80v480h-80Zm-440 0v-480l360 240-360 240Zm80-240Zm0 90 136-90-136-90v180Z\"/></svg>\n </div>\n <!-- API Icon -->\n <div><svg width=\"20\" height=\"16\" viewBox=\"0 0 20 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"20\" height=\"16\" rx=\"4\" fill=\"#EDE9FE\"/><path d=\"M8 6.5L9.5 8L8 9.5M10.5 9.5H12M6.5 12H13.5C13.7652 12 14.0196 11.8946 14.2071 11.7071C14.3946 11.5196 14.5 11.2652 14.5 11V5C14.5 4.73478 14.3946 4.48043 14.2071 4.29289C14.0196 4.10536 13.7652 4 13.5 4H6.5C6.23478 4 5.98043 4.10536 5.79289 4.29289C5.60536 4.48043 5.5 4.73478 5.5 5V11C5.5 11.2652 5.60536 11.5196 5.79289 11.7071C5.98043 11.8946 6.23478 12 6.5 12Z\" stroke=\"#7F22FE\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n\n <!-- Step Number and Title -->\n <div class=\"cqa-flex-1 cqa-flex cqa-items-center cqa-gap-3 cqa-font-inter\">\n <span class=\"cqa-font-semibold cqa-text-[#334155] cqa-text-[14px] cqa-leading-[18px]\" style=\"word-break: break-word;\">\n {{ config?.stepNumber }}. <span [innerHTML]=\"config.title\"></span>\n </span>\n <span class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-[#7008E7] cqa-bg-[#EDE9FE] cqa-text-[10px] cqa-leading-[15px]\">\n API\n </span>\n <span class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-[#008236] cqa-bg-[#DCFCE7] cqa-text-[10px] cqa-leading-[15px]\">\n {{ config.method }}\n </span>\n <span *ngIf=\"config.stepDeleted\" class=\"cqa-px-1.5 cqa-py-[2px] cqa-rounded-[4px] cqa-text-[10px] cqa-leading-[12px] cqa-font-medium cqa-text-[#B42318] cqa-bg-[#FEF3F2] cqa-border cqa-border-[#FEE4E2]\">\n Deleted\n </span>\n </div>\n\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-font-inter\">\n <span *ngIf=\"selfHealAnalysis\" class=\"cqa-px-1.5 cqa-rounded-full cqa-font-medium cqa-text-[#097E53] cqa-bg-[#CFF2E5] cqa-text-[10px] cqa-leading-[15px] cqa-min-w-max cqa-flex cqa-items-center cqa-gap-[6px]\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"9\" height=\"9\" viewBox=\"0 0 9 9\" fill=\"none\">\n <path d=\"M4.50941 0C4.56489 0.0227384 4.58859 0.0782652 4.61131 0.129846C4.62269 0.1599 4.63314 0.190117 4.64329 0.220575C4.64726 0.232247 4.65123 0.243918 4.65532 0.255943C4.70806 0.413005 4.75504 0.571748 4.80229 0.73038C4.81297 0.76619 4.82369 0.801987 4.83442 0.837783C4.88905 1.02004 4.94327 1.2024 4.99719 1.38484C5.00476 1.41047 5.01234 1.43609 5.01992 1.46171C5.04128 1.53395 5.06262 1.60619 5.08383 1.67847C5.12867 1.8312 5.17473 1.98347 5.22378 2.13501C5.22807 2.14827 5.23236 2.16152 5.23677 2.17518C5.3642 2.565 5.54482 2.91437 5.8409 3.21196C5.84823 3.2197 5.85556 3.22744 5.86312 3.23541C5.9895 3.36437 6.15169 3.46771 6.3138 3.55111C6.32206 3.55542 6.33031 3.55974 6.33882 3.56419C6.81587 3.80925 7.38951 3.91704 7.90619 4.0605C8.1326 4.1234 8.3583 4.18829 8.58317 4.25603C8.59897 4.26079 8.61478 4.26554 8.63058 4.27028C8.67784 4.28445 8.725 4.29887 8.77211 4.31347C8.7831 4.31679 8.79408 4.32011 8.80539 4.32353C8.87029 4.34406 8.93239 4.36829 8.98566 4.41027C9.00191 4.44418 9.00191 4.44418 8.99748 4.4781C8.94564 4.52736 8.8942 4.55046 8.82578 4.573C8.816 4.57632 8.80622 4.57965 8.79614 4.58308C8.68061 4.62183 8.56351 4.65575 8.44626 4.68935C8.4222 4.6963 8.39814 4.70326 8.37408 4.71021C8.22571 4.75301 8.07708 4.7949 7.92829 4.83632C7.73232 4.89088 7.53663 4.94634 7.34113 5.00243C7.3091 5.01162 7.27706 5.02078 7.24501 5.02991C7.07671 5.07786 6.90923 5.12753 6.74314 5.18208C6.72937 5.18659 6.71559 5.1911 6.70139 5.19574C6.14511 5.38082 5.7211 5.72609 5.45571 6.23099C5.31263 6.51475 5.22823 6.82161 5.14214 7.12447C5.11884 7.20619 5.09409 7.28745 5.06905 7.36869C5.0494 7.43261 5.0302 7.49663 5.01149 7.56081C5.00926 7.56844 5.00703 7.57608 5.00473 7.58395C4.99394 7.62094 4.98319 7.65793 4.97252 7.69495C4.94519 7.78879 4.91578 7.88187 4.88555 7.97489C4.83191 8.14021 4.7831 8.30674 4.73459 8.4735C4.66144 8.72457 4.66144 8.72457 4.61997 8.84527C4.61721 8.85337 4.61446 8.86147 4.61163 8.86982C4.59649 8.91278 4.58092 8.95233 4.55226 8.9887C4.50867 8.99788 4.50867 8.99788 4.46951 9C4.42473 8.93759 4.39508 8.87711 4.37133 8.80508C4.36787 8.79487 4.36441 8.78466 4.36085 8.77415C4.31684 8.64248 4.27751 8.50946 4.23817 8.37646C4.22916 8.34604 4.22011 8.31564 4.21105 8.28524C4.1436 8.05863 4.07725 7.83174 4.01101 7.60481C3.73507 6.48224 3.73507 6.48224 3.039 5.57466C3.02784 5.56596 3.01669 5.55726 3.00519 5.5483C2.54913 5.19902 1.94834 5.06969 1.39815 4.91813C1.26207 4.88062 1.12605 4.84293 0.990032 4.80523C0.978138 4.80193 0.978138 4.80193 0.966003 4.79857C0.769811 4.74417 0.573674 4.68963 0.378224 4.63283C0.369956 4.63045 0.361688 4.62806 0.353169 4.62561C0.0528989 4.53883 0.0528989 4.53883 0.000646537 4.4781C-0.000831261 4.45054 -0.000831261 4.45054 0.0124689 4.42157C0.0670835 4.3704 0.120077 4.34848 0.19216 4.32619C0.202597 4.32284 0.213034 4.31948 0.223787 4.31603C0.255753 4.30582 0.287788 4.29584 0.319851 4.28592C0.329001 4.28305 0.338151 4.28017 0.347578 4.27722C0.412285 4.25693 0.477225 4.2374 0.542259 4.21809C0.55824 4.21332 0.55824 4.21332 0.574544 4.20846C0.852269 4.12587 1.13181 4.049 1.41126 3.97196C1.6195 3.91455 1.82738 3.85618 2.0346 3.79548C2.04413 3.79271 2.05365 3.78993 2.06346 3.78707C2.5435 3.64696 3.01278 3.44816 3.32274 3.0537C3.32738 3.04785 3.33202 3.042 3.3368 3.03597C3.68197 2.59815 3.81658 2.06572 3.96695 1.54621C4.01643 1.37534 4.06649 1.20464 4.11673 1.03399C4.13064 0.986733 4.14453 0.939471 4.15836 0.892194C4.21394 0.702289 4.27035 0.512642 4.33 0.323864C4.33558 0.306186 4.34114 0.288501 4.34666 0.270807C4.43017 0.00398761 4.43017 0.00398761 4.50941 0Z\" fill=\"#0DBD7D\"/>\n <path d=\"M7.23597 0.554859C7.29024 0.613599 7.30109 0.682631 7.31799 0.757638C7.37436 0.993269 7.43929 1.20993 7.66467 1.34681C7.80371 1.42035 7.96944 1.45381 8.1235 1.48541C8.18854 1.49902 8.24348 1.51709 8.29924 1.55321C8.31181 1.57229 8.31181 1.57229 8.31107 1.60549C8.29814 1.64588 8.28678 1.6589 8.25269 1.68533C8.21543 1.69726 8.21543 1.69726 8.17068 1.70653C8.15375 1.71025 8.13683 1.714 8.11992 1.71779C8.11086 1.7198 8.10181 1.72181 8.09247 1.72388C7.81696 1.78482 7.81696 1.78482 7.57882 1.92273C7.57108 1.92869 7.56333 1.93466 7.55536 1.9408C7.38516 2.08431 7.34916 2.32303 7.29793 2.52301C7.29499 2.53399 7.29206 2.54497 7.28903 2.55629C7.28649 2.56601 7.28395 2.57573 7.28133 2.58575C7.27028 2.61544 7.25881 2.63479 7.23597 2.65754C7.17234 2.66527 7.17234 2.66527 7.14139 2.65754C7.09216 2.62106 7.08114 2.5795 7.06828 2.52365C7.06613 2.51501 7.06398 2.50636 7.06176 2.49745C7.05489 2.46983 7.04824 2.44217 7.04164 2.41449C6.98979 2.19897 6.93126 1.98751 6.72451 1.86118C6.56293 1.77501 6.36646 1.73426 6.18587 1.70136C6.13637 1.69151 6.10802 1.67911 6.07738 1.64012C6.07073 1.60055 6.07073 1.60055 6.07738 1.56098C6.12447 1.51437 6.17402 1.50299 6.23772 1.48891C6.25778 1.48416 6.27784 1.47938 6.29789 1.47456C6.30825 1.47209 6.31861 1.46962 6.32929 1.46707C6.38212 1.45407 6.43443 1.43949 6.48673 1.42462C6.49623 1.42198 6.50573 1.41935 6.51552 1.41663C6.62182 1.38624 6.71356 1.34737 6.79854 1.27836C6.80647 1.27213 6.81439 1.26589 6.82255 1.25946C6.9548 1.14565 6.99974 0.974674 7.04053 0.815134C7.04364 0.803022 7.04675 0.79091 7.04995 0.778432C7.05614 0.754101 7.06222 0.729743 7.06817 0.705359C7.07243 0.688394 7.07243 0.688394 7.07678 0.671086C7.07927 0.660951 7.08175 0.650816 7.08431 0.640373C7.09521 0.608108 7.10952 0.582772 7.12957 0.554859C7.1681 0.536435 7.19515 0.544764 7.23597 0.554859Z\" fill=\"#075F3F\"/>\n <path d=\"M1.79545 6.2471C1.80951 6.24719 1.80951 6.24719 1.82386 6.24729C1.92477 6.25022 1.99304 6.28115 2.06736 6.34601C2.15384 6.43533 2.19377 6.53611 2.1915 6.6565C2.18178 6.75412 2.12158 6.83935 2.04773 6.90533C1.96081 6.97242 1.87313 6.99459 1.76206 6.99149C1.66841 6.98107 1.5803 6.93852 1.51393 6.87451C1.43138 6.76681 1.40725 6.66803 1.41935 6.53537C1.44433 6.43092 1.51637 6.34613 1.6085 6.28666C1.67251 6.25564 1.72399 6.24652 1.79545 6.2471Z\" fill=\"#0DBD7D\"/>\n </svg>\n Self-healed\n </span>\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-rounded-[4px] cqa-py-0.5 cqa-px-1 cqa-bg-[#6366F11A] cqa-ml-1 cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity\" \n *ngIf=\"step?.executedResult?.video_start_time\" \n [matTooltip]=\"'Jump to video time'\" \n matTooltipPosition=\"below\"\n (click)=\"onJumpToTimestamp($event)\">\n <mat-icon class=\"cqa-text-[#636363] !cqa-text-[10px] !cqa-w-[10px] !cqa-h-[10px]\">\n play_arrow\n </mat-icon>\n <span class=\"cqa-text-[8px] cqa-leading-[12px] cqa-font-normal cqa-text-[#636363]\">\n {{ formatDurationClock(step?.executedResult?.video_start_time || 0) }}\n </span>\n </div>\n <div *ngIf=\"isDebug\" class=\"cqa-flex cqa-items-center cqa-gap-0.5 cqa-text-[#9CA3AF]\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Edit\" (click)=\"onEditStep($event)\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">edit</mat-icon>\n </button>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Add\" [matMenuTriggerFor]=\"addStepMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">add</mat-icon>\n </button>\n <mat-menu #addStepMenu=\"matMenu\" class=\"cqa-add-step-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of addStepMenuOptions\" (click)=\"onAddStepOptionSelect(opt, $event)\">\n {{ opt.label }}\n </button>\n </mat-menu>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"More options\" [matMenuTriggerFor]=\"stepMoreMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">more_vert</mat-icon>\n </button>\n <mat-menu #stepMoreMenu=\"matMenu\" class=\"cqa-step-more-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of stepMoreMenuOptions\" (click)=\"onStepMoreOptionSelect(opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n </div>\n <span class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF]\">\n {{ formatDuration(config.duration) }}\n </span>\n <svg [class.cqa-rotate-180]=\"isExpanded\" class=\"cqa-transition-transform\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M3.5 5L7 8.5L10.5 5\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n </div>\n\n <!-- Expanded Content -->\n <div *ngIf=\"isExpanded\">\n <!-- Initial Actions -->\n <div *ngIf=\"config.initialActions && config.initialActions.length > 0\" class=\"cqa-flex cqa-flex-col cqa-gap-1 cqa-ml-9\">\n <!-- Single loop: render all entries in chronological order -->\n <ng-container *ngFor=\"let action of (isLive ? processedInitialActions : processedInitialActionsForRunResult)\">\n <!-- AI_AUTO_HEAL_SUCCESS/FAILED: render with ai-agent-step style (both live and run result screens) -->\n <cqa-ai-logs-with-reasoning\n *ngIf=\"$any(action).isAiAutoHealResult\"\n [status]=\"action.status\"\n [text]=\"$any(action).text || action?.value\"\n [description]=\"$any(action).description || action?.text || action?.value\"\n [reasoning]=\"$any(action).reasoning || action?.reasoning\"\n [duration]=\"action.duration\">\n </cqa-ai-logs-with-reasoning>\n\n <!-- Regular initial actions -->\n <div\n *ngIf=\"!$any(action).isAiAutoHealResult\"\n class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-py-[5.5px] cqa-px-3\">\n \n <div *ngIf=\"action?.status?.toLowerCase() === 'success' || action?.status?.toLowerCase() === 'passed'\" >\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Failure -->\n <div *ngIf=\"action?.status?.toLowerCase() === 'failure' || action?.status?.toLowerCase() === 'failed'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7.5 4.5L4.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 4.5L7.5 7.5\" stroke=\"#DC2626\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Pending -->\n <div *ngIf=\"action?.status?.toLowerCase() === 'pending'\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n <!-- Running - Show spinner (also used for active WAIT_FOR_LOCATOR countdown in live mode) -->\n <div *ngIf=\"action?.status?.toLowerCase() === 'running'\">\n <svg class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n </div>\n\n <!-- Action Description -->\n <span class=\"cqa-flex-1 cqa-text-[13px] cqa-leading-[15px] cqa-text-[#364153]\" style=\"white-space: pre-line; word-break: break-word;\">\n {{ $any(action).description || $any(action).text }}\n <!-- Countdown for active WAIT_FOR_LOCATOR in live mode -->\n <span *ngIf=\"isLive && $any(action).remainingSeconds != null\" class=\"cqa-text-[#F97316] cqa-font-medium cqa-ml-1\">({{ $any(action).remainingSeconds }}s remaining)</span>\n </span>\n\n <!-- Action Duration -->\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-metadata-key\">\n {{ formatDuration(action.duration) }}\n </span>\n </div>\n </ng-container>\n </div>\n\n <!-- Request Summary Card -->\n <div *ngIf=\"!isLive\" class=\"cqa-bg-[#FFFEF9] cqa-mt-1.5 cqa-ml-9 cqa-mr-6 cqa-p-4\" style=\"border-top: 1px solid #E4E4E4;\">\n \n <div class=\"cqa-bg-[#FCFCFC] cqa-rounded-lg cqa-p-3\" style=\"border: 1px solid #EDE9FE\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-mb-3 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\">\n <span>Request Summary</span>\n <div class=\"cqa-relative\">\n <button (click)=\"copyRequestSummary()\" class=\"cqa-flex cqa-items-center cqa-gap-1 p-0\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 4H5C4.44772 4 4 4.44772 4 5V10C4 10.5523 4.44772 11 5 11H10C10.5523 11 11 10.5523 11 10V5C11 4.44772 10.5523 4 10 4Z\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M2 8C1.45 8 1 7.55 1 7V2C1 1.45 1.45 1 2 1H7C7.55 1 8 1.45 8 2\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n Copy\n </button>\n <!-- Copied Tooltip -->\n <div \n *ngIf=\"showRequestSummaryCopied\" \n class=\"cqa-absolute cqa-right-0 cqa-top-full cqa-mt-1 cqa-px-2 cqa-py-1 cqa-bg-[#0B0B0B] cqa-text-white cqa-text-[10px] cqa-rounded cqa-whitespace-nowrap cqa-z-50 cqa-shadow-lg\"\n style=\"animation: fadeInOut 0.2s ease-in-out;\">\n Copied!\n </div>\n </div>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-cursor-pointer\" (dblclick)=\"copyRequestSummary()\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <span class=\"cqa-px-1 cqa-py-[2px] cqa-rounded cqa-font-medium cqa-text-[#008236] cqa-bg-[#DCFCE7] cqa-text-[10px] cqa-leading-[15px]\">\n {{ config.method }}\n </span>\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#0B0B0B]\">{{ config.endpoint }}</span>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-3\">\n <span *ngIf=\"config?.statusCode === 200 || config?.statusCode === 201\" class=\"cqa-flex cqa-items-center cqa-gap-1.5 cqa-px-1 cqa-py-[2px] cqa-rounded cqa-font-medium cqa-text-[#00A63E] cqa-bg-[#DCFCE7] cqa-text-[10px] cqa-leading-[15px]\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 3L4.5 8.5L2 6\" stroke=\"#00A63E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path></svg>\n {{ config.statusCode }}\n </span>\n <span *ngIf=\"config?.statusCode && config?.statusCode !== 200 && config?.statusCode !== 201\" class=\"cqa-flex cqa-items-center cqa-gap-1.5 cqa-px-1 cqa-py-[2px] cqa-rounded cqa-font-medium cqa-text-[#E7000B] cqa-bg-[#FFE2E2] cqa-text-[10px] cqa-leading-[15px]\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.5 3.5L3.5 10.5\" stroke=\"#E7000B\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M3.5 3.5L10.5 10.5\" stroke=\"#E7000B\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n {{ config.statusCode }}\n </span>\n <div class=\"cqa-flex cqa-items-center cqa-gap-1.5 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\" *ngIf=\"config?.responseTime\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6.99999 12.8334C10.2217 12.8334 12.8333 10.2217 12.8333 7.00008C12.8333 3.77842 10.2217 1.16675 6.99999 1.16675C3.77833 1.16675 1.16666 3.77842 1.16666 7.00008C1.16666 10.2217 3.77833 12.8334 6.99999 12.8334Z\" stroke=\"#636363\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7 3.5V7L9.33333 8.16667\" stroke=\"#636363\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <span>{{ config.responseTime }}ms</span>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Request/Response Headers -->\n <div class=\"cqa-grid cqa-grid-cols-2 cqa-gap-3 cqa-mt-4\" *ngIf=\"config?.requestHeaders || config?.responseHeaders\">\n <!-- Request Headers -->\n <div class=\"cqa-bg-[#FCFCFC] cqa-rounded-lg cqa-p-3 cqa-flex cqa-flex-col\" style=\"border: 1px solid #EDE9FE\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2 cqa-mb-2\">\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\">Request Headers</span>\n <div class=\"cqa-relative\">\n <button (click)=\"copyRequestHeaders()\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 4H5C4.44772 4 4 4.44772 4 5V10C4 10.5523 4.44772 11 5 11H10C10.5523 11 11 10.5523 11 10V5C11 4.44772 10.5523 4 10 4Z\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M2 8C1.45 8 1 7.55 1 7V2C1 1.45 1.45 1 2 1H7C7.55 1 8 1.45 8 2\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </button>\n <!-- Copied Tooltip -->\n <div \n *ngIf=\"showRequestHeadersCopied\" \n class=\"cqa-absolute cqa-right-0 cqa-top-full cqa-mt-1 cqa-px-2 cqa-py-1 cqa-bg-[#0B0B0B] cqa-text-white cqa-text-[10px] cqa-rounded cqa-whitespace-nowrap cqa-z-50 cqa-shadow-lg\"\n style=\"animation: fadeInOut 0.2s ease-in-out;\">\n Copied\n </div>\n </div>\n </div>\n <pre *ngIf=\"config.requestHeaders\" class=\"cqa-h-full cqa-text-[12px] cqa-text-[#0B0B0B] cqa-bg-[#F8F8F8] cqa-p-2 cqa-m-0 cqa-rounded cqa-overflow-auto cqa-max-h-[114px] cqa-cursor-pointer\" style=\"scrollbar-width: thin;\" (dblclick)=\"copyJsonPath($event, config.requestHeaders, 'requestHeaders')\">{{ formatJson(config.requestHeaders) }}</pre>\n </div>\n\n <!-- Response Headers -->\n <div class=\"cqa-bg-[#FCFCFC] cqa-rounded-lg cqa-p-3 cqa-flex cqa-flex-col\" style=\"border: 1px solid #EDE9FE\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-mb-2\">\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\">Response Headers</span>\n <div class=\"cqa-relative\">\n <button (click)=\"copyResponseHeaders()\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 4H5C4.44772 4 4 4.44772 4 5V10C4 10.5523 4.44772 11 5 11H10C10.5523 11 11 10.5523 11 10V5C11 4.44772 10.5523 4 10 4Z\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M2 8C1.45 8 1 7.55 1 7V2C1 1.45 1.45 1 2 1H7C7.55 1 8 1.45 8 2\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </button>\n <!-- Copied Tooltip -->\n <div \n *ngIf=\"showResponseHeadersCopied\" \n class=\"cqa-absolute cqa-right-0 cqa-top-full cqa-mt-1 cqa-px-2 cqa-py-1 cqa-bg-[#0B0B0B] cqa-text-white cqa-text-[10px] cqa-rounded cqa-whitespace-nowrap cqa-z-50 cqa-shadow-lg\"\n style=\"animation: fadeInOut 0.2s ease-in-out;\">\n Copied\n </div>\n </div>\n </div>\n <pre *ngIf=\"config.responseHeaders\" [ngClass]=\"{'cqa-bg-[#FEF2F2] cqa-text-[#C10007]': config.statusCode >= 400}\" class=\"cqa-h-full cqa-text-[12px] cqa-p-2 cqa-m-0 cqa-rounded cqa-overflow-auto cqa-max-h-[114px] cqa-cursor-pointer\" style=\"scrollbar-width: thin;\" (dblclick)=\"copyJsonPath($event, config.responseHeaders, 'responseHeaders')\">{{ formatJson(config.responseHeaders) }}</pre>\n </div>\n </div>\n\n <!-- Request/Response Bodies -->\n <div class=\"cqa-grid cqa-grid-cols-2 cqa-gap-3 cqa-mt-4\" *ngIf=\"config?.requestBody || config?.responseBody\">\n <!-- Request Body -->\n <div class=\"cqa-bg-[#FCFCFC] cqa-rounded-lg cqa-p-3 cqa-flex cqa-flex-col\" style=\"border: 1px solid #EDE9FE\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2 cqa-mb-2\">\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\">Request Body</span>\n <div class=\"cqa-relative\">\n <button (click)=\"copyRequestBody()\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 4H5C4.44772 4 4 4.44772 4 5V10C4 10.5523 4.44772 11 5 11H10C10.5523 11 11 10.5523 11 10V5C11 4.44772 10.5523 4 10 4Z\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M2 8C1.45 8 1 7.55 1 7V2C1 1.45 1.45 1 2 1H7C7.55 1 8 1.45 8 2\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </button>\n <!-- Copied Tooltip -->\n <div \n *ngIf=\"showRequestBodyCopied\" \n class=\"cqa-absolute cqa-right-0 cqa-top-full cqa-mt-1 cqa-px-2 cqa-py-1 cqa-bg-[#0B0B0B] cqa-text-white cqa-text-[10px] cqa-rounded cqa-whitespace-nowrap cqa-z-50 cqa-shadow-lg\"\n style=\"animation: fadeInOut 0.2s ease-in-out;\">\n Copied\n </div>\n </div>\n </div>\n <pre *ngIf=\"config.requestBody\" class=\"cqa-h-full cqa-text-[12px] cqa-text-[#0B0B0B] cqa-bg-[#F8F8F8] cqa-p-2 cqa-m-0 cqa-rounded cqa-overflow-auto cqa-max-h-[114px] cqa-cursor-pointer\" style=\"scrollbar-width: thin;\" (dblclick)=\"copyJsonPath($event, config.requestBody, 'requestBody')\">{{ formatJson(config.requestBody) }}</pre>\n </div>\n\n <!-- Response Body -->\n <div class=\"cqa-bg-[#FCFCFC] cqa-rounded-lg cqa-p-3 cqa-flex cqa-flex-col\" style=\"border: 1px solid #EDE9FE\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-mb-2\">\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\">Response Body</span>\n <div class=\"cqa-relative\">\n <button (click)=\"copyResponseBody()\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 4H5C4.44772 4 4 4.44772 4 5V10C4 10.5523 4.44772 11 5 11H10C10.5523 11 11 10.5523 11 10V5C11 4.44772 10.5523 4 10 4Z\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M2 8C1.45 8 1 7.55 1 7V2C1 1.45 1.45 1 2 1H7C7.55 1 8 1.45 8 2\" stroke=\"#636363\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </button>\n <!-- Copied Tooltip -->\n <div \n *ngIf=\"showResponseBodyCopied\" \n class=\"cqa-absolute cqa-right-0 cqa-top-full cqa-mt-1 cqa-px-2 cqa-py-1 cqa-bg-[#0B0B0B] cqa-text-white cqa-text-[10px] cqa-rounded cqa-whitespace-nowrap cqa-z-50 cqa-shadow-lg\"\n style=\"animation: fadeInOut 0.2s ease-in-out;\">\n Copied\n </div>\n </div>\n </div>\n <pre *ngIf=\"config.responseBody\" [ngClass]=\"{'cqa-bg-[#FEF2F2] cqa-text-[#C10007]': config.statusCode >= 400}\" class=\"cqa-h-full cqa-text-[12px] cqa-p-2 cqa-m-0 cqa-rounded cqa-overflow-auto cqa-max-h-[114px] cqa-cursor-pointer\" style=\"scrollbar-width: thin;\" (dblclick)=\"copyJsonPath($event, config.responseBody, 'responseBody')\">{{ formatJson(config.responseBody) }}</pre>\n </div>\n </div>\n\n <!-- Assertions -->\n <div *ngIf=\"config.assertions && config.assertions.length > 0\" class=\"cqa-bg-[#FCFCFC] cqa-rounded-lg cqa-p-3 cqa-flex cqa-flex-col cqa-mt-4\" style=\"border: 1px solid #EDE9FE\">\n <div class=\"cqa-flex cqa-items-center cqa-justify-between cqa-gap-2 cqa-mb-3\">\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363]\">Assertions</span>\n <div class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium\">\n <span class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-text-[#00A63E]\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 3L4.5 8.5L2 6\" stroke=\"#00A63E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n {{ getPassedAssertions() }} passed\n </span>\n <span class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-text-[#E7000B]\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M9 3L3 9\" stroke=\"#E7000B\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M3 3L9 9\" stroke=\"#E7000B\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n {{ getFailedAssertions() }} failed\n </span>\n </div>\n </div>\n <div class=\"cqa-flex cqa-flex-col cqa-gap-2\">\n <div\n *ngFor=\"let assertion of config.assertions\"\n class=\"cqa-flex cqa-justify-between cqa-gap-2 cqa-flex-wrap cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#636363] cqa-px-3 cqa-py-1 cqa-rounded-md cqa-items-center\"\n [ngStyle]=\"{\n 'background-color': assertion.status === 'passed' ? '#ECFDF3' : '#FEF2F2',\n 'border': assertion.status === 'passed'\n ? '1px solid #A7F3D0'\n : '1px solid #FFC9C9'\n }\"\n >\n <div class=\"cqa-flex-1 cqa-flex cqa-items-center cqa-gap-2\">\n <div>\n <!-- Passed -->\n <ng-container *ngIf=\"assertion.status === 'passed'; else failedIcon\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"20\" height=\"20\" rx=\"10\" fill=\"#DCFCE7\"/><path d=\"M14 7L8.5 12.5L6 10\" stroke=\"#00A63E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </ng-container>\n \n <!-- Failed -->\n <ng-template #failedIcon>\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"20\" height=\"20\" rx=\"10\" fill=\"#FFE2E2\"/><path d=\"M13 7L7 13\" stroke=\"#E7000B\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M7 7L13 13\" stroke=\"#E7000B\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </ng-template>\n </div>\n <div class=\"cqa-text-[12px] cqa-leading-[15px]\" \n [ngClass]=\"{\n 'cqa-text-[#9F0712]': assertion.status !== 'passed',\n 'cqa-text-[#016630]': assertion.status === 'passed'\n }\"\n >\n {{ assertion.description }}\n </div>\n </div>\n <div class=\"cqa-flex cqa-items-center cqa-gap-4 cqa-max-w-[200px]\">\n <div>\n <span>Expected:</span>\n <span style=\"word-break: break-word;\" [ngClass]=\"assertion.status === 'passed' ? 'cqa-text-[#008236]' : 'cqa-text-[#0B0B0B]'\">\n {{ assertion.expected }}\n </span>\n </div>\n <div>\n <span>Actual:</span>\n <span style=\"word-break: break-word;\" [ngClass]=\"assertion.status === 'passed' ? 'cqa-text-green-600' : 'cqa-text-[#E7000B]'\">\n {{ assertion.actual }}\n </span>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Self Heal Analysis -->\n <cqa-self-heal-analysis \n *ngIf=\"selfHealAnalysis\" \n [id]=\"step?.testStepId\"\n [originalLocator]=\"selfHealAnalysis.originalLocator\"\n [healedLocator]=\"selfHealAnalysis.healedLocator\"\n [confidence]=\"selfHealAnalysis.confidence\"\n [healMethod]=\"selfHealAnalysis.healMethod\"\n [isLoadingAccept]=\"getSelfHealLoadingStatesHandler ? getSelfHealLoadingStatesHandler().isLoadingAccept?.[step?.testStepId] : false\"\n [isLoadingModifyAccept]=\"getSelfHealLoadingStatesHandler ? getSelfHealLoadingStatesHandler().isLoadingModifyAccept?.[step?.testStepId] : false\"\n (action)=\"onSelfHealAction($event)\">\n </cqa-self-heal-analysis>\n\n <!-- Timing Breakdown -->\n <div *ngIf=\"config.timingBreakdown\" class=\"cqa-flex cqa-items-center cqa-justify-end cqa-gap-5 cqa-pt-1.5 cqa-px-4 cqa-text-[10px] cqa-leading-[15px] cqa-font-medium cqa-text-[#9CA3AF]\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\">\n <div><svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg></div>\n <span>Timing breakdown</span>\n </div>\n <span class=\"cqa-text-dialog-muted cqa-flex cqa-items-center cqa-gap-3\">\n <div>\n App <span class=\"cqa-text-gray-700\">{{ formatDuration(config.timingBreakdown.app) }}</span>\n </div>\n <div><svg width=\"1\" height=\"11\" viewBox=\"0 0 1 11\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M-3.8147e-06 10.32V-7.15256e-07H0.959996V10.32H-3.8147e-06Z\" fill=\"#E5E7EB\"/></svg></div>\n <div>\n Tool <span class=\"cqa-text-gray-700\">{{ formatDuration(config.timingBreakdown.tool) }}</span>\n </div>\n </span>\n </div>\n </div>\n\n <!-- View More Failed Step Button - shown when expanded and failure details exist -->\n <div *ngIf=\"showViewMoreButton\" class=\"cqa-mt-2 cqa-px-4\">\n <cqa-view-more-failed-step-button\n [timingBreakdown]=\"timingBreakdown\"\n [subSteps]=\"getSubStepsForFailedStep()\"\n [failureDetails]=\"failureDetails\"\n [isExpanded]=\"showFailedStepDetails\"\n (viewMoreClick)=\"onViewMoreFailedStepClick($event)\">\n </cqa-view-more-failed-step-button>\n </div>\n\n <!-- Updated Failed Step Component - shown when button is clicked -->\n <div *ngIf=\"showViewMoreButton && showFailedStepDetails && failureDetails\" class=\"cqa-mt-2 cqa-px-4\">\n <cqa-updated-failed-step\n [testStepResultId]=\"testStepResultId\"\n [timingBreakdown]=\"timingBreakdown\"\n [expanded]=\"true\"\n [subSteps]=\"getSubStepsForFailedStep()\"\n [failureDetails]=\"failureDetails\"\n [reasoning]=\"reasoning\"\n [confidence]=\"confidence\"\n [isUploadingBaseline]=\"isUploadingBaseline\"\n [isMakingCurrentBaseline]=\"isMakingCurrentBaseline\"\n [isLive]=\"isLive\"\n (makeCurrentBaseline)=\"onMakeCurrentBaseline($event)\"\n (uploadBaseline)=\"onUploadBaseline($event)\"\n (analyze)=\"onAnalyze()\"\n (viewFullLogs)=\"onViewFullLogs()\">\n </cqa-updated-failed-step>\n </div>\n</div>\n", styles: [] }]
|
|
12131
12847
|
}], propDecorators: { id: [{
|
|
12132
12848
|
type: Input
|
|
12133
12849
|
}], testStepResultId: [{
|
|
@@ -12561,6 +13277,13 @@ class LiveExecutionStepComponent extends BaseStepComponent {
|
|
|
12561
13277
|
this.stepMoreMenuOptions = DEFAULT_STEP_MORE_MENU_OPTIONS;
|
|
12562
13278
|
this.subSteps = [];
|
|
12563
13279
|
this.userManuallyClosed = false;
|
|
13280
|
+
// Processed sub-steps for WAIT_FOR_LOCATOR countdown grouping
|
|
13281
|
+
this.processedSubSteps = [];
|
|
13282
|
+
this.lastProcessedIndex = 0;
|
|
13283
|
+
this.waitLocatorGroupEntry = null;
|
|
13284
|
+
this.countdownIntervalId = null;
|
|
13285
|
+
// AI_AUTO_HEAL grouping: show loading until AI_AUTO_HEAL_SUCCESS or AI_AUTO_HEAL_FAILED
|
|
13286
|
+
this.aiAutoHealGroupEntry = null;
|
|
12564
13287
|
}
|
|
12565
13288
|
/** Show debug icon only when this step has no child steps (leaf step: always show when isDebug). */
|
|
12566
13289
|
get showDebugIcon() {
|
|
@@ -12583,6 +13306,10 @@ class LiveExecutionStepComponent extends BaseStepComponent {
|
|
|
12583
13306
|
super.ngOnInit();
|
|
12584
13307
|
// Initialize previous status
|
|
12585
13308
|
this.previousStatus = this.status;
|
|
13309
|
+
// Process any subSteps that were passed at init time
|
|
13310
|
+
if (this.subSteps && this.subSteps.length > 0) {
|
|
13311
|
+
this.processLiveSubSteps();
|
|
13312
|
+
}
|
|
12586
13313
|
// Auto-expand if step is running and has subSteps on init
|
|
12587
13314
|
if (this.status === 'running' && this.hasSubSteps && !this.isExpanded) {
|
|
12588
13315
|
this.autoExpand();
|
|
@@ -12598,6 +13325,8 @@ class LiveExecutionStepComponent extends BaseStepComponent {
|
|
|
12598
13325
|
if (this.config) {
|
|
12599
13326
|
this.config.subSteps = this.subSteps || [];
|
|
12600
13327
|
}
|
|
13328
|
+
// Process incoming subSteps for WAIT_FOR_LOCATOR grouping
|
|
13329
|
+
this.processLiveSubSteps();
|
|
12601
13330
|
// Auto-expand if step is running and new subSteps are added (logs coming in)
|
|
12602
13331
|
if (!changes['subSteps'].firstChange &&
|
|
12603
13332
|
this.status === 'running' &&
|
|
@@ -12636,6 +13365,12 @@ class LiveExecutionStepComponent extends BaseStepComponent {
|
|
|
12636
13365
|
this.config.stepDeleted = changes['stepDeleted'].currentValue;
|
|
12637
13366
|
}
|
|
12638
13367
|
}
|
|
13368
|
+
ngDoCheck() {
|
|
13369
|
+
const currentLength = (this.subSteps || []).length;
|
|
13370
|
+
if (currentLength !== this.lastProcessedIndex) {
|
|
13371
|
+
this.processLiveSubSteps();
|
|
13372
|
+
}
|
|
13373
|
+
}
|
|
12639
13374
|
onDebugPointClick(event) {
|
|
12640
13375
|
event.preventDefault();
|
|
12641
13376
|
event.stopPropagation();
|
|
@@ -12660,7 +13395,7 @@ class LiveExecutionStepComponent extends BaseStepComponent {
|
|
|
12660
13395
|
}
|
|
12661
13396
|
}
|
|
12662
13397
|
get hasSubSteps() {
|
|
12663
|
-
return this.
|
|
13398
|
+
return this.processedSubSteps && this.processedSubSteps.length > 0;
|
|
12664
13399
|
}
|
|
12665
13400
|
trackBySubStepId(index, subStep) {
|
|
12666
13401
|
return subStep.id;
|
|
@@ -12680,12 +13415,146 @@ class LiveExecutionStepComponent extends BaseStepComponent {
|
|
|
12680
13415
|
event.stopPropagation();
|
|
12681
13416
|
this.stepMoreOptionSelect.emit(option);
|
|
12682
13417
|
}
|
|
13418
|
+
ngOnDestroy() {
|
|
13419
|
+
this.clearCountdownTimer();
|
|
13420
|
+
}
|
|
13421
|
+
processLiveSubSteps() {
|
|
13422
|
+
var _a, _b, _c, _d;
|
|
13423
|
+
const allSubSteps = (this.subSteps || []);
|
|
13424
|
+
// Reset if subSteps were cleared or replaced with fewer entries
|
|
13425
|
+
if (allSubSteps.length < this.lastProcessedIndex) {
|
|
13426
|
+
this.resetLiveProcessing();
|
|
13427
|
+
}
|
|
13428
|
+
for (let i = this.lastProcessedIndex; i < allSubSteps.length; i++) {
|
|
13429
|
+
const subStep = allSubSteps[i];
|
|
13430
|
+
const uiType = (subStep === null || subStep === void 0 ? void 0 : subStep.uiType) || (subStep === null || subStep === void 0 ? void 0 : subStep.type) || '';
|
|
13431
|
+
const status = ((subStep === null || subStep === void 0 ? void 0 : subStep.status) || '').toLowerCase();
|
|
13432
|
+
if (uiType === 'WAIT_FOR_LOCATOR') {
|
|
13433
|
+
// Create a single grouped entry with a countdown; absorbs FIND_LOCATOR and LOCATOR_FOUND
|
|
13434
|
+
const timeoutSeconds = typeof subStep.value === 'number'
|
|
13435
|
+
? subStep.value
|
|
13436
|
+
: (subStep.value ? parseFloat(subStep.value) : 30);
|
|
13437
|
+
this.clearCountdownTimer();
|
|
13438
|
+
this.waitLocatorGroupEntry = Object.assign(Object.assign({}, subStep), { isRunning: true, remainingSeconds: timeoutSeconds, status: 'pending' });
|
|
13439
|
+
this.processedSubSteps.push(this.waitLocatorGroupEntry);
|
|
13440
|
+
// Tick down every second
|
|
13441
|
+
this.countdownIntervalId = setInterval(() => {
|
|
13442
|
+
if (this.waitLocatorGroupEntry) {
|
|
13443
|
+
this.waitLocatorGroupEntry.remainingSeconds = Math.max(0, this.waitLocatorGroupEntry.remainingSeconds - 1);
|
|
13444
|
+
if (this.waitLocatorGroupEntry.remainingSeconds <= 0) {
|
|
13445
|
+
this.waitLocatorGroupEntry.isRunning = false;
|
|
13446
|
+
this.waitLocatorGroupEntry.status = 'failed';
|
|
13447
|
+
this.waitLocatorGroupEntry.remainingSeconds = null;
|
|
13448
|
+
this.clearCountdownTimer();
|
|
13449
|
+
this.waitLocatorGroupEntry = null;
|
|
13450
|
+
}
|
|
13451
|
+
}
|
|
13452
|
+
}, 1000);
|
|
13453
|
+
}
|
|
13454
|
+
else if (uiType === 'FIND_LOCATOR') {
|
|
13455
|
+
if (status === 'failed' || status === 'failure') {
|
|
13456
|
+
// Abort countdown, replace group entry with this failed log
|
|
13457
|
+
if (this.waitLocatorGroupEntry) {
|
|
13458
|
+
this.processedSubSteps = this.processedSubSteps.filter(entry => entry !== this.waitLocatorGroupEntry);
|
|
13459
|
+
this.clearCountdownTimer();
|
|
13460
|
+
this.waitLocatorGroupEntry = null;
|
|
13461
|
+
}
|
|
13462
|
+
this.processedSubSteps.push(Object.assign(Object.assign({}, subStep), { isRunning: false, status: 'failed' }));
|
|
13463
|
+
}
|
|
13464
|
+
else if (this.waitLocatorGroupEntry) {
|
|
13465
|
+
// Update the single group entry's text so the user sees progress
|
|
13466
|
+
const newText = subStep.text || subStep.description || subStep.title;
|
|
13467
|
+
if (newText)
|
|
13468
|
+
this.waitLocatorGroupEntry.text = newText;
|
|
13469
|
+
}
|
|
13470
|
+
}
|
|
13471
|
+
else if (uiType === 'LOCATOR_FOUND') {
|
|
13472
|
+
if (status === 'failed' || status === 'failure') {
|
|
13473
|
+
// Abort countdown, replace group entry with this failed log
|
|
13474
|
+
if (this.waitLocatorGroupEntry) {
|
|
13475
|
+
this.processedSubSteps = this.processedSubSteps.filter(entry => entry !== this.waitLocatorGroupEntry);
|
|
13476
|
+
this.clearCountdownTimer();
|
|
13477
|
+
this.waitLocatorGroupEntry = null;
|
|
13478
|
+
}
|
|
13479
|
+
this.processedSubSteps.push(Object.assign(Object.assign({}, subStep), { isRunning: false, status: 'failed' }));
|
|
13480
|
+
}
|
|
13481
|
+
else {
|
|
13482
|
+
// Sequence complete – update the group entry to show LOCATOR_FOUND text as success
|
|
13483
|
+
if (this.waitLocatorGroupEntry) {
|
|
13484
|
+
const newText = subStep.text || subStep.description || subStep.title;
|
|
13485
|
+
if (newText)
|
|
13486
|
+
this.waitLocatorGroupEntry.text = newText;
|
|
13487
|
+
this.waitLocatorGroupEntry.isRunning = false;
|
|
13488
|
+
this.waitLocatorGroupEntry.status = 'success';
|
|
13489
|
+
this.waitLocatorGroupEntry.remainingSeconds = null;
|
|
13490
|
+
this.clearCountdownTimer();
|
|
13491
|
+
this.waitLocatorGroupEntry = null;
|
|
13492
|
+
}
|
|
13493
|
+
else {
|
|
13494
|
+
// No active group – just push LOCATOR_FOUND normally
|
|
13495
|
+
this.processedSubSteps.push(Object.assign(Object.assign({}, subStep), { isRunning: false }));
|
|
13496
|
+
}
|
|
13497
|
+
}
|
|
13498
|
+
}
|
|
13499
|
+
else if (uiType === 'AI_AUTO_HEAL') {
|
|
13500
|
+
// Add single loading entry; will be replaced by AI_AUTO_HEAL_SUCCESS or AI_AUTO_HEAL_FAILED
|
|
13501
|
+
this.aiAutoHealGroupEntry = Object.assign(Object.assign({}, subStep), { text: subStep.text || subStep.description || 'AI auto-heal started', isRunning: true, status: 'pending', uiType: 'AI_AUTO_HEAL' });
|
|
13502
|
+
this.processedSubSteps.push(this.aiAutoHealGroupEntry);
|
|
13503
|
+
}
|
|
13504
|
+
else if (uiType === 'AI_AUTO_HEAL_SUCCESS' || uiType === 'AI_AUTO_HEAL_FAILED') {
|
|
13505
|
+
// Remove loading entry and add TWO separate entries: value and reasoning (like AI_ANSWER)
|
|
13506
|
+
if (this.aiAutoHealGroupEntry) {
|
|
13507
|
+
this.processedSubSteps = this.processedSubSteps.filter(entry => entry !== this.aiAutoHealGroupEntry);
|
|
13508
|
+
this.aiAutoHealGroupEntry = null;
|
|
13509
|
+
}
|
|
13510
|
+
const isSuccess = uiType === 'AI_AUTO_HEAL_SUCCESS';
|
|
13511
|
+
const value = (_b = (_a = subStep.value) !== null && _a !== void 0 ? _a : subStep.text) !== null && _b !== void 0 ? _b : '';
|
|
13512
|
+
const reasoning = (_d = (_c = subStep.reasoning) !== null && _c !== void 0 ? _c : subStep.Reasoning) !== null && _d !== void 0 ? _d : '';
|
|
13513
|
+
const baseDuration = subStep.duration || 0;
|
|
13514
|
+
const finalStatus = isSuccess ? 'success' : 'failed';
|
|
13515
|
+
// First entry: value/description
|
|
13516
|
+
const valueDescription = subStep.text || subStep.description || (isSuccess
|
|
13517
|
+
? `AI auto-heal successful. New locator: ${value}`
|
|
13518
|
+
: `AI auto-heal failed for element: ${value}`);
|
|
13519
|
+
this.processedSubSteps.push(Object.assign(Object.assign({}, subStep), { text: valueDescription, description: valueDescription, value: value, reasoning: null, isRunning: false, status: finalStatus, uiType: 'AI_AUTO_HEAL_VALUE', type: 'AI_AUTO_HEAL_VALUE', duration: baseDuration, isAiAutoHealResult: true }));
|
|
13520
|
+
// Second entry: reasoning (only if present)
|
|
13521
|
+
if (reasoning) {
|
|
13522
|
+
this.processedSubSteps.push(Object.assign(Object.assign({}, subStep), { text: reasoning, description: reasoning, value: null, reasoning: reasoning, isRunning: false, status: finalStatus, uiType: 'AI_AUTO_HEAL_REASONING', type: 'AI_AUTO_HEAL_REASONING', duration: baseDuration, isAiAutoHealResult: true }));
|
|
13523
|
+
}
|
|
13524
|
+
}
|
|
13525
|
+
else {
|
|
13526
|
+
// Any failed log while a countdown is active – resolve it as failed
|
|
13527
|
+
if ((status === 'failed' || status === 'failure') && this.waitLocatorGroupEntry) {
|
|
13528
|
+
this.waitLocatorGroupEntry.isRunning = false;
|
|
13529
|
+
this.waitLocatorGroupEntry.status = 'failed';
|
|
13530
|
+
this.waitLocatorGroupEntry.remainingSeconds = null;
|
|
13531
|
+
this.clearCountdownTimer();
|
|
13532
|
+
this.waitLocatorGroupEntry = null;
|
|
13533
|
+
}
|
|
13534
|
+
this.processedSubSteps.push(subStep);
|
|
13535
|
+
}
|
|
13536
|
+
}
|
|
13537
|
+
this.lastProcessedIndex = allSubSteps.length;
|
|
13538
|
+
}
|
|
13539
|
+
resetLiveProcessing() {
|
|
13540
|
+
this.clearCountdownTimer();
|
|
13541
|
+
this.processedSubSteps = [];
|
|
13542
|
+
this.lastProcessedIndex = 0;
|
|
13543
|
+
this.waitLocatorGroupEntry = null;
|
|
13544
|
+
this.aiAutoHealGroupEntry = null;
|
|
13545
|
+
}
|
|
13546
|
+
clearCountdownTimer() {
|
|
13547
|
+
if (this.countdownIntervalId !== null) {
|
|
13548
|
+
clearInterval(this.countdownIntervalId);
|
|
13549
|
+
this.countdownIntervalId = null;
|
|
13550
|
+
}
|
|
13551
|
+
}
|
|
12683
13552
|
}
|
|
12684
13553
|
LiveExecutionStepComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: LiveExecutionStepComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
12685
|
-
LiveExecutionStepComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: LiveExecutionStepComponent, selector: "cqa-live-execution-step", inputs: { id: "id", testStepResultId: "testStepResultId", stepNumber: "stepNumber", title: "title", status: "status", isDebug: "isDebug", debugPointSet: "debugPointSet", addStepMenuOptions: "addStepMenuOptions", stepMoreMenuOptions: "stepMoreMenuOptions", duration: "duration", expanded: "expanded", subSteps: "subSteps", stepDeleted: "stepDeleted" }, outputs: { debugPointChange: "debugPointChange", editStep: "editStep", addStepOptionSelect: "addStepOptionSelect", stepMoreOptionSelect: "stepMoreOptionSelect" }, host: { classAttribute: "cqa-ui-root" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-font-inter\">\n <!-- Header -->\n <div\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-p-2 cqa-cursor-pointer\"\n (click)=\"toggle()\"\n style=\"border-bottom: '1px solid #F3F4F6'\"\n >\n <div *ngIf=\"showDebugIcon\" class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer cqa-rounded-full hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" (click)=\"onDebugPointClick($event)\" [attr.aria-label]=\"debugPointSet ? 'Remove debug point' : 'Set debug point'\">\n <svg *ngIf=\"debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" fill=\"#C63535\"/>\n </svg>\n <svg *ngIf=\"!debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" stroke=\"#C63535\" stroke-width=\"1.5\" fill=\"none\"/>\n </svg>\n </button>\n </div>\n <!-- Status Icon -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <!-- Success -->\n <svg *ngIf=\"status.toLowerCase() === 'success'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <!-- Failed -->\n <svg *ngIf=\"status.toLowerCase() === 'failure' || status.toLowerCase() === 'failed'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4 4L8 8M8 4L4 8\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <!-- Pending -->\n <svg *ngIf=\"status.toLowerCase() === 'pending'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <!-- Running - Show spinner -->\n <svg *ngIf=\"status.toLowerCase() === 'running'\" class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n <!-- Skipped -->\n <span *ngIf=\"status.toLowerCase() === 'skipped'\" class=\"material-symbols-outlined cqa-text-[#9CA3AF] cqa-text-[12px]\">\n skip_next\n </span>\n </div>\n\n <!-- Step Number and Title -->\n <div class=\"cqa-font-semibold cqa-flex-1 cqa-text-[#334155] cqa-text-[14px] cqa-leading-[18px] cqa-font-inter cqa-flex cqa-items-center cqa-gap-1\" style=\"word-break: break-word;\">\n <span>{{ stepNumber }}. <span [innerHTML]=\"title\"></span></span>\n <span *ngIf=\"config.stepDeleted\" class=\"cqa-px-1.5 cqa-py-[2px] cqa-rounded-[4px] cqa-text-[10px] cqa-leading-[12px] cqa-font-medium cqa-text-[#B42318] cqa-bg-[#FEF3F2] cqa-border cqa-border-[#FEE4E2]\">\n Deleted\n </span>\n </div>\n\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-font-inter\">\n <div *ngIf=\"isDebug\" class=\"cqa-flex cqa-items-center cqa-gap-0.5 cqa-text-[#9CA3AF]\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Edit\" (click)=\"onEditStep($event)\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">edit</mat-icon>\n </button>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Add\" [matMenuTriggerFor]=\"addStepMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">add</mat-icon>\n </button>\n <mat-menu #addStepMenu=\"matMenu\" class=\"cqa-add-step-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of addStepMenuOptions\" (click)=\"onAddStepOptionSelect(opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"More options\" [matMenuTriggerFor]=\"stepMoreMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">more_vert</mat-icon>\n </button>\n <mat-menu #stepMoreMenu=\"matMenu\" class=\"cqa-step-more-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of stepMoreMenuOptions\" (click)=\"onStepMoreOptionSelect(opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n </div>\n <span class=\"cqa-text-[12px] cqa-leading-[15px] cqa-text-[#9CA3AF] cqa-font-medium\">\n {{ formatDuration(duration) }}\n </span>\n <svg *ngIf=\"hasSubSteps\" [class.cqa-rotate-180]=\"isExpanded\" class=\"cqa-transition-transform\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M3.5 5L7 8.5L10.5 5\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n </div>\n\n <!-- Expanded Content -->\n <div *ngIf=\"isExpanded && hasSubSteps\">\n <!-- Sub-steps -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-1 cqa-pt-1 cqa-pl-9\">\n <div\n *ngFor=\"let subStep of subSteps; trackBy: trackBySubStepId\"\n class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-py-[5.5px] cqa-px-3\">\n \n <!-- Sub-step Status Icon or Loader -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-3 cqa-h-3\">\n <!-- Loader when running -->\n <svg *ngIf=\"subStep.isRunning\" class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n \n <!-- Success Icon when complete -->\n <svg *ngIf=\"!subStep.isRunning && (subStep?.status?.toLowerCase() === 'passed' || subStep?.status?.toLowerCase() === 'success')\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#00A63E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M4.5 6L5.5 7L7.5 5\" stroke=\"#00A63E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <svg *ngIf=\"!subStep.isRunning && subStep?.status?.toLowerCase() === 'failed'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4 4L8 8M8 4L4 8\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n\n <!-- Sub-step Description (text from socket) with typing animation -->\n <span class=\"cqa-flex-1 cqa-text-[13px] cqa-leading-[15px] cqa-text-[#364153]\" style=\"word-break: break-word;\">\n <ngx-typed-js \n *ngIf=\"subStep.isRunning && subStep.text\"\n [strings]=\"[subStep.text]\"\n [typeSpeed]=\"30\"\n [showCursor]=\"false\"\n [fadeOut]=\"false\">\n <span class=\"typing\"></span>\n </ngx-typed-js>\n <span *ngIf=\"!subStep.isRunning\">{{ subStep.text }}</span>\n </span>\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-text-[#6A7282] cqa-font-medium\" style=\"white-space: pre-line;\">\n {{ formatDuration(subStep.duration || 0) }}\n </span>\n </div>\n </div>\n </div>\n</div>\n\n", components: [{ type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i2$1.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { type: i2$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { type: i3$4.NgxTypedJsComponent, selector: "ngx-typed-js", inputs: ["cursorColor", "strings", "stringsElement", "typeSpeed", "startDelay", "backSpeed", "smartBackspace", "shuffle", "backDelay", "fadeOut", "fadeOutClass", "fadeOutDelay", "loop", "loopCount", "showCursor", "cursorChar", "autoInsertCss", "attr", "bindInputFocusEvents", "contentType"], outputs: ["completed", "preStringTyped", "stringTyped", "lastStringBackspaced", "typingPaused", "typingResumed", "reset", "stopped", "started", "destroyed"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
|
|
13554
|
+
LiveExecutionStepComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: LiveExecutionStepComponent, selector: "cqa-live-execution-step", inputs: { id: "id", testStepResultId: "testStepResultId", stepNumber: "stepNumber", title: "title", status: "status", isDebug: "isDebug", debugPointSet: "debugPointSet", addStepMenuOptions: "addStepMenuOptions", stepMoreMenuOptions: "stepMoreMenuOptions", duration: "duration", expanded: "expanded", subSteps: "subSteps", stepDeleted: "stepDeleted" }, outputs: { debugPointChange: "debugPointChange", editStep: "editStep", addStepOptionSelect: "addStepOptionSelect", stepMoreOptionSelect: "stepMoreOptionSelect" }, host: { classAttribute: "cqa-ui-root" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"cqa-font-inter\">\n <!-- Header -->\n <div\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-p-2 cqa-cursor-pointer\"\n (click)=\"toggle()\"\n style=\"border-bottom: '1px solid #F3F4F6'\"\n >\n <div *ngIf=\"showDebugIcon\" class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer cqa-rounded-full hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" (click)=\"onDebugPointClick($event)\" [attr.aria-label]=\"debugPointSet ? 'Remove debug point' : 'Set debug point'\">\n <svg *ngIf=\"debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" fill=\"#C63535\"/>\n </svg>\n <svg *ngIf=\"!debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" stroke=\"#C63535\" stroke-width=\"1.5\" fill=\"none\"/>\n </svg>\n </button>\n </div>\n <!-- Status Icon -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <!-- Success -->\n <svg *ngIf=\"status.toLowerCase() === 'success'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <!-- Failed -->\n <svg *ngIf=\"status.toLowerCase() === 'failure' || status.toLowerCase() === 'failed'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4 4L8 8M8 4L4 8\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <!-- Pending -->\n <svg *ngIf=\"status.toLowerCase() === 'pending'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <!-- Running - Show spinner -->\n <svg *ngIf=\"status.toLowerCase() === 'running'\" class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n <!-- Skipped -->\n <span *ngIf=\"status.toLowerCase() === 'skipped'\" class=\"material-symbols-outlined cqa-text-[#9CA3AF] cqa-text-[12px]\">\n skip_next\n </span>\n </div>\n\n <!-- Step Number and Title -->\n <div class=\"cqa-font-semibold cqa-flex-1 cqa-text-[#334155] cqa-text-[14px] cqa-leading-[18px] cqa-font-inter cqa-flex cqa-items-center cqa-gap-1\" style=\"word-break: break-word;\">\n <span>{{ stepNumber }}. <span [innerHTML]=\"title\"></span></span>\n <span *ngIf=\"config.stepDeleted\" class=\"cqa-px-1.5 cqa-py-[2px] cqa-rounded-[4px] cqa-text-[10px] cqa-leading-[12px] cqa-font-medium cqa-text-[#B42318] cqa-bg-[#FEF3F2] cqa-border cqa-border-[#FEE4E2]\">\n Deleted\n </span>\n </div>\n\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-font-inter\">\n <div *ngIf=\"isDebug\" class=\"cqa-flex cqa-items-center cqa-gap-0.5 cqa-text-[#9CA3AF]\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Edit\" (click)=\"onEditStep($event)\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">edit</mat-icon>\n </button>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Add\" [matMenuTriggerFor]=\"addStepMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">add</mat-icon>\n </button>\n <mat-menu #addStepMenu=\"matMenu\" class=\"cqa-add-step-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of addStepMenuOptions\" (click)=\"onAddStepOptionSelect(opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"More options\" [matMenuTriggerFor]=\"stepMoreMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">more_vert</mat-icon>\n </button>\n <mat-menu #stepMoreMenu=\"matMenu\" class=\"cqa-step-more-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of stepMoreMenuOptions\" (click)=\"onStepMoreOptionSelect(opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n </div>\n <span class=\"cqa-text-[12px] cqa-leading-[15px] cqa-text-[#9CA3AF] cqa-font-medium\">\n {{ formatDuration(duration) }}\n </span>\n <svg *ngIf=\"hasSubSteps\" [class.cqa-rotate-180]=\"isExpanded\" class=\"cqa-transition-transform\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M3.5 5L7 8.5L10.5 5\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n </div>\n\n <!-- Expanded Content -->\n <div *ngIf=\"isExpanded && hasSubSteps\">\n <!-- Sub-steps -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-1 cqa-pt-1 cqa-pl-9\">\n <!-- Single loop: render all entries in chronological order -->\n <ng-container *ngFor=\"let subStep of processedSubSteps; trackBy: trackBySubStepId\">\n <!-- AI_AUTO_HEAL result entries: render with ai-agent-step style -->\n <cqa-ai-logs-with-reasoning\n *ngIf=\"subStep.isAiAutoHealResult\"\n [status]=\"subStep.status\"\n [text]=\"subStep.text\"\n [description]=\"subStep.description\"\n [reasoning]=\"subStep.reasoning\"\n [duration]=\"subStep.duration\">\n </cqa-ai-logs-with-reasoning>\n\n <!-- Regular sub-steps (non-AI_AUTO_HEAL) -->\n <div\n *ngIf=\"!subStep.isAiAutoHealResult\"\n class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-py-[5.5px] cqa-px-3\">\n \n <!-- Sub-step Status Icon or Loader -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-3 cqa-h-3\">\n <!-- Loader when running -->\n <svg *ngIf=\"subStep.isRunning\" class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n \n <!-- Success Icon when complete -->\n <svg *ngIf=\"!subStep.isRunning && (subStep?.status?.toLowerCase() === 'passed' || subStep?.status?.toLowerCase() === 'success')\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#00A63E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M4.5 6L5.5 7L7.5 5\" stroke=\"#00A63E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <svg *ngIf=\"!subStep.isRunning && subStep?.status?.toLowerCase() === 'failed'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4 4L8 8M8 4L4 8\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n\n <!-- Sub-step Description (text from socket) with typing animation -->\n <span class=\"cqa-flex-1 cqa-text-[13px] cqa-leading-[15px] cqa-text-[#364153]\" style=\"word-break: break-word;\">\n <span style=\"display: inline-flex; align-items: baseline; flex-wrap: wrap;\">\n <ngx-typed-js \n *ngIf=\"subStep.isRunning && subStep.text\"\n [strings]=\"[subStep.text]\"\n [typeSpeed]=\"30\"\n [showCursor]=\"false\"\n [fadeOut]=\"false\"\n style=\"display: inline;\">\n <span class=\"typing\"></span>\n </ngx-typed-js>\n <span *ngIf=\"!subStep.isRunning\" style=\"display: inline;\">{{ subStep.text }}</span>\n <!-- Countdown remaining for WAIT_FOR_LOCATOR group -->\n <span *ngIf=\"subStep.remainingSeconds != null\" class=\"cqa-text-[#F97316] cqa-font-medium cqa-ml-1\" style=\"display: inline;\">({{ subStep.remainingSeconds }}s remaining)</span>\n </span>\n </span>\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-text-[#6A7282] cqa-font-medium\" style=\"white-space: pre-line;\">\n {{ formatDuration(subStep.duration || 0) }}\n </span>\n </div>\n </ng-container>\n </div>\n </div>\n</div>\n\n", components: [{ type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i2$1.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { type: i2$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }, { type: AiLogsWithReasoningComponent, selector: "cqa-ai-logs-with-reasoning", inputs: ["status", "text", "description", "reasoning", "duration"] }, { type: i4$2.NgxTypedJsComponent, selector: "ngx-typed-js", inputs: ["cursorColor", "strings", "stringsElement", "typeSpeed", "startDelay", "backSpeed", "smartBackspace", "shuffle", "backDelay", "fadeOut", "fadeOutClass", "fadeOutDelay", "loop", "loopCount", "showCursor", "cursorChar", "autoInsertCss", "attr", "bindInputFocusEvents", "contentType"], outputs: ["completed", "preStringTyped", "stringTyped", "lastStringBackspaced", "typingPaused", "typingResumed", "reset", "stopped", "started", "destroyed"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
|
|
12686
13555
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: LiveExecutionStepComponent, decorators: [{
|
|
12687
13556
|
type: Component,
|
|
12688
|
-
args: [{ selector: 'cqa-live-execution-step', host: { class: 'cqa-ui-root' }, template: "<div class=\"cqa-font-inter\">\n <!-- Header -->\n <div\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-p-2 cqa-cursor-pointer\"\n (click)=\"toggle()\"\n style=\"border-bottom: '1px solid #F3F4F6'\"\n >\n <div *ngIf=\"showDebugIcon\" class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer cqa-rounded-full hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" (click)=\"onDebugPointClick($event)\" [attr.aria-label]=\"debugPointSet ? 'Remove debug point' : 'Set debug point'\">\n <svg *ngIf=\"debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" fill=\"#C63535\"/>\n </svg>\n <svg *ngIf=\"!debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" stroke=\"#C63535\" stroke-width=\"1.5\" fill=\"none\"/>\n </svg>\n </button>\n </div>\n <!-- Status Icon -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <!-- Success -->\n <svg *ngIf=\"status.toLowerCase() === 'success'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <!-- Failed -->\n <svg *ngIf=\"status.toLowerCase() === 'failure' || status.toLowerCase() === 'failed'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4 4L8 8M8 4L4 8\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <!-- Pending -->\n <svg *ngIf=\"status.toLowerCase() === 'pending'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <!-- Running - Show spinner -->\n <svg *ngIf=\"status.toLowerCase() === 'running'\" class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n <!-- Skipped -->\n <span *ngIf=\"status.toLowerCase() === 'skipped'\" class=\"material-symbols-outlined cqa-text-[#9CA3AF] cqa-text-[12px]\">\n skip_next\n </span>\n </div>\n\n <!-- Step Number and Title -->\n <div class=\"cqa-font-semibold cqa-flex-1 cqa-text-[#334155] cqa-text-[14px] cqa-leading-[18px] cqa-font-inter cqa-flex cqa-items-center cqa-gap-1\" style=\"word-break: break-word;\">\n <span>{{ stepNumber }}. <span [innerHTML]=\"title\"></span></span>\n <span *ngIf=\"config.stepDeleted\" class=\"cqa-px-1.5 cqa-py-[2px] cqa-rounded-[4px] cqa-text-[10px] cqa-leading-[12px] cqa-font-medium cqa-text-[#B42318] cqa-bg-[#FEF3F2] cqa-border cqa-border-[#FEE4E2]\">\n Deleted\n </span>\n </div>\n\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-font-inter\">\n <div *ngIf=\"isDebug\" class=\"cqa-flex cqa-items-center cqa-gap-0.5 cqa-text-[#9CA3AF]\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Edit\" (click)=\"onEditStep($event)\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">edit</mat-icon>\n </button>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Add\" [matMenuTriggerFor]=\"addStepMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">add</mat-icon>\n </button>\n <mat-menu #addStepMenu=\"matMenu\" class=\"cqa-add-step-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of addStepMenuOptions\" (click)=\"onAddStepOptionSelect(opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"More options\" [matMenuTriggerFor]=\"stepMoreMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">more_vert</mat-icon>\n </button>\n <mat-menu #stepMoreMenu=\"matMenu\" class=\"cqa-step-more-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of stepMoreMenuOptions\" (click)=\"onStepMoreOptionSelect(opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n </div>\n <span class=\"cqa-text-[12px] cqa-leading-[15px] cqa-text-[#9CA3AF] cqa-font-medium\">\n {{ formatDuration(duration) }}\n </span>\n <svg *ngIf=\"hasSubSteps\" [class.cqa-rotate-180]=\"isExpanded\" class=\"cqa-transition-transform\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M3.5 5L7 8.5L10.5 5\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n </div>\n\n <!-- Expanded Content -->\n <div *ngIf=\"isExpanded && hasSubSteps\">\n <!-- Sub-steps -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-1 cqa-pt-1 cqa-pl-9\">\n <div\n *ngFor=\"let subStep of subSteps; trackBy: trackBySubStepId\"\n class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-py-[5.5px] cqa-px-3\">\n \n <!-- Sub-step Status Icon or Loader -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-3 cqa-h-3\">\n <!-- Loader when running -->\n <svg *ngIf=\"subStep.isRunning\" class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n \n <!-- Success Icon when complete -->\n <svg *ngIf=\"!subStep.isRunning && (subStep?.status?.toLowerCase() === 'passed' || subStep?.status?.toLowerCase() === 'success')\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#00A63E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M4.5 6L5.5 7L7.5 5\" stroke=\"#00A63E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <svg *ngIf=\"!subStep.isRunning && subStep?.status?.toLowerCase() === 'failed'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4 4L8 8M8 4L4 8\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n\n <!-- Sub-step Description (text from socket) with typing animation -->\n <span class=\"cqa-flex-1 cqa-text-[13px] cqa-leading-[15px] cqa-text-[#364153]\" style=\"word-break: break-word;\">\n <ngx-typed-js \n *ngIf=\"subStep.isRunning && subStep.text\"\n [strings]=\"[subStep.text]\"\n [typeSpeed]=\"30\"\n [showCursor]=\"false\"\n [fadeOut]=\"false\">\n <span class=\"typing\"></span>\n </ngx-typed-js>\n <span *ngIf=\"!subStep.isRunning\">{{ subStep.text }}</span>\n </span>\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-text-[#6A7282] cqa-font-medium\" style=\"white-space: pre-line;\">\n {{ formatDuration(subStep.duration || 0) }}\n </span>\n </div>\n </div>\n </div>\n</div>\n\n", styles: [] }]
|
|
13557
|
+
args: [{ selector: 'cqa-live-execution-step', host: { class: 'cqa-ui-root' }, template: "<div class=\"cqa-font-inter\">\n <!-- Header -->\n <div\n class=\"cqa-flex cqa-items-center cqa-gap-2 cqa-p-2 cqa-cursor-pointer\"\n (click)=\"toggle()\"\n style=\"border-bottom: '1px solid #F3F4F6'\"\n >\n <div *ngIf=\"showDebugIcon\" class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer cqa-rounded-full hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" (click)=\"onDebugPointClick($event)\" [attr.aria-label]=\"debugPointSet ? 'Remove debug point' : 'Set debug point'\">\n <svg *ngIf=\"debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" fill=\"#C63535\"/>\n </svg>\n <svg *ngIf=\"!debugPointSet\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"7\" cy=\"7\" r=\"6\" stroke=\"#C63535\" stroke-width=\"1.5\" fill=\"none\"/>\n </svg>\n </button>\n </div>\n <!-- Status Icon -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-center\">\n <!-- Success -->\n <svg *ngIf=\"status.toLowerCase() === 'success'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.9005 4.99999C11.1289 6.12064 10.9662 7.28571 10.4395 8.30089C9.91279 9.31608 9.054 10.12 8.00631 10.5787C6.95862 11.0373 5.78536 11.1229 4.6822 10.8212C3.57904 10.5195 2.61265 9.84869 1.94419 8.92071C1.27573 7.99272 0.945611 6.86361 1.00888 5.72169C1.07215 4.57976 1.52499 3.49404 2.29188 2.64558C3.05876 1.79712 4.09334 1.23721 5.22308 1.05922C6.35282 0.881233 7.50944 1.09592 8.50005 1.66749\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4.5 5.5L6 7L11 2\" stroke=\"#22C55E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <!-- Failed -->\n <svg *ngIf=\"status.toLowerCase() === 'failure' || status.toLowerCase() === 'failed'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4 4L8 8M8 4L4 8\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <!-- Pending -->\n <svg *ngIf=\"status.toLowerCase() === 'pending'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 3V6L8 7\" stroke=\"#9CA3AF\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n <!-- Running - Show spinner -->\n <svg *ngIf=\"status.toLowerCase() === 'running'\" class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n <!-- Skipped -->\n <span *ngIf=\"status.toLowerCase() === 'skipped'\" class=\"material-symbols-outlined cqa-text-[#9CA3AF] cqa-text-[12px]\">\n skip_next\n </span>\n </div>\n\n <!-- Step Number and Title -->\n <div class=\"cqa-font-semibold cqa-flex-1 cqa-text-[#334155] cqa-text-[14px] cqa-leading-[18px] cqa-font-inter cqa-flex cqa-items-center cqa-gap-1\" style=\"word-break: break-word;\">\n <span>{{ stepNumber }}. <span [innerHTML]=\"title\"></span></span>\n <span *ngIf=\"config.stepDeleted\" class=\"cqa-px-1.5 cqa-py-[2px] cqa-rounded-[4px] cqa-text-[10px] cqa-leading-[12px] cqa-font-medium cqa-text-[#B42318] cqa-bg-[#FEF3F2] cqa-border cqa-border-[#FEE4E2]\">\n Deleted\n </span>\n </div>\n\n <div class=\"cqa-flex cqa-items-center cqa-gap-1 cqa-font-inter\">\n <div *ngIf=\"isDebug\" class=\"cqa-flex cqa-items-center cqa-gap-0.5 cqa-text-[#9CA3AF]\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Edit\" (click)=\"onEditStep($event)\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">edit</mat-icon>\n </button>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Add\" [matMenuTriggerFor]=\"addStepMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">add</mat-icon>\n </button>\n <mat-menu #addStepMenu=\"matMenu\" class=\"cqa-add-step-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of addStepMenuOptions\" (click)=\"onAddStepOptionSelect(opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"More options\" [matMenuTriggerFor]=\"stepMoreMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">more_vert</mat-icon>\n </button>\n <mat-menu #stepMoreMenu=\"matMenu\" class=\"cqa-step-more-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of stepMoreMenuOptions\" (click)=\"onStepMoreOptionSelect(opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n </div>\n <span class=\"cqa-text-[12px] cqa-leading-[15px] cqa-text-[#9CA3AF] cqa-font-medium\">\n {{ formatDuration(duration) }}\n </span>\n <svg *ngIf=\"hasSubSteps\" [class.cqa-rotate-180]=\"isExpanded\" class=\"cqa-transition-transform\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M3.5 5L7 8.5L10.5 5\" stroke=\"#9CA3AF\" stroke-width=\"0.833333\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>\n </div>\n </div>\n\n <!-- Expanded Content -->\n <div *ngIf=\"isExpanded && hasSubSteps\">\n <!-- Sub-steps -->\n <div class=\"cqa-flex cqa-flex-col cqa-gap-1 cqa-pt-1 cqa-pl-9\">\n <!-- Single loop: render all entries in chronological order -->\n <ng-container *ngFor=\"let subStep of processedSubSteps; trackBy: trackBySubStepId\">\n <!-- AI_AUTO_HEAL result entries: render with ai-agent-step style -->\n <cqa-ai-logs-with-reasoning\n *ngIf=\"subStep.isAiAutoHealResult\"\n [status]=\"subStep.status\"\n [text]=\"subStep.text\"\n [description]=\"subStep.description\"\n [reasoning]=\"subStep.reasoning\"\n [duration]=\"subStep.duration\">\n </cqa-ai-logs-with-reasoning>\n\n <!-- Regular sub-steps (non-AI_AUTO_HEAL) -->\n <div\n *ngIf=\"!subStep.isAiAutoHealResult\"\n class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-py-[5.5px] cqa-px-3\">\n \n <!-- Sub-step Status Icon or Loader -->\n <div class=\"cqa-flex cqa-items-center cqa-justify-center cqa-w-3 cqa-h-3\">\n <!-- Loader when running -->\n <svg *ngIf=\"subStep.isRunning\" class=\"cqa-animate-spin cqa-text-[#3B82F6]\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"6\" r=\"5\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" opacity=\"0.25\"/>\n <path d=\"M6 1A5 5 0 0 1 11 6\" stroke=\"currentColor\" stroke-width=\"1.5\" fill=\"none\" stroke-linecap=\"round\"/>\n </svg>\n \n <!-- Success Icon when complete -->\n <svg *ngIf=\"!subStep.isRunning && (subStep?.status?.toLowerCase() === 'passed' || subStep?.status?.toLowerCase() === 'success')\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#00A63E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M4.5 6L5.5 7L7.5 5\" stroke=\"#00A63E\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n <svg *ngIf=\"!subStep.isRunning && subStep?.status?.toLowerCase() === 'failed'\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M4 4L8 8M8 4L4 8\" stroke=\"#EF4444\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n\n <!-- Sub-step Description (text from socket) with typing animation -->\n <span class=\"cqa-flex-1 cqa-text-[13px] cqa-leading-[15px] cqa-text-[#364153]\" style=\"word-break: break-word;\">\n <span style=\"display: inline-flex; align-items: baseline; flex-wrap: wrap;\">\n <ngx-typed-js \n *ngIf=\"subStep.isRunning && subStep.text\"\n [strings]=\"[subStep.text]\"\n [typeSpeed]=\"30\"\n [showCursor]=\"false\"\n [fadeOut]=\"false\"\n style=\"display: inline;\">\n <span class=\"typing\"></span>\n </ngx-typed-js>\n <span *ngIf=\"!subStep.isRunning\" style=\"display: inline;\">{{ subStep.text }}</span>\n <!-- Countdown remaining for WAIT_FOR_LOCATOR group -->\n <span *ngIf=\"subStep.remainingSeconds != null\" class=\"cqa-text-[#F97316] cqa-font-medium cqa-ml-1\" style=\"display: inline;\">({{ subStep.remainingSeconds }}s remaining)</span>\n </span>\n </span>\n <span class=\"cqa-text-[10px] cqa-leading-[15px] cqa-text-[#6A7282] cqa-font-medium\" style=\"white-space: pre-line;\">\n {{ formatDuration(subStep.duration || 0) }}\n </span>\n </div>\n </ng-container>\n </div>\n </div>\n</div>\n\n", styles: [] }]
|
|
12689
13558
|
}], propDecorators: { id: [{
|
|
12690
13559
|
type: Input
|
|
12691
13560
|
}], testStepResultId: [{
|
|
@@ -12933,6 +13802,7 @@ class MainStepCollapseComponent {
|
|
|
12933
13802
|
constructor() {
|
|
12934
13803
|
this.title = 'Prerequisites';
|
|
12935
13804
|
this.expanded = true;
|
|
13805
|
+
this.countLoading = false;
|
|
12936
13806
|
/** When true, "View steps" redirects to URL instead of expanding inline. URL comes from item.viewStepsUrl or getViewStepsUrl(item). */
|
|
12937
13807
|
this.viewStepsAsRedirect = false;
|
|
12938
13808
|
/** When redirecting, open link in new tab. Default true */
|
|
@@ -13069,10 +13939,10 @@ class MainStepCollapseComponent {
|
|
|
13069
13939
|
}
|
|
13070
13940
|
}
|
|
13071
13941
|
MainStepCollapseComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: MainStepCollapseComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
13072
|
-
MainStepCollapseComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: MainStepCollapseComponent, selector: "cqa-main-step-collapse", inputs: { title: "title", items: "items", expanded: "expanded", icon: "icon", count: "count", itemContentTemplate: "itemContentTemplate", headerButtons: "headerButtons", viewStepsAsRedirect: "viewStepsAsRedirect", getViewStepsUrl: "getViewStepsUrl", viewStepsOpenInNewTab: "viewStepsOpenInNewTab", initialExpandedItemId: "initialExpandedItemId", isDebug: "isDebug", addStepMenuOptions: "addStepMenuOptions", stepMoreMenuOptions: "stepMoreMenuOptions" }, outputs: { viewSteps: "viewSteps", editStep: "editStep", addStepOptionSelect: "addStepOptionSelect", stepMoreOptionSelect: "stepMoreOptionSelect", headerButtonClick: "headerButtonClick", expandedChange: "expandedChange" }, host: { classAttribute: "cqa-ui-root" }, queries: [{ propertyName: "itemContentTpl", first: true, predicate: ["itemContent"], descendants: true, read: TemplateRef }], usesOnChanges: true, ngImport: i0, template: "<!-- Header -->\n<div\n class=\"cqa-mt-2 cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-px-3 cqa-py-2 cqa-cursor-pointer cqa-bg-[#EEF2FF] cqa-rounded-[4px] cqa-border cqa-border-[#C6D2FF] cqa-border-solid\"\n (click)=\"toggle()\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-w-full\">\n <!-- Chevron Icon (Left) -->\n <!-- <svg [class.cqa-rotate-180]=\"isExpanded\" class=\"cqa-transition-transform\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 6L8 10L12 6\" stroke=\"#3F51B5\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg> -->\n <div><svg [class.cqa-rotate-180]=\"isExpanded\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 6L8 10L12 6\" stroke=\"#4F39F6\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg></div>\n\n <!-- Chain-Link Icon (if configured, otherwise default) -->\n <!-- <div *ngIf=\"icon && icon.type === 'folder'\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M11.6666 11.6667C11.976 11.6667 12.2728 11.5437 12.4916 11.325C12.7104 11.1062 12.8333 10.8094 12.8333 10.5V4.66667C12.8333 4.35725 12.7104 4.0605 12.4916 3.84171C12.2728 3.62292 11.976 3.5 11.6666 3.5H7.05829C6.86318 3.50191 6.67069 3.45486 6.49847 3.36314C6.32624 3.27142 6.17977 3.13797 6.07246 2.975L5.59996 2.275C5.49373 2.11369 5.34911 1.98128 5.17908 1.88965C5.00906 1.79802 4.81894 1.75003 4.62579 1.75H2.33329C2.02387 1.75 1.72713 1.87292 1.50833 2.09171C1.28954 2.3105 1.16663 2.60725 1.16663 2.91667V10.5C1.16663 10.8094 1.28954 11.1062 1.50833 11.325C1.72713 11.5437 2.02387 11.6667 2.33329 11.6667H11.6666Z\" fill=\"#EFF6FF\" stroke=\"#3F51B5\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n <div *ngIf=\"icon && icon.type === 'loop'\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect width=\"16\" height=\"16\" rx=\"4\" fill=\"#EBECFD\"/>\n <path d=\"M9.66663 4.66666L11 5.99999L9.66663 7.33332\" stroke=\"#3F51B5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M5 7.66667V7.33333C5 6.97971 5.14048 6.64057 5.39052 6.39052C5.64057 6.14048 5.97971 6 6.33333 6H11\" stroke=\"#3F51B5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M6.33333 11.3333L5 9.99999L6.33333 8.66666\" stroke=\"#3F51B5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M11 8.33334V8.66668C11 9.0203 10.8595 9.35944 10.6095 9.60949C10.3594 9.85953 10.0203 10 9.66667 10H5\" stroke=\"#3F51B5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div> -->\n <!-- Bar Icon (Bulleted List) -->\n <div *ngIf=\"icon && icon.type === 'bar'\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <!-- First bullet and line -->\n <circle cx=\"3\" cy=\"5\" r=\"2\" fill=\"#4F39F6\"/>\n <line x1=\"7\" y1=\"5\" x2=\"17\" y2=\"5\" stroke=\"#4F39F6\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n <!-- Second bullet and line -->\n <circle cx=\"3\" cy=\"10\" r=\"2\" fill=\"#4F39F6\"/>\n <line x1=\"7\" y1=\"10\" x2=\"17\" y2=\"10\" stroke=\"#4F39F6\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n <!-- Third bullet and line -->\n <circle cx=\"3\" cy=\"15\" r=\"2\" fill=\"#4F39F6\"/>\n <line x1=\"7\" y1=\"15\" x2=\"17\" y2=\"15\" stroke=\"#4F39F6\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n </svg>\n </div>\n\n <!-- Default Chain-Link Icon (when no icon or icon type is not specified) -->\n <div *ngIf=\"!icon || (icon.type !== 'bar' && icon.type !== 'folder' && icon.type !== 'loop' && icon.type !== 'custom')\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M7.50033 14.1663H5.83366C4.72859 14.1663 3.66878 13.7274 2.88738 12.946C2.10598 12.1646 1.66699 11.1047 1.66699 9.99967C1.66699 8.89461 2.10598 7.8348 2.88738 7.0534C3.66878 6.27199 4.72859 5.83301 5.83366 5.83301H7.50033\"\n stroke=\"#4F39F6\" stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M12.5 5.83301H14.1667C15.2717 5.83301 16.3315 6.27199 17.1129 7.0534C17.8943 7.8348 18.3333 8.89461 18.3333 9.99967C18.3333 11.1047 17.8943 12.1646 17.1129 12.946C16.3315 13.7274 15.2717 14.1663 14.1667 14.1663H12.5\"\n stroke=\"#4F39F6\" stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6.66699 10H13.3337\" stroke=\"#4F39F6\" stroke-width=\"1.66667\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n\n <!-- Custom Icon -->\n <div *ngIf=\"icon && icon.type === 'custom' && icon.svg\" [innerHTML]=\"icon.svg\"></div>\n\n <!-- Title -->\n <span class=\"cqa-font-semibold cqa-text-[14px] cqa-leading-[17px] cqa-text-[#312C85] cqa-flex-1\">\n {{ title }}\n </span>\n\n <!-- Badge and dynamic header buttons -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" (click)=\"$event.stopPropagation()\">\n <ng-container *ngFor=\"let btn of headerButtons; let i = index\">\n <cqa-button\n [text]=\"btn.text\"\n [icon]=\"btn.icon\"\n [variant]=\"btn.variant || 'outlined'\"\n [disabled]=\"btn.disabled\"\n [tooltip]=\"btn.tooltip\"\n [customClass]=\"btn.customClass\"\n [btnSize]=\"btn.btnSize || 'sm'\"\n (clicked)=\"onHeaderButtonClick(btn, i, $event)\">\n </cqa-button>\n </ng-container>\n <span\n class=\"cqa-px-2 cqa-py-[2px] cqa-rounded-[4px] cqa-bg-[#C6D2FF] cqa-text-[12px] cqa-leading-[16px] cqa-text-[#432DD7]\">\n {{ getDisplayCount() }}\n </span>\n </div>\n </div>\n</div>\n\n<!-- Expanded Content -->\n<div *ngIf=\"isExpanded\" class=\"cqa-mt-2 cqa-flex cqa-flex-col cqa-gap-2 cqa-px-2.5\">\n <!-- When there are no items, display ng-content directly -->\n <ng-container *ngIf=\"!items || items.length === 0\">\n <ng-content></ng-content>\n </ng-container>\n\n <!-- When items exist, display them -->\n <div *ngFor=\"let item of items\">\n\n <!-- Item Header -->\n <div class=\"cqa-bg-white cqa-border cqa-border-solid cqa-border-[#E5E5E5] cqa-rounded-md cqa-overflow-hidden\">\n <div class=\"cqa-py-2 cqa-px-3 cqa-flex cqa-items-center cqa-justify-between cqa-gap-3\">\n <!-- Left side: Status and Title -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-flex-1\">\n <!-- Status Icon (Filled Green Circle with Checkmark) -->\n <div>\n <!-- Success -->\n <svg *ngIf=\"item.status === 'success'\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <g clip-path=\"url(#clip0_48_121)\">\n <path\n d=\"M10.0003 18.3337C14.6027 18.3337 18.3337 14.6027 18.3337 10.0003C18.3337 5.39795 14.6027 1.66699 10.0003 1.66699C5.39795 1.66699 1.66699 5.39795 1.66699 10.0003C1.66699 14.6027 5.39795 18.3337 10.0003 18.3337Z\"\n stroke=\"#00A63E\" stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M7.5 9.99967L9.16667 11.6663L12.5 8.33301\" stroke=\"#00A63E\" stroke-width=\"1.66667\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </g>\n <defs>\n <clipPath id=\"clip0_48_121\">\n <rect width=\"20\" height=\"20\" fill=\"white\" />\n </clipPath>\n </defs>\n </svg>\n <!-- Failed -->\n <svg *ngIf=\"item.status === 'failed'\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"10\" cy=\"10\" r=\"8\" fill=\"#EF4444\" />\n <path d=\"M7 7L13 13M13 7L7 13\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n <!-- Pending -->\n <svg *ngIf=\"item.status === 'pending'\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"10\" cy=\"10\" r=\"8\" fill=\"#9CA3AF\" />\n <path d=\"M10 6V10L13 12\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n <!-- Running -->\n <svg *ngIf=\"item.status === 'running'\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"10\" cy=\"10\" r=\"8\" fill=\"#3B82F6\" />\n <path d=\"M10 6V10L13 12\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n \n <!-- Title -->\n <span class=\"cqa-text-[14px] cqa-leading-[18px]\" style=\"word-break: break-word;\">\n {{ item.title }}\n </span>\n </div>\n \n <!-- Right side: Duration and View Steps Link -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-3\">\n <!-- Step action icons (only when isDebug) -->\n <div *ngIf=\"isDebug\" class=\"cqa-flex cqa-items-center cqa-gap-0.5 cqa-text-[#9CA3AF]\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Edit\" (click)=\"onEditStep(item, $event)\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">edit</mat-icon>\n </button>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Add\" [matMenuTriggerFor]=\"addStepMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">add</mat-icon>\n </button>\n <mat-menu #addStepMenu=\"matMenu\" class=\"cqa-add-step-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of addStepMenuOptions\" (click)=\"onAddStepOptionSelect(item, opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"More options\" [matMenuTriggerFor]=\"stepMoreMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">more_vert</mat-icon>\n </button>\n <mat-menu #stepMoreMenu=\"matMenu\" class=\"cqa-step-more-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of stepMoreMenuOptions\" (click)=\"onStepMoreOptionSelect(item, opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n </div>\n <!-- Duration with Clock Icon -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-1\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\"\n stroke=\"#6A7282\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6 3V6L8 7\" stroke=\"#6A7282\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n <span class=\"cqa-text-[14px] cqa-leading-[20px] cqa-text-[#6A7282]\">\n {{ formatDuration(item.duration) }}\n </span>\n </div>\n \n <!-- View Steps Link: redirect mode (navigates to URL) or inline mode (toggle expand) -->\n <a *ngIf=\"hasViewStepsRedirectUrl(item)\"\n [href]=\"getItemViewStepsUrl(item)\"\n [attr.target]=\"viewStepsOpenInNewTab ? '_blank' : null\"\n [attr.rel]=\"viewStepsOpenInNewTab ? 'noopener noreferrer' : null\"\n class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-semibold cqa-text-[#3F43EE] cqa-no-underline cqa-flex cqa-items-center cqa-gap-1 hover:cqa-underline\">\n <span>View steps</span>\n <svg class=\"cqa-transition-transform\" width=\"16\" height=\"15\"\n viewBox=\"0 0 16 15\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M8.6552 12.8184L7.55413 11.7668L10.852 8.5864H2.83984V7.05032H10.852L7.55413 3.87506L8.6552 2.81836L13.8398 7.81836L8.6552 12.8184Z\"\n fill=\"#3F43EE\" />\n </svg>\n </a>\n <a *ngIf=\"!hasViewStepsRedirectUrl(item)\" href=\"#\" (click)=\"onViewSteps(item, $event)\"\n class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-semibold cqa-text-[#3F43EE] cqa-no-underline cqa-flex cqa-items-center cqa-gap-1 hover:cqa-underline\">\n <span>{{ isItemExpanded(item.id) ? 'Hide steps' : 'View steps' }}</span>\n <svg [class.cqa-rotate-90]=\"isItemExpanded(item.id)\" class=\"cqa-transition-transform\" width=\"16\" height=\"15\"\n viewBox=\"0 0 16 15\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M8.6552 12.8184L7.55413 11.7668L10.852 8.5864H2.83984V7.05032H10.852L7.55413 3.87506L8.6552 2.81836L13.8398 7.81836L8.6552 12.8184Z\"\n fill=\"#3F43EE\" />\n </svg>\n </a>\n </div>\n </div>\n </div>\n\n <!-- Steps Content (shown when item is expanded) -->\n <div *ngIf=\"isItemExpanded(item.id)\">\n <!-- Custom template via TemplateRef (from @ContentChild or @Input) - passes item as context -->\n <ng-container *ngIf=\"itemContentTpl || itemContentTemplate\">\n <div class=\"cqa-p-3\">\n <ng-container\n *ngTemplateOutlet=\"(itemContentTpl || itemContentTemplate)!; context: { $implicit: item, item: item }\"></ng-container>\n </div>\n </ng-container>\n\n <!-- Custom content projection via ng-content - displayed for all expanded items -->\n <ng-content select=\"[itemContent]\"></ng-content>\n </div>\n </div>\n</div>\n\n<!-- Custom content projection after all items - for steps loaded after API call -->\n<ng-content select=\"[afterItems]\"></ng-content>", components: [{ type: ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }, { type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i2$1.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { type: i2$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }] });
|
|
13942
|
+
MainStepCollapseComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: MainStepCollapseComponent, selector: "cqa-main-step-collapse", inputs: { title: "title", items: "items", expanded: "expanded", icon: "icon", count: "count", countLoading: "countLoading", itemContentTemplate: "itemContentTemplate", headerButtons: "headerButtons", viewStepsAsRedirect: "viewStepsAsRedirect", getViewStepsUrl: "getViewStepsUrl", viewStepsOpenInNewTab: "viewStepsOpenInNewTab", initialExpandedItemId: "initialExpandedItemId", isDebug: "isDebug", addStepMenuOptions: "addStepMenuOptions", stepMoreMenuOptions: "stepMoreMenuOptions" }, outputs: { viewSteps: "viewSteps", editStep: "editStep", addStepOptionSelect: "addStepOptionSelect", stepMoreOptionSelect: "stepMoreOptionSelect", headerButtonClick: "headerButtonClick", expandedChange: "expandedChange" }, host: { classAttribute: "cqa-ui-root" }, queries: [{ propertyName: "itemContentTpl", first: true, predicate: ["itemContent"], descendants: true, read: TemplateRef }], usesOnChanges: true, ngImport: i0, template: "<!-- Header -->\n<div\n class=\"cqa-mt-2 cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-px-3 cqa-py-2 cqa-cursor-pointer cqa-bg-[#EEF2FF] cqa-rounded-[4px] cqa-border cqa-border-[#C6D2FF] cqa-border-solid\"\n (click)=\"toggle()\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-w-full\">\n <!-- Chevron Icon (Left) -->\n <!-- <svg [class.cqa-rotate-180]=\"isExpanded\" class=\"cqa-transition-transform\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 6L8 10L12 6\" stroke=\"#3F51B5\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg> -->\n <div><svg [class.cqa-rotate-180]=\"isExpanded\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 6L8 10L12 6\" stroke=\"#4F39F6\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg></div>\n\n <!-- Chain-Link Icon (if configured, otherwise default) -->\n <!-- <div *ngIf=\"icon && icon.type === 'folder'\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M11.6666 11.6667C11.976 11.6667 12.2728 11.5437 12.4916 11.325C12.7104 11.1062 12.8333 10.8094 12.8333 10.5V4.66667C12.8333 4.35725 12.7104 4.0605 12.4916 3.84171C12.2728 3.62292 11.976 3.5 11.6666 3.5H7.05829C6.86318 3.50191 6.67069 3.45486 6.49847 3.36314C6.32624 3.27142 6.17977 3.13797 6.07246 2.975L5.59996 2.275C5.49373 2.11369 5.34911 1.98128 5.17908 1.88965C5.00906 1.79802 4.81894 1.75003 4.62579 1.75H2.33329C2.02387 1.75 1.72713 1.87292 1.50833 2.09171C1.28954 2.3105 1.16663 2.60725 1.16663 2.91667V10.5C1.16663 10.8094 1.28954 11.1062 1.50833 11.325C1.72713 11.5437 2.02387 11.6667 2.33329 11.6667H11.6666Z\" fill=\"#EFF6FF\" stroke=\"#3F51B5\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n <div *ngIf=\"icon && icon.type === 'loop'\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect width=\"16\" height=\"16\" rx=\"4\" fill=\"#EBECFD\"/>\n <path d=\"M9.66663 4.66666L11 5.99999L9.66663 7.33332\" stroke=\"#3F51B5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M5 7.66667V7.33333C5 6.97971 5.14048 6.64057 5.39052 6.39052C5.64057 6.14048 5.97971 6 6.33333 6H11\" stroke=\"#3F51B5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M6.33333 11.3333L5 9.99999L6.33333 8.66666\" stroke=\"#3F51B5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M11 8.33334V8.66668C11 9.0203 10.8595 9.35944 10.6095 9.60949C10.3594 9.85953 10.0203 10 9.66667 10H5\" stroke=\"#3F51B5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div> -->\n <!-- Bar Icon (Bulleted List) -->\n <div *ngIf=\"icon && icon.type === 'bar'\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <!-- First bullet and line -->\n <circle cx=\"3\" cy=\"5\" r=\"2\" fill=\"#4F39F6\"/>\n <line x1=\"7\" y1=\"5\" x2=\"17\" y2=\"5\" stroke=\"#4F39F6\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n <!-- Second bullet and line -->\n <circle cx=\"3\" cy=\"10\" r=\"2\" fill=\"#4F39F6\"/>\n <line x1=\"7\" y1=\"10\" x2=\"17\" y2=\"10\" stroke=\"#4F39F6\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n <!-- Third bullet and line -->\n <circle cx=\"3\" cy=\"15\" r=\"2\" fill=\"#4F39F6\"/>\n <line x1=\"7\" y1=\"15\" x2=\"17\" y2=\"15\" stroke=\"#4F39F6\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n </svg>\n </div>\n\n <!-- Default Chain-Link Icon (when no icon or icon type is not specified) -->\n <div *ngIf=\"!icon || (icon.type !== 'bar' && icon.type !== 'folder' && icon.type !== 'loop' && icon.type !== 'custom')\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M7.50033 14.1663H5.83366C4.72859 14.1663 3.66878 13.7274 2.88738 12.946C2.10598 12.1646 1.66699 11.1047 1.66699 9.99967C1.66699 8.89461 2.10598 7.8348 2.88738 7.0534C3.66878 6.27199 4.72859 5.83301 5.83366 5.83301H7.50033\"\n stroke=\"#4F39F6\" stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M12.5 5.83301H14.1667C15.2717 5.83301 16.3315 6.27199 17.1129 7.0534C17.8943 7.8348 18.3333 8.89461 18.3333 9.99967C18.3333 11.1047 17.8943 12.1646 17.1129 12.946C16.3315 13.7274 15.2717 14.1663 14.1667 14.1663H12.5\"\n stroke=\"#4F39F6\" stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6.66699 10H13.3337\" stroke=\"#4F39F6\" stroke-width=\"1.66667\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n\n <!-- Custom Icon -->\n <div *ngIf=\"icon && icon.type === 'custom' && icon.svg\" [innerHTML]=\"icon.svg\"></div>\n\n <!-- Title -->\n <span class=\"cqa-font-semibold cqa-text-[14px] cqa-leading-[17px] cqa-text-[#312C85] cqa-flex-1\">\n {{ title }}\n </span>\n\n <!-- Badge and dynamic header buttons -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" (click)=\"$event.stopPropagation()\">\n <ng-container *ngFor=\"let btn of headerButtons; let i = index\">\n <cqa-button\n [text]=\"btn.text\"\n [icon]=\"btn.icon\"\n [variant]=\"btn.variant || 'outlined'\"\n [disabled]=\"btn.disabled\"\n [tooltip]=\"btn.tooltip\"\n [customClass]=\"btn.customClass\"\n [btnSize]=\"btn.btnSize || 'sm'\"\n (clicked)=\"onHeaderButtonClick(btn, i, $event)\">\n </cqa-button>\n </ng-container>\n <span\n class=\"cqa-px-2 cqa-py-[2px] cqa-rounded-[4px] cqa-bg-[#C6D2FF] cqa-text-[12px] cqa-leading-[16px] cqa-text-[#432DD7] cqa-inline-flex cqa-items-center cqa-justify-center cqa-min-w-[24px]\">\n <mat-spinner *ngIf=\"countLoading\" diameter=\"16\" class=\"cqa-inline-block\"></mat-spinner>\n <span *ngIf=\"!countLoading\">{{ getDisplayCount() }}</span>\n </span>\n </div>\n </div>\n</div>\n\n<!-- Expanded Content -->\n<div *ngIf=\"isExpanded\" class=\"cqa-mt-2 cqa-flex cqa-flex-col cqa-gap-2 cqa-px-2.5\">\n <!-- When there are no items, display ng-content directly -->\n <ng-container *ngIf=\"!items || items.length === 0\">\n <ng-content></ng-content>\n </ng-container>\n\n <!-- When items exist, display them -->\n <div *ngFor=\"let item of items\">\n\n <!-- Item Header -->\n <div class=\"cqa-bg-white cqa-border cqa-border-solid cqa-border-[#E5E5E5] cqa-rounded-md cqa-overflow-hidden\">\n <div class=\"cqa-py-2 cqa-px-3 cqa-flex cqa-items-center cqa-justify-between cqa-gap-3\">\n <!-- Left side: Status and Title -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-flex-1\">\n <!-- Status Icon (Filled Green Circle with Checkmark) -->\n <div>\n <!-- Success -->\n <svg *ngIf=\"item.status === 'success'\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <g clip-path=\"url(#clip0_48_121)\">\n <path\n d=\"M10.0003 18.3337C14.6027 18.3337 18.3337 14.6027 18.3337 10.0003C18.3337 5.39795 14.6027 1.66699 10.0003 1.66699C5.39795 1.66699 1.66699 5.39795 1.66699 10.0003C1.66699 14.6027 5.39795 18.3337 10.0003 18.3337Z\"\n stroke=\"#00A63E\" stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M7.5 9.99967L9.16667 11.6663L12.5 8.33301\" stroke=\"#00A63E\" stroke-width=\"1.66667\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </g>\n <defs>\n <clipPath id=\"clip0_48_121\">\n <rect width=\"20\" height=\"20\" fill=\"white\" />\n </clipPath>\n </defs>\n </svg>\n <!-- Failed -->\n <svg *ngIf=\"item.status === 'failed'\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"10\" cy=\"10\" r=\"8\" fill=\"#EF4444\" />\n <path d=\"M7 7L13 13M13 7L7 13\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n <!-- Pending -->\n <svg *ngIf=\"item.status === 'pending'\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"10\" cy=\"10\" r=\"8\" fill=\"#9CA3AF\" />\n <path d=\"M10 6V10L13 12\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n <!-- Running -->\n <svg *ngIf=\"item.status === 'running'\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"10\" cy=\"10\" r=\"8\" fill=\"#3B82F6\" />\n <path d=\"M10 6V10L13 12\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n \n <!-- Title -->\n <span class=\"cqa-text-[14px] cqa-leading-[18px]\" style=\"word-break: break-word;\">\n {{ item.title }}\n </span>\n </div>\n \n <!-- Right side: Duration and View Steps Link -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-3\">\n <!-- Step action icons (only when isDebug) -->\n <div *ngIf=\"isDebug\" class=\"cqa-flex cqa-items-center cqa-gap-0.5 cqa-text-[#9CA3AF]\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Edit\" (click)=\"onEditStep(item, $event)\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">edit</mat-icon>\n </button>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Add\" [matMenuTriggerFor]=\"addStepMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">add</mat-icon>\n </button>\n <mat-menu #addStepMenu=\"matMenu\" class=\"cqa-add-step-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of addStepMenuOptions\" (click)=\"onAddStepOptionSelect(item, opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"More options\" [matMenuTriggerFor]=\"stepMoreMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">more_vert</mat-icon>\n </button>\n <mat-menu #stepMoreMenu=\"matMenu\" class=\"cqa-step-more-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of stepMoreMenuOptions\" (click)=\"onStepMoreOptionSelect(item, opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n </div>\n <!-- Duration with Clock Icon -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-1\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\"\n stroke=\"#6A7282\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6 3V6L8 7\" stroke=\"#6A7282\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n <span class=\"cqa-text-[14px] cqa-leading-[20px] cqa-text-[#6A7282]\">\n {{ formatDuration(item.duration) }}\n </span>\n </div>\n \n <!-- View Steps Link: redirect mode (navigates to URL) or inline mode (toggle expand) -->\n <a *ngIf=\"hasViewStepsRedirectUrl(item)\"\n [href]=\"getItemViewStepsUrl(item)\"\n [attr.target]=\"viewStepsOpenInNewTab ? '_blank' : null\"\n [attr.rel]=\"viewStepsOpenInNewTab ? 'noopener noreferrer' : null\"\n class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-semibold cqa-text-[#3F43EE] cqa-no-underline cqa-flex cqa-items-center cqa-gap-1 hover:cqa-underline\">\n <span>View steps</span>\n <svg class=\"cqa-transition-transform\" width=\"16\" height=\"15\"\n viewBox=\"0 0 16 15\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M8.6552 12.8184L7.55413 11.7668L10.852 8.5864H2.83984V7.05032H10.852L7.55413 3.87506L8.6552 2.81836L13.8398 7.81836L8.6552 12.8184Z\"\n fill=\"#3F43EE\" />\n </svg>\n </a>\n <a *ngIf=\"!hasViewStepsRedirectUrl(item)\" href=\"#\" (click)=\"onViewSteps(item, $event)\"\n class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-semibold cqa-text-[#3F43EE] cqa-no-underline cqa-flex cqa-items-center cqa-gap-1 hover:cqa-underline\">\n <span>{{ isItemExpanded(item.id) ? 'Hide steps' : 'View steps' }}</span>\n <svg [class.cqa-rotate-90]=\"isItemExpanded(item.id)\" class=\"cqa-transition-transform\" width=\"16\" height=\"15\"\n viewBox=\"0 0 16 15\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M8.6552 12.8184L7.55413 11.7668L10.852 8.5864H2.83984V7.05032H10.852L7.55413 3.87506L8.6552 2.81836L13.8398 7.81836L8.6552 12.8184Z\"\n fill=\"#3F43EE\" />\n </svg>\n </a>\n </div>\n </div>\n </div>\n\n <!-- Steps Content (shown when item is expanded) -->\n <div *ngIf=\"isItemExpanded(item.id)\">\n <!-- Custom template via TemplateRef (from @ContentChild or @Input) - passes item as context -->\n <ng-container *ngIf=\"itemContentTpl || itemContentTemplate\">\n <div class=\"cqa-p-3\">\n <ng-container\n *ngTemplateOutlet=\"(itemContentTpl || itemContentTemplate)!; context: { $implicit: item, item: item }\"></ng-container>\n </div>\n </ng-container>\n\n <!-- Custom content projection via ng-content - displayed for all expanded items -->\n <ng-content select=\"[itemContent]\"></ng-content>\n </div>\n </div>\n</div>\n\n<!-- Custom content projection after all items - for steps loaded after API call -->\n<ng-content select=\"[afterItems]\"></ng-content>", components: [{ type: ButtonComponent, selector: "cqa-button", inputs: ["variant", "btnSize", "disabled", "icon", "iconPosition", "fullWidth", "iconColor", "type", "text", "customClass", "inlineStyles", "tooltip", "tooltipPosition"], outputs: ["clicked"] }, { type: i3$3.MatProgressSpinner, selector: "mat-progress-spinner, mat-spinner", inputs: ["color", "diameter", "strokeWidth", "mode", "value"], exportAs: ["matProgressSpinner"] }, { type: i1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i2$1.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }, { type: i2$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }, { type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }] });
|
|
13073
13943
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: MainStepCollapseComponent, decorators: [{
|
|
13074
13944
|
type: Component,
|
|
13075
|
-
args: [{ selector: 'cqa-main-step-collapse', host: { class: 'cqa-ui-root' }, template: "<!-- Header -->\n<div\n class=\"cqa-mt-2 cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-px-3 cqa-py-2 cqa-cursor-pointer cqa-bg-[#EEF2FF] cqa-rounded-[4px] cqa-border cqa-border-[#C6D2FF] cqa-border-solid\"\n (click)=\"toggle()\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-w-full\">\n <!-- Chevron Icon (Left) -->\n <!-- <svg [class.cqa-rotate-180]=\"isExpanded\" class=\"cqa-transition-transform\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 6L8 10L12 6\" stroke=\"#3F51B5\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg> -->\n <div><svg [class.cqa-rotate-180]=\"isExpanded\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 6L8 10L12 6\" stroke=\"#4F39F6\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg></div>\n\n <!-- Chain-Link Icon (if configured, otherwise default) -->\n <!-- <div *ngIf=\"icon && icon.type === 'folder'\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M11.6666 11.6667C11.976 11.6667 12.2728 11.5437 12.4916 11.325C12.7104 11.1062 12.8333 10.8094 12.8333 10.5V4.66667C12.8333 4.35725 12.7104 4.0605 12.4916 3.84171C12.2728 3.62292 11.976 3.5 11.6666 3.5H7.05829C6.86318 3.50191 6.67069 3.45486 6.49847 3.36314C6.32624 3.27142 6.17977 3.13797 6.07246 2.975L5.59996 2.275C5.49373 2.11369 5.34911 1.98128 5.17908 1.88965C5.00906 1.79802 4.81894 1.75003 4.62579 1.75H2.33329C2.02387 1.75 1.72713 1.87292 1.50833 2.09171C1.28954 2.3105 1.16663 2.60725 1.16663 2.91667V10.5C1.16663 10.8094 1.28954 11.1062 1.50833 11.325C1.72713 11.5437 2.02387 11.6667 2.33329 11.6667H11.6666Z\" fill=\"#EFF6FF\" stroke=\"#3F51B5\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n <div *ngIf=\"icon && icon.type === 'loop'\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect width=\"16\" height=\"16\" rx=\"4\" fill=\"#EBECFD\"/>\n <path d=\"M9.66663 4.66666L11 5.99999L9.66663 7.33332\" stroke=\"#3F51B5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M5 7.66667V7.33333C5 6.97971 5.14048 6.64057 5.39052 6.39052C5.64057 6.14048 5.97971 6 6.33333 6H11\" stroke=\"#3F51B5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M6.33333 11.3333L5 9.99999L6.33333 8.66666\" stroke=\"#3F51B5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M11 8.33334V8.66668C11 9.0203 10.8595 9.35944 10.6095 9.60949C10.3594 9.85953 10.0203 10 9.66667 10H5\" stroke=\"#3F51B5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div> -->\n <!-- Bar Icon (Bulleted List) -->\n <div *ngIf=\"icon && icon.type === 'bar'\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <!-- First bullet and line -->\n <circle cx=\"3\" cy=\"5\" r=\"2\" fill=\"#4F39F6\"/>\n <line x1=\"7\" y1=\"5\" x2=\"17\" y2=\"5\" stroke=\"#4F39F6\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n <!-- Second bullet and line -->\n <circle cx=\"3\" cy=\"10\" r=\"2\" fill=\"#4F39F6\"/>\n <line x1=\"7\" y1=\"10\" x2=\"17\" y2=\"10\" stroke=\"#4F39F6\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n <!-- Third bullet and line -->\n <circle cx=\"3\" cy=\"15\" r=\"2\" fill=\"#4F39F6\"/>\n <line x1=\"7\" y1=\"15\" x2=\"17\" y2=\"15\" stroke=\"#4F39F6\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n </svg>\n </div>\n\n <!-- Default Chain-Link Icon (when no icon or icon type is not specified) -->\n <div *ngIf=\"!icon || (icon.type !== 'bar' && icon.type !== 'folder' && icon.type !== 'loop' && icon.type !== 'custom')\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M7.50033 14.1663H5.83366C4.72859 14.1663 3.66878 13.7274 2.88738 12.946C2.10598 12.1646 1.66699 11.1047 1.66699 9.99967C1.66699 8.89461 2.10598 7.8348 2.88738 7.0534C3.66878 6.27199 4.72859 5.83301 5.83366 5.83301H7.50033\"\n stroke=\"#4F39F6\" stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M12.5 5.83301H14.1667C15.2717 5.83301 16.3315 6.27199 17.1129 7.0534C17.8943 7.8348 18.3333 8.89461 18.3333 9.99967C18.3333 11.1047 17.8943 12.1646 17.1129 12.946C16.3315 13.7274 15.2717 14.1663 14.1667 14.1663H12.5\"\n stroke=\"#4F39F6\" stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6.66699 10H13.3337\" stroke=\"#4F39F6\" stroke-width=\"1.66667\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n\n <!-- Custom Icon -->\n <div *ngIf=\"icon && icon.type === 'custom' && icon.svg\" [innerHTML]=\"icon.svg\"></div>\n\n <!-- Title -->\n <span class=\"cqa-font-semibold cqa-text-[14px] cqa-leading-[17px] cqa-text-[#312C85] cqa-flex-1\">\n {{ title }}\n </span>\n\n <!-- Badge and dynamic header buttons -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" (click)=\"$event.stopPropagation()\">\n <ng-container *ngFor=\"let btn of headerButtons; let i = index\">\n <cqa-button\n [text]=\"btn.text\"\n [icon]=\"btn.icon\"\n [variant]=\"btn.variant || 'outlined'\"\n [disabled]=\"btn.disabled\"\n [tooltip]=\"btn.tooltip\"\n [customClass]=\"btn.customClass\"\n [btnSize]=\"btn.btnSize || 'sm'\"\n (clicked)=\"onHeaderButtonClick(btn, i, $event)\">\n </cqa-button>\n </ng-container>\n <span\n class=\"cqa-px-2 cqa-py-[2px] cqa-rounded-[4px] cqa-bg-[#C6D2FF] cqa-text-[12px] cqa-leading-[16px] cqa-text-[#432DD7]\">\n {{ getDisplayCount() }}\n </span>\n </div>\n </div>\n</div>\n\n<!-- Expanded Content -->\n<div *ngIf=\"isExpanded\" class=\"cqa-mt-2 cqa-flex cqa-flex-col cqa-gap-2 cqa-px-2.5\">\n <!-- When there are no items, display ng-content directly -->\n <ng-container *ngIf=\"!items || items.length === 0\">\n <ng-content></ng-content>\n </ng-container>\n\n <!-- When items exist, display them -->\n <div *ngFor=\"let item of items\">\n\n <!-- Item Header -->\n <div class=\"cqa-bg-white cqa-border cqa-border-solid cqa-border-[#E5E5E5] cqa-rounded-md cqa-overflow-hidden\">\n <div class=\"cqa-py-2 cqa-px-3 cqa-flex cqa-items-center cqa-justify-between cqa-gap-3\">\n <!-- Left side: Status and Title -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-flex-1\">\n <!-- Status Icon (Filled Green Circle with Checkmark) -->\n <div>\n <!-- Success -->\n <svg *ngIf=\"item.status === 'success'\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <g clip-path=\"url(#clip0_48_121)\">\n <path\n d=\"M10.0003 18.3337C14.6027 18.3337 18.3337 14.6027 18.3337 10.0003C18.3337 5.39795 14.6027 1.66699 10.0003 1.66699C5.39795 1.66699 1.66699 5.39795 1.66699 10.0003C1.66699 14.6027 5.39795 18.3337 10.0003 18.3337Z\"\n stroke=\"#00A63E\" stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M7.5 9.99967L9.16667 11.6663L12.5 8.33301\" stroke=\"#00A63E\" stroke-width=\"1.66667\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </g>\n <defs>\n <clipPath id=\"clip0_48_121\">\n <rect width=\"20\" height=\"20\" fill=\"white\" />\n </clipPath>\n </defs>\n </svg>\n <!-- Failed -->\n <svg *ngIf=\"item.status === 'failed'\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"10\" cy=\"10\" r=\"8\" fill=\"#EF4444\" />\n <path d=\"M7 7L13 13M13 7L7 13\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n <!-- Pending -->\n <svg *ngIf=\"item.status === 'pending'\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"10\" cy=\"10\" r=\"8\" fill=\"#9CA3AF\" />\n <path d=\"M10 6V10L13 12\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n <!-- Running -->\n <svg *ngIf=\"item.status === 'running'\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"10\" cy=\"10\" r=\"8\" fill=\"#3B82F6\" />\n <path d=\"M10 6V10L13 12\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n \n <!-- Title -->\n <span class=\"cqa-text-[14px] cqa-leading-[18px]\" style=\"word-break: break-word;\">\n {{ item.title }}\n </span>\n </div>\n \n <!-- Right side: Duration and View Steps Link -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-3\">\n <!-- Step action icons (only when isDebug) -->\n <div *ngIf=\"isDebug\" class=\"cqa-flex cqa-items-center cqa-gap-0.5 cqa-text-[#9CA3AF]\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Edit\" (click)=\"onEditStep(item, $event)\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">edit</mat-icon>\n </button>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Add\" [matMenuTriggerFor]=\"addStepMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">add</mat-icon>\n </button>\n <mat-menu #addStepMenu=\"matMenu\" class=\"cqa-add-step-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of addStepMenuOptions\" (click)=\"onAddStepOptionSelect(item, opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"More options\" [matMenuTriggerFor]=\"stepMoreMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">more_vert</mat-icon>\n </button>\n <mat-menu #stepMoreMenu=\"matMenu\" class=\"cqa-step-more-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of stepMoreMenuOptions\" (click)=\"onStepMoreOptionSelect(item, opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n </div>\n <!-- Duration with Clock Icon -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-1\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\"\n stroke=\"#6A7282\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6 3V6L8 7\" stroke=\"#6A7282\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n <span class=\"cqa-text-[14px] cqa-leading-[20px] cqa-text-[#6A7282]\">\n {{ formatDuration(item.duration) }}\n </span>\n </div>\n \n <!-- View Steps Link: redirect mode (navigates to URL) or inline mode (toggle expand) -->\n <a *ngIf=\"hasViewStepsRedirectUrl(item)\"\n [href]=\"getItemViewStepsUrl(item)\"\n [attr.target]=\"viewStepsOpenInNewTab ? '_blank' : null\"\n [attr.rel]=\"viewStepsOpenInNewTab ? 'noopener noreferrer' : null\"\n class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-semibold cqa-text-[#3F43EE] cqa-no-underline cqa-flex cqa-items-center cqa-gap-1 hover:cqa-underline\">\n <span>View steps</span>\n <svg class=\"cqa-transition-transform\" width=\"16\" height=\"15\"\n viewBox=\"0 0 16 15\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M8.6552 12.8184L7.55413 11.7668L10.852 8.5864H2.83984V7.05032H10.852L7.55413 3.87506L8.6552 2.81836L13.8398 7.81836L8.6552 12.8184Z\"\n fill=\"#3F43EE\" />\n </svg>\n </a>\n <a *ngIf=\"!hasViewStepsRedirectUrl(item)\" href=\"#\" (click)=\"onViewSteps(item, $event)\"\n class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-semibold cqa-text-[#3F43EE] cqa-no-underline cqa-flex cqa-items-center cqa-gap-1 hover:cqa-underline\">\n <span>{{ isItemExpanded(item.id) ? 'Hide steps' : 'View steps' }}</span>\n <svg [class.cqa-rotate-90]=\"isItemExpanded(item.id)\" class=\"cqa-transition-transform\" width=\"16\" height=\"15\"\n viewBox=\"0 0 16 15\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M8.6552 12.8184L7.55413 11.7668L10.852 8.5864H2.83984V7.05032H10.852L7.55413 3.87506L8.6552 2.81836L13.8398 7.81836L8.6552 12.8184Z\"\n fill=\"#3F43EE\" />\n </svg>\n </a>\n </div>\n </div>\n </div>\n\n <!-- Steps Content (shown when item is expanded) -->\n <div *ngIf=\"isItemExpanded(item.id)\">\n <!-- Custom template via TemplateRef (from @ContentChild or @Input) - passes item as context -->\n <ng-container *ngIf=\"itemContentTpl || itemContentTemplate\">\n <div class=\"cqa-p-3\">\n <ng-container\n *ngTemplateOutlet=\"(itemContentTpl || itemContentTemplate)!; context: { $implicit: item, item: item }\"></ng-container>\n </div>\n </ng-container>\n\n <!-- Custom content projection via ng-content - displayed for all expanded items -->\n <ng-content select=\"[itemContent]\"></ng-content>\n </div>\n </div>\n</div>\n\n<!-- Custom content projection after all items - for steps loaded after API call -->\n<ng-content select=\"[afterItems]\"></ng-content>", styles: [] }]
|
|
13945
|
+
args: [{ selector: 'cqa-main-step-collapse', host: { class: 'cqa-ui-root' }, template: "<!-- Header -->\n<div\n class=\"cqa-mt-2 cqa-flex cqa-items-center cqa-justify-between cqa-gap-3 cqa-px-3 cqa-py-2 cqa-cursor-pointer cqa-bg-[#EEF2FF] cqa-rounded-[4px] cqa-border cqa-border-[#C6D2FF] cqa-border-solid\"\n (click)=\"toggle()\">\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-w-full\">\n <!-- Chevron Icon (Left) -->\n <!-- <svg [class.cqa-rotate-180]=\"isExpanded\" class=\"cqa-transition-transform\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 6L8 10L12 6\" stroke=\"#3F51B5\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg> -->\n <div><svg [class.cqa-rotate-180]=\"isExpanded\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 6L8 10L12 6\" stroke=\"#4F39F6\" stroke-width=\"1.33333\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg></div>\n\n <!-- Chain-Link Icon (if configured, otherwise default) -->\n <!-- <div *ngIf=\"icon && icon.type === 'folder'\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M11.6666 11.6667C11.976 11.6667 12.2728 11.5437 12.4916 11.325C12.7104 11.1062 12.8333 10.8094 12.8333 10.5V4.66667C12.8333 4.35725 12.7104 4.0605 12.4916 3.84171C12.2728 3.62292 11.976 3.5 11.6666 3.5H7.05829C6.86318 3.50191 6.67069 3.45486 6.49847 3.36314C6.32624 3.27142 6.17977 3.13797 6.07246 2.975L5.59996 2.275C5.49373 2.11369 5.34911 1.98128 5.17908 1.88965C5.00906 1.79802 4.81894 1.75003 4.62579 1.75H2.33329C2.02387 1.75 1.72713 1.87292 1.50833 2.09171C1.28954 2.3105 1.16663 2.60725 1.16663 2.91667V10.5C1.16663 10.8094 1.28954 11.1062 1.50833 11.325C1.72713 11.5437 2.02387 11.6667 2.33329 11.6667H11.6666Z\" fill=\"#EFF6FF\" stroke=\"#3F51B5\" stroke-width=\"1.16667\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n <div *ngIf=\"icon && icon.type === 'loop'\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect width=\"16\" height=\"16\" rx=\"4\" fill=\"#EBECFD\"/>\n <path d=\"M9.66663 4.66666L11 5.99999L9.66663 7.33332\" stroke=\"#3F51B5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M5 7.66667V7.33333C5 6.97971 5.14048 6.64057 5.39052 6.39052C5.64057 6.14048 5.97971 6 6.33333 6H11\" stroke=\"#3F51B5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M6.33333 11.3333L5 9.99999L6.33333 8.66666\" stroke=\"#3F51B5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n <path d=\"M11 8.33334V8.66668C11 9.0203 10.8595 9.35944 10.6095 9.60949C10.3594 9.85953 10.0203 10 9.66667 10H5\" stroke=\"#3F51B5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div> -->\n <!-- Bar Icon (Bulleted List) -->\n <div *ngIf=\"icon && icon.type === 'bar'\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <!-- First bullet and line -->\n <circle cx=\"3\" cy=\"5\" r=\"2\" fill=\"#4F39F6\"/>\n <line x1=\"7\" y1=\"5\" x2=\"17\" y2=\"5\" stroke=\"#4F39F6\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n <!-- Second bullet and line -->\n <circle cx=\"3\" cy=\"10\" r=\"2\" fill=\"#4F39F6\"/>\n <line x1=\"7\" y1=\"10\" x2=\"17\" y2=\"10\" stroke=\"#4F39F6\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n <!-- Third bullet and line -->\n <circle cx=\"3\" cy=\"15\" r=\"2\" fill=\"#4F39F6\"/>\n <line x1=\"7\" y1=\"15\" x2=\"17\" y2=\"15\" stroke=\"#4F39F6\" stroke-width=\"1.5\" stroke-linecap=\"round\"/>\n </svg>\n </div>\n\n <!-- Default Chain-Link Icon (when no icon or icon type is not specified) -->\n <div *ngIf=\"!icon || (icon.type !== 'bar' && icon.type !== 'folder' && icon.type !== 'loop' && icon.type !== 'custom')\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M7.50033 14.1663H5.83366C4.72859 14.1663 3.66878 13.7274 2.88738 12.946C2.10598 12.1646 1.66699 11.1047 1.66699 9.99967C1.66699 8.89461 2.10598 7.8348 2.88738 7.0534C3.66878 6.27199 4.72859 5.83301 5.83366 5.83301H7.50033\"\n stroke=\"#4F39F6\" stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path\n d=\"M12.5 5.83301H14.1667C15.2717 5.83301 16.3315 6.27199 17.1129 7.0534C17.8943 7.8348 18.3333 8.89461 18.3333 9.99967C18.3333 11.1047 17.8943 12.1646 17.1129 12.946C16.3315 13.7274 15.2717 14.1663 14.1667 14.1663H12.5\"\n stroke=\"#4F39F6\" stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6.66699 10H13.3337\" stroke=\"#4F39F6\" stroke-width=\"1.66667\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n\n <!-- Custom Icon -->\n <div *ngIf=\"icon && icon.type === 'custom' && icon.svg\" [innerHTML]=\"icon.svg\"></div>\n\n <!-- Title -->\n <span class=\"cqa-font-semibold cqa-text-[14px] cqa-leading-[17px] cqa-text-[#312C85] cqa-flex-1\">\n {{ title }}\n </span>\n\n <!-- Badge and dynamic header buttons -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-2\" (click)=\"$event.stopPropagation()\">\n <ng-container *ngFor=\"let btn of headerButtons; let i = index\">\n <cqa-button\n [text]=\"btn.text\"\n [icon]=\"btn.icon\"\n [variant]=\"btn.variant || 'outlined'\"\n [disabled]=\"btn.disabled\"\n [tooltip]=\"btn.tooltip\"\n [customClass]=\"btn.customClass\"\n [btnSize]=\"btn.btnSize || 'sm'\"\n (clicked)=\"onHeaderButtonClick(btn, i, $event)\">\n </cqa-button>\n </ng-container>\n <span\n class=\"cqa-px-2 cqa-py-[2px] cqa-rounded-[4px] cqa-bg-[#C6D2FF] cqa-text-[12px] cqa-leading-[16px] cqa-text-[#432DD7] cqa-inline-flex cqa-items-center cqa-justify-center cqa-min-w-[24px]\">\n <mat-spinner *ngIf=\"countLoading\" diameter=\"16\" class=\"cqa-inline-block\"></mat-spinner>\n <span *ngIf=\"!countLoading\">{{ getDisplayCount() }}</span>\n </span>\n </div>\n </div>\n</div>\n\n<!-- Expanded Content -->\n<div *ngIf=\"isExpanded\" class=\"cqa-mt-2 cqa-flex cqa-flex-col cqa-gap-2 cqa-px-2.5\">\n <!-- When there are no items, display ng-content directly -->\n <ng-container *ngIf=\"!items || items.length === 0\">\n <ng-content></ng-content>\n </ng-container>\n\n <!-- When items exist, display them -->\n <div *ngFor=\"let item of items\">\n\n <!-- Item Header -->\n <div class=\"cqa-bg-white cqa-border cqa-border-solid cqa-border-[#E5E5E5] cqa-rounded-md cqa-overflow-hidden\">\n <div class=\"cqa-py-2 cqa-px-3 cqa-flex cqa-items-center cqa-justify-between cqa-gap-3\">\n <!-- Left side: Status and Title -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-3 cqa-flex-1\">\n <!-- Status Icon (Filled Green Circle with Checkmark) -->\n <div>\n <!-- Success -->\n <svg *ngIf=\"item.status === 'success'\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <g clip-path=\"url(#clip0_48_121)\">\n <path\n d=\"M10.0003 18.3337C14.6027 18.3337 18.3337 14.6027 18.3337 10.0003C18.3337 5.39795 14.6027 1.66699 10.0003 1.66699C5.39795 1.66699 1.66699 5.39795 1.66699 10.0003C1.66699 14.6027 5.39795 18.3337 10.0003 18.3337Z\"\n stroke=\"#00A63E\" stroke-width=\"1.66667\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M7.5 9.99967L9.16667 11.6663L12.5 8.33301\" stroke=\"#00A63E\" stroke-width=\"1.66667\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </g>\n <defs>\n <clipPath id=\"clip0_48_121\">\n <rect width=\"20\" height=\"20\" fill=\"white\" />\n </clipPath>\n </defs>\n </svg>\n <!-- Failed -->\n <svg *ngIf=\"item.status === 'failed'\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"10\" cy=\"10\" r=\"8\" fill=\"#EF4444\" />\n <path d=\"M7 7L13 13M13 7L7 13\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n <!-- Pending -->\n <svg *ngIf=\"item.status === 'pending'\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"10\" cy=\"10\" r=\"8\" fill=\"#9CA3AF\" />\n <path d=\"M10 6V10L13 12\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n <!-- Running -->\n <svg *ngIf=\"item.status === 'running'\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"10\" cy=\"10\" r=\"8\" fill=\"#3B82F6\" />\n <path d=\"M10 6V10L13 12\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n \n <!-- Title -->\n <span class=\"cqa-text-[14px] cqa-leading-[18px]\" style=\"word-break: break-word;\">\n {{ item.title }}\n </span>\n </div>\n \n <!-- Right side: Duration and View Steps Link -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-3\">\n <!-- Step action icons (only when isDebug) -->\n <div *ngIf=\"isDebug\" class=\"cqa-flex cqa-items-center cqa-gap-0.5 cqa-text-[#9CA3AF]\" (click)=\"$event.stopPropagation()\">\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Edit\" (click)=\"onEditStep(item, $event)\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">edit</mat-icon>\n </button>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"Add\" [matMenuTriggerFor]=\"addStepMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">add</mat-icon>\n </button>\n <mat-menu #addStepMenu=\"matMenu\" class=\"cqa-add-step-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of addStepMenuOptions\" (click)=\"onAddStepOptionSelect(item, opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n <button type=\"button\" class=\"cqa-p-0 cqa-border-0 cqa-bg-transparent cqa-cursor-pointer hover:cqa-opacity-80 cqa-transition-opacity focus:cqa-outline-none\" aria-label=\"More options\" [matMenuTriggerFor]=\"stepMoreMenu\">\n <mat-icon class=\"!cqa-text-[14px] !cqa-w-[14px] !cqa-h-[14px]\">more_vert</mat-icon>\n </button>\n <mat-menu #stepMoreMenu=\"matMenu\" class=\"cqa-step-more-menu\" xPosition=\"before\" yPosition=\"below\">\n <button mat-menu-item *ngFor=\"let opt of stepMoreMenuOptions\" (click)=\"onStepMoreOptionSelect(item, opt, $event)\">{{ opt.label }}</button>\n </mat-menu>\n </div>\n <!-- Duration with Clock Icon -->\n <div class=\"cqa-flex cqa-items-center cqa-gap-1\">\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M6 11C8.76142 11 11 8.76142 11 6C11 3.23858 8.76142 1 6 1C3.23858 1 1 3.23858 1 6C1 8.76142 3.23858 11 6 11Z\"\n stroke=\"#6A7282\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6 3V6L8 7\" stroke=\"#6A7282\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n <span class=\"cqa-text-[14px] cqa-leading-[20px] cqa-text-[#6A7282]\">\n {{ formatDuration(item.duration) }}\n </span>\n </div>\n \n <!-- View Steps Link: redirect mode (navigates to URL) or inline mode (toggle expand) -->\n <a *ngIf=\"hasViewStepsRedirectUrl(item)\"\n [href]=\"getItemViewStepsUrl(item)\"\n [attr.target]=\"viewStepsOpenInNewTab ? '_blank' : null\"\n [attr.rel]=\"viewStepsOpenInNewTab ? 'noopener noreferrer' : null\"\n class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-semibold cqa-text-[#3F43EE] cqa-no-underline cqa-flex cqa-items-center cqa-gap-1 hover:cqa-underline\">\n <span>View steps</span>\n <svg class=\"cqa-transition-transform\" width=\"16\" height=\"15\"\n viewBox=\"0 0 16 15\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M8.6552 12.8184L7.55413 11.7668L10.852 8.5864H2.83984V7.05032H10.852L7.55413 3.87506L8.6552 2.81836L13.8398 7.81836L8.6552 12.8184Z\"\n fill=\"#3F43EE\" />\n </svg>\n </a>\n <a *ngIf=\"!hasViewStepsRedirectUrl(item)\" href=\"#\" (click)=\"onViewSteps(item, $event)\"\n class=\"cqa-text-[12px] cqa-leading-[15px] cqa-font-semibold cqa-text-[#3F43EE] cqa-no-underline cqa-flex cqa-items-center cqa-gap-1 hover:cqa-underline\">\n <span>{{ isItemExpanded(item.id) ? 'Hide steps' : 'View steps' }}</span>\n <svg [class.cqa-rotate-90]=\"isItemExpanded(item.id)\" class=\"cqa-transition-transform\" width=\"16\" height=\"15\"\n viewBox=\"0 0 16 15\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M8.6552 12.8184L7.55413 11.7668L10.852 8.5864H2.83984V7.05032H10.852L7.55413 3.87506L8.6552 2.81836L13.8398 7.81836L8.6552 12.8184Z\"\n fill=\"#3F43EE\" />\n </svg>\n </a>\n </div>\n </div>\n </div>\n\n <!-- Steps Content (shown when item is expanded) -->\n <div *ngIf=\"isItemExpanded(item.id)\">\n <!-- Custom template via TemplateRef (from @ContentChild or @Input) - passes item as context -->\n <ng-container *ngIf=\"itemContentTpl || itemContentTemplate\">\n <div class=\"cqa-p-3\">\n <ng-container\n *ngTemplateOutlet=\"(itemContentTpl || itemContentTemplate)!; context: { $implicit: item, item: item }\"></ng-container>\n </div>\n </ng-container>\n\n <!-- Custom content projection via ng-content - displayed for all expanded items -->\n <ng-content select=\"[itemContent]\"></ng-content>\n </div>\n </div>\n</div>\n\n<!-- Custom content projection after all items - for steps loaded after API call -->\n<ng-content select=\"[afterItems]\"></ng-content>", styles: [] }]
|
|
13076
13946
|
}], propDecorators: { title: [{
|
|
13077
13947
|
type: Input
|
|
13078
13948
|
}], items: [{
|
|
@@ -13083,6 +13953,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
13083
13953
|
type: Input
|
|
13084
13954
|
}], count: [{
|
|
13085
13955
|
type: Input
|
|
13956
|
+
}], countLoading: [{
|
|
13957
|
+
type: Input
|
|
13086
13958
|
}], itemContentTemplate: [{
|
|
13087
13959
|
type: Input
|
|
13088
13960
|
}], headerButtons: [{
|
|
@@ -29543,6 +30415,7 @@ UiKitModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "1
|
|
|
29543
30415
|
FileDownloadStepComponent,
|
|
29544
30416
|
DocumentVerificationStepComponent,
|
|
29545
30417
|
LiveExecutionStepComponent,
|
|
30418
|
+
AiLogsWithReasoningComponent,
|
|
29546
30419
|
JumpToStepModalComponent,
|
|
29547
30420
|
BreakpointsModalComponent,
|
|
29548
30421
|
MainStepCollapseComponent,
|
|
@@ -29634,6 +30507,7 @@ UiKitModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "1
|
|
|
29634
30507
|
MatInputModule,
|
|
29635
30508
|
OverlayModule,
|
|
29636
30509
|
PortalModule,
|
|
30510
|
+
ScrollingModule,
|
|
29637
30511
|
NgxTypedJsModule,
|
|
29638
30512
|
DndModule], exports: [ButtonComponent,
|
|
29639
30513
|
SearchBarComponent,
|
|
@@ -29685,6 +30559,7 @@ UiKitModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "1
|
|
|
29685
30559
|
FileDownloadStepComponent,
|
|
29686
30560
|
DocumentVerificationStepComponent,
|
|
29687
30561
|
LiveExecutionStepComponent,
|
|
30562
|
+
AiLogsWithReasoningComponent,
|
|
29688
30563
|
JumpToStepModalComponent,
|
|
29689
30564
|
BreakpointsModalComponent,
|
|
29690
30565
|
MainStepCollapseComponent,
|
|
@@ -29816,6 +30691,7 @@ UiKitModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "1
|
|
|
29816
30691
|
MatInputModule,
|
|
29817
30692
|
OverlayModule,
|
|
29818
30693
|
PortalModule,
|
|
30694
|
+
ScrollingModule,
|
|
29819
30695
|
NgxTypedJsModule,
|
|
29820
30696
|
DndModule
|
|
29821
30697
|
]] });
|
|
@@ -29874,6 +30750,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
29874
30750
|
FileDownloadStepComponent,
|
|
29875
30751
|
DocumentVerificationStepComponent,
|
|
29876
30752
|
LiveExecutionStepComponent,
|
|
30753
|
+
AiLogsWithReasoningComponent,
|
|
29877
30754
|
JumpToStepModalComponent,
|
|
29878
30755
|
BreakpointsModalComponent,
|
|
29879
30756
|
MainStepCollapseComponent,
|
|
@@ -29968,6 +30845,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
29968
30845
|
MatInputModule,
|
|
29969
30846
|
OverlayModule,
|
|
29970
30847
|
PortalModule,
|
|
30848
|
+
ScrollingModule,
|
|
29971
30849
|
NgxTypedJsModule,
|
|
29972
30850
|
DndModule
|
|
29973
30851
|
],
|
|
@@ -30022,6 +30900,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
30022
30900
|
FileDownloadStepComponent,
|
|
30023
30901
|
DocumentVerificationStepComponent,
|
|
30024
30902
|
LiveExecutionStepComponent,
|
|
30903
|
+
AiLogsWithReasoningComponent,
|
|
30025
30904
|
JumpToStepModalComponent,
|
|
30026
30905
|
BreakpointsModalComponent,
|
|
30027
30906
|
MainStepCollapseComponent,
|
|
@@ -30768,5 +31647,5 @@ function buildTestCaseDetailsFromApi(data, options) {
|
|
|
30768
31647
|
* Generated bundle index. Do not edit.
|
|
30769
31648
|
*/
|
|
30770
31649
|
|
|
30771
|
-
export { ADVANCED_SUBFIELDS_BY_TYPE, ADVANCED_TOGGLE_KEYS, AIActionStepComponent, AIAgentStepComponent, API_EDIT_STEP_LABELS, ActionMenuButtonComponent, AddPrerequisiteCasesSectionComponent, AiDebugAlertComponent, AiReasoningComponent, ApiEditStepComponent, ApiStepComponent, AutocompleteComponent, BadgeComponent, BasicStepComponent, BreakpointsModalComponent, ButtonComponent, CUSTOM_EDIT_STEP_DATA, CUSTOM_EDIT_STEP_EDIT_IN_DEPTH, CUSTOM_EDIT_STEP_REF, CUSTOM_ELEMENT_POPUP_REF, ChartCardComponent, ColumnVisibilityComponent, CompareRunsComponent, ConditionStepComponent, ConfigurationCardComponent, ConsoleAlertComponent, CoverageModuleCardComponent, CreateStepGroupComponent, CustomEditStepComponent, CustomEditStepRef, CustomEditStepService, CustomInputComponent, CustomTextareaComponent, CustomToggleComponent, DEFAULT_METADATA_COLOR, DEFAULT_PRIORITY_COLOR_CONFIG, DEFAULT_STATUS_COLOR_CONFIG, DIALOG_DATA, DIALOG_REF, DashboardHeaderComponent, DaterangepickerComponent, DaterangepickerDirective, DbQueryExecutionItemComponent, DbVerificationStepComponent, DeleteStepsComponent, DetailDrawerComponent, DetailDrawerTabComponent, DetailDrawerTabContentDirective, DetailSidePanelComponent, DialogComponent, DialogRef, DialogService, DocumentVerificationStepComponent, DropdownButtonComponent, DynamicCellContainerDirective, DynamicCellTemplateDirective, DynamicFilterComponent, DynamicHeaderTemplateDirective, DynamicSelectFieldComponent, DynamicTableComponent, ELEMENT_POPUP_DATA, ELEMENT_POPUP_EDIT_IN_DEPTH, EMPTY_STATE_IMAGES, EMPTY_STATE_PRESETS, ElementListComponent, ElementPopupComponent, ElementPopupRef, ElementPopupService, EmptyStateComponent, ErrorModalComponent, ExecutionResultModalComponent, ExportCodeModalComponent, FailedStepCardComponent, FailedStepComponent, FailedTestCasesCardComponent, FileDownloadStepComponent, FileUploadComponent, FullTableLoaderComponent, HeatErrorMapCellComponent, InsightCardComponent, ItemListComponent, IterationsLoopComponent, JumpToStepModalComponent, LiveConversationComponent, LiveExecutionStepComponent, LoopStepComponent, MainStepCollapseComponent, MetricsCardComponent, NetworkRequestComponent, OtherButtonComponent, PRIORITY_COLORS, PaginationComponent, ProgressIndicatorComponent, ProgressTextCardComponent, RESULT_COLORS, RunHistoryCardComponent, STATUS_COLORS, STEP_DETAILS_DRAWER_DATA, STEP_DETAILS_DRAWER_REF, STEP_DETAILS_FIELDS_BY_TYPE, STEP_DETAILS_FIELD_META, SearchBarComponent, SegmentControlComponent, SelectedFiltersComponent, SelfHealAnalysisComponent, SessionChangesModalComponent, SimulatorComponent, StepBuilderActionComponent, StepBuilderAiAgentComponent, StepBuilderConditionComponent, StepBuilderCustomCodeComponent, StepBuilderDatabaseComponent, StepBuilderDocumentComponent, StepBuilderDocumentGenerationTemplateStepComponent, StepBuilderGroupComponent, StepBuilderLoopComponent, StepBuilderRecordStepComponent, StepDetailsDrawerComponent, StepDetailsDrawerRef, StepDetailsDrawerService, StepGroupComponent, StepProgressCardComponent, StepRendererComponent, StepStatusCardComponent, StepTypes, TEST_CASE_DETAILS_FIELD_MAP, TEST_CASE_DETAILS_SELECT_KEYS, TEST_DATA_MODAL_DATA, TEST_DATA_MODAL_EDIT_IN_DEPTH, TEST_DATA_MODAL_REF, TableActionToolbarComponent, TableDataLoaderComponent, TableTemplateComponent, TailwindOverlayContainer, TemplateVariablesFormComponent, TestCaseAiAgentStepComponent, TestCaseAiVerifyStepComponent, TestCaseApiStepComponent, TestCaseConditionStepComponent, TestCaseCustomCodeStepComponent, TestCaseDatabaseStepComponent, TestCaseDetailsComponent, TestCaseDetailsEditComponent, TestCaseDetailsRendererComponent, TestCaseLoopStepComponent, TestCaseNormalStepComponent, TestCaseRestoreSessionStepComponent, TestCaseScreenshotStepComponent, TestCaseScrollStepComponent, TestCaseStepGroupComponent, TestCaseUploadStepComponent, TestCaseVerifyUrlStepComponent, TestDataModalComponent, TestDataModalRef, TestDataModalService, TestDistributionCardComponent, UiKitModule, UpdatedFailedStepComponent, ViewMoreFailedStepButtonComponent, VisualComparisonComponent, VisualDifferenceModalComponent, buildTestCaseDetailsFromApi, getDynamicFieldsFromLegacyConfig, getEmptyStatePreset, getMetadataColor, getMetadataValueStyle, getStepDetailsStepType, humanizeVariableKey, isAiAgentStepConfig, isAiVerifyStepConfig, isApiStepConfig, isConditionStepConfig, isCustomCodeStepConfig, isDatabaseStepConfig, isLoopStepConfig, isNormalStepConfig, isRestoreSessionStepConfig, isScreenshotStepConfig, isScrollStepConfig, isStepGroupConfig, isUploadStepConfig, isVerifyUrlStepConfig, mapApiVariablesToDynamicFields };
|
|
31650
|
+
export { ADVANCED_SUBFIELDS_BY_TYPE, ADVANCED_TOGGLE_KEYS, AIActionStepComponent, AIAgentStepComponent, API_EDIT_STEP_LABELS, ActionMenuButtonComponent, AddPrerequisiteCasesSectionComponent, AiDebugAlertComponent, AiLogsWithReasoningComponent, AiReasoningComponent, ApiEditStepComponent, ApiStepComponent, AutocompleteComponent, BadgeComponent, BasicStepComponent, BreakpointsModalComponent, ButtonComponent, CUSTOM_EDIT_STEP_DATA, CUSTOM_EDIT_STEP_EDIT_IN_DEPTH, CUSTOM_EDIT_STEP_REF, CUSTOM_ELEMENT_POPUP_REF, ChartCardComponent, ColumnVisibilityComponent, CompareRunsComponent, ConditionStepComponent, ConfigurationCardComponent, ConsoleAlertComponent, CoverageModuleCardComponent, CreateStepGroupComponent, CustomEditStepComponent, CustomEditStepRef, CustomEditStepService, CustomInputComponent, CustomTextareaComponent, CustomToggleComponent, DEFAULT_METADATA_COLOR, DEFAULT_PRIORITY_COLOR_CONFIG, DEFAULT_STATUS_COLOR_CONFIG, DIALOG_DATA, DIALOG_REF, DashboardHeaderComponent, DaterangepickerComponent, DaterangepickerDirective, DbQueryExecutionItemComponent, DbVerificationStepComponent, DeleteStepsComponent, DetailDrawerComponent, DetailDrawerTabComponent, DetailDrawerTabContentDirective, DetailSidePanelComponent, DialogComponent, DialogRef, DialogService, DocumentVerificationStepComponent, DropdownButtonComponent, DynamicCellContainerDirective, DynamicCellTemplateDirective, DynamicFilterComponent, DynamicHeaderTemplateDirective, DynamicSelectFieldComponent, DynamicTableComponent, ELEMENT_POPUP_DATA, ELEMENT_POPUP_EDIT_IN_DEPTH, EMPTY_STATE_IMAGES, EMPTY_STATE_PRESETS, ElementListComponent, ElementPopupComponent, ElementPopupRef, ElementPopupService, EmptyStateComponent, ErrorModalComponent, ExecutionResultModalComponent, ExportCodeModalComponent, FailedStepCardComponent, FailedStepComponent, FailedTestCasesCardComponent, FileDownloadStepComponent, FileUploadComponent, FullTableLoaderComponent, HeatErrorMapCellComponent, InsightCardComponent, ItemListComponent, IterationsLoopComponent, JumpToStepModalComponent, LiveConversationComponent, LiveExecutionStepComponent, LoopStepComponent, MainStepCollapseComponent, MetricsCardComponent, NetworkRequestComponent, OtherButtonComponent, PRIORITY_COLORS, PaginationComponent, ProgressIndicatorComponent, ProgressTextCardComponent, RESULT_COLORS, RunHistoryCardComponent, STATUS_COLORS, STEP_DETAILS_DRAWER_DATA, STEP_DETAILS_DRAWER_REF, STEP_DETAILS_FIELDS_BY_TYPE, STEP_DETAILS_FIELD_META, SearchBarComponent, SegmentControlComponent, SelectedFiltersComponent, SelfHealAnalysisComponent, SessionChangesModalComponent, SimulatorComponent, StepBuilderActionComponent, StepBuilderAiAgentComponent, StepBuilderConditionComponent, StepBuilderCustomCodeComponent, StepBuilderDatabaseComponent, StepBuilderDocumentComponent, StepBuilderDocumentGenerationTemplateStepComponent, StepBuilderGroupComponent, StepBuilderLoopComponent, StepBuilderRecordStepComponent, StepDetailsDrawerComponent, StepDetailsDrawerRef, StepDetailsDrawerService, StepGroupComponent, StepProgressCardComponent, StepRendererComponent, StepStatusCardComponent, StepTypes, TEST_CASE_DETAILS_FIELD_MAP, TEST_CASE_DETAILS_SELECT_KEYS, TEST_DATA_MODAL_DATA, TEST_DATA_MODAL_EDIT_IN_DEPTH, TEST_DATA_MODAL_REF, TableActionToolbarComponent, TableDataLoaderComponent, TableTemplateComponent, TailwindOverlayContainer, TemplateVariablesFormComponent, TestCaseAiAgentStepComponent, TestCaseAiVerifyStepComponent, TestCaseApiStepComponent, TestCaseConditionStepComponent, TestCaseCustomCodeStepComponent, TestCaseDatabaseStepComponent, TestCaseDetailsComponent, TestCaseDetailsEditComponent, TestCaseDetailsRendererComponent, TestCaseLoopStepComponent, TestCaseNormalStepComponent, TestCaseRestoreSessionStepComponent, TestCaseScreenshotStepComponent, TestCaseScrollStepComponent, TestCaseStepGroupComponent, TestCaseUploadStepComponent, TestCaseVerifyUrlStepComponent, TestDataModalComponent, TestDataModalRef, TestDataModalService, TestDistributionCardComponent, UiKitModule, UpdatedFailedStepComponent, ViewMoreFailedStepButtonComponent, VisualComparisonComponent, VisualDifferenceModalComponent, buildTestCaseDetailsFromApi, getDynamicFieldsFromLegacyConfig, getEmptyStatePreset, getMetadataColor, getMetadataValueStyle, getStepDetailsStepType, humanizeVariableKey, isAiAgentStepConfig, isAiVerifyStepConfig, isApiStepConfig, isConditionStepConfig, isCustomCodeStepConfig, isDatabaseStepConfig, isLoopStepConfig, isNormalStepConfig, isRestoreSessionStepConfig, isScreenshotStepConfig, isScrollStepConfig, isStepGroupConfig, isUploadStepConfig, isVerifyUrlStepConfig, mapApiVariablesToDynamicFields };
|
|
30772
31651
|
//# sourceMappingURL=cqa-lib-cqa-ui.mjs.map
|