@cqa-lib/cqa-ui 1.1.224 → 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/ui-kit.module.mjs +6 -1
- package/esm2020/public-api.mjs +2 -1
- package/fesm2015/cqa-lib-cqa-ui.mjs +879 -11
- package/fesm2015/cqa-lib-cqa-ui.mjs.map +1 -1
- package/fesm2020/cqa-lib-cqa-ui.mjs +1052 -11
- 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/ui-kit.module.d.ts +95 -94
- package/package.json +1 -1
- package/public-api.d.ts +1 -0
- package/styles.css +1 -1
|
@@ -40,7 +40,7 @@ import * as i3 from '@angular/cdk/portal';
|
|
|
40
40
|
import { TemplatePortal, CdkPortalOutlet, ComponentPortal, PortalModule } from '@angular/cdk/portal';
|
|
41
41
|
import * as i2$3 from '@angular/cdk/scrolling';
|
|
42
42
|
import { ScrollingModule } from '@angular/cdk/scrolling';
|
|
43
|
-
import * as
|
|
43
|
+
import * as i4$2 from 'ngx-typed-js';
|
|
44
44
|
import { NgxTypedJsModule } from 'ngx-typed-js';
|
|
45
45
|
import * as i1$2 from '@angular/platform-browser';
|
|
46
46
|
import * as jquery from 'jquery';
|
|
@@ -6519,6 +6519,39 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
6519
6519
|
type: Output
|
|
6520
6520
|
}] } });
|
|
6521
6521
|
|
|
6522
|
+
class AiLogsWithReasoningComponent extends BaseStepComponent {
|
|
6523
|
+
ngOnInit() { }
|
|
6524
|
+
get displayText() {
|
|
6525
|
+
return this.text || this.description || '';
|
|
6526
|
+
}
|
|
6527
|
+
get hasReasoning() {
|
|
6528
|
+
return !!this.reasoning;
|
|
6529
|
+
}
|
|
6530
|
+
get isSuccess() {
|
|
6531
|
+
const statusLower = this.status?.toLowerCase();
|
|
6532
|
+
return statusLower === 'success' || statusLower === 'passed';
|
|
6533
|
+
}
|
|
6534
|
+
get isFailed() {
|
|
6535
|
+
return this.status?.toLowerCase() === 'failed';
|
|
6536
|
+
}
|
|
6537
|
+
}
|
|
6538
|
+
AiLogsWithReasoningComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AiLogsWithReasoningComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
6539
|
+
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"] }] });
|
|
6540
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: AiLogsWithReasoningComponent, decorators: [{
|
|
6541
|
+
type: Component,
|
|
6542
|
+
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: [] }]
|
|
6543
|
+
}], propDecorators: { status: [{
|
|
6544
|
+
type: Input
|
|
6545
|
+
}], text: [{
|
|
6546
|
+
type: Input
|
|
6547
|
+
}], description: [{
|
|
6548
|
+
type: Input
|
|
6549
|
+
}], reasoning: [{
|
|
6550
|
+
type: Input
|
|
6551
|
+
}], duration: [{
|
|
6552
|
+
type: Input
|
|
6553
|
+
}] } });
|
|
6554
|
+
|
|
6522
6555
|
/**
|
|
6523
6556
|
* Component that renders the appropriate step component based on the step type.
|
|
6524
6557
|
* Uses dynamic component loading and an injection token to break circular dependencies
|
|
@@ -8636,6 +8669,15 @@ class BasicStepComponent extends BaseStepComponent {
|
|
|
8636
8669
|
this.stepMoreMenuOptions = DEFAULT_STEP_MORE_MENU_OPTIONS;
|
|
8637
8670
|
// Track which steps are still loading to show skeleton
|
|
8638
8671
|
this.loadingSteps = new Set();
|
|
8672
|
+
// Processed sub-steps for live mode WAIT_FOR_LOCATOR countdown grouping
|
|
8673
|
+
this.processedSubSteps = [];
|
|
8674
|
+
this.lastProcessedIndex = 0;
|
|
8675
|
+
this.waitLocatorGroupEntry = null;
|
|
8676
|
+
this.countdownIntervalId = null;
|
|
8677
|
+
// AI_AUTO_HEAL grouping: show loading until AI_AUTO_HEAL_SUCCESS or AI_AUTO_HEAL_FAILED
|
|
8678
|
+
this.aiAutoHealGroupEntry = null;
|
|
8679
|
+
// Processed sub-steps for run result screen (filter and split AI_AUTO_HEAL_SUCCESS/FAILED)
|
|
8680
|
+
this.processedSubStepsForRunResult = [];
|
|
8639
8681
|
this.showFailedStepDetails = false;
|
|
8640
8682
|
}
|
|
8641
8683
|
/** Show debug icon when debug mode is on (shown on parent and all child steps). */
|
|
@@ -8665,6 +8707,14 @@ class BasicStepComponent extends BaseStepComponent {
|
|
|
8665
8707
|
nestedSteps: stepsToUse,
|
|
8666
8708
|
};
|
|
8667
8709
|
super.ngOnInit();
|
|
8710
|
+
// Initialize live sub-step processing for WAIT_FOR_LOCATOR grouping
|
|
8711
|
+
if (this.isLive && this.subSteps && this.subSteps.length > 0) {
|
|
8712
|
+
this.processLiveSubSteps();
|
|
8713
|
+
}
|
|
8714
|
+
else if (!this.isLive && this.subSteps && this.subSteps.length > 0) {
|
|
8715
|
+
// Process for run result screen: filter and split AI_AUTO_HEAL_SUCCESS/FAILED
|
|
8716
|
+
this.processSubStepsForRunResult();
|
|
8717
|
+
}
|
|
8668
8718
|
// Initialize loading state if already expanded
|
|
8669
8719
|
if (this.isExpanded && this.nestedSteps && this.nestedSteps.length > 0) {
|
|
8670
8720
|
this.loadingSteps.clear();
|
|
@@ -8691,6 +8741,21 @@ class BasicStepComponent extends BaseStepComponent {
|
|
|
8691
8741
|
// Update config when subSteps changes
|
|
8692
8742
|
if (changes['subSteps'] && this.config) {
|
|
8693
8743
|
this.config.subSteps = this.subSteps || [];
|
|
8744
|
+
if (this.isLive) {
|
|
8745
|
+
this.processLiveSubSteps();
|
|
8746
|
+
}
|
|
8747
|
+
else {
|
|
8748
|
+
this.processSubStepsForRunResult();
|
|
8749
|
+
}
|
|
8750
|
+
}
|
|
8751
|
+
// Re-process when isLive changes
|
|
8752
|
+
if (changes['isLive'] && this.subSteps && this.subSteps.length > 0) {
|
|
8753
|
+
if (this.isLive) {
|
|
8754
|
+
this.processLiveSubSteps();
|
|
8755
|
+
}
|
|
8756
|
+
else {
|
|
8757
|
+
this.processSubStepsForRunResult();
|
|
8758
|
+
}
|
|
8694
8759
|
}
|
|
8695
8760
|
// Update config when nestedSteps changes
|
|
8696
8761
|
if (changes['nestedSteps'] && this.config) {
|
|
@@ -8724,6 +8789,14 @@ class BasicStepComponent extends BaseStepComponent {
|
|
|
8724
8789
|
});
|
|
8725
8790
|
}
|
|
8726
8791
|
}
|
|
8792
|
+
ngDoCheck() {
|
|
8793
|
+
if (!this.isLive)
|
|
8794
|
+
return;
|
|
8795
|
+
const currentLength = (this.subSteps || []).length;
|
|
8796
|
+
if (currentLength !== this.lastProcessedIndex) {
|
|
8797
|
+
this.processLiveSubSteps();
|
|
8798
|
+
}
|
|
8799
|
+
}
|
|
8727
8800
|
get hasSubSteps() {
|
|
8728
8801
|
return this.subSteps && this.subSteps.length > 0;
|
|
8729
8802
|
}
|
|
@@ -8859,12 +8932,219 @@ class BasicStepComponent extends BaseStepComponent {
|
|
|
8859
8932
|
}
|
|
8860
8933
|
}
|
|
8861
8934
|
}
|
|
8935
|
+
ngOnDestroy() {
|
|
8936
|
+
this.clearCountdownTimer();
|
|
8937
|
+
}
|
|
8938
|
+
processLiveSubSteps() {
|
|
8939
|
+
const allSubSteps = (this.subSteps || []);
|
|
8940
|
+
// Reset if subSteps were cleared or replaced with fewer entries
|
|
8941
|
+
if (allSubSteps.length < this.lastProcessedIndex) {
|
|
8942
|
+
this.resetLiveProcessing();
|
|
8943
|
+
}
|
|
8944
|
+
for (let i = this.lastProcessedIndex; i < allSubSteps.length; i++) {
|
|
8945
|
+
const subStep = allSubSteps[i];
|
|
8946
|
+
const uiType = subStep?.uiType || subStep?.type || '';
|
|
8947
|
+
const status = (subStep?.status || '').toLowerCase();
|
|
8948
|
+
if (uiType === 'WAIT_FOR_LOCATOR') {
|
|
8949
|
+
// Create a single grouped entry with a countdown; absorbs FIND_LOCATOR and LOCATOR_FOUND
|
|
8950
|
+
const timeoutSeconds = typeof subStep.value === 'number'
|
|
8951
|
+
? subStep.value
|
|
8952
|
+
: (subStep.value ? parseFloat(subStep.value) : 30);
|
|
8953
|
+
this.clearCountdownTimer();
|
|
8954
|
+
this.waitLocatorGroupEntry = {
|
|
8955
|
+
...subStep,
|
|
8956
|
+
remainingSeconds: timeoutSeconds,
|
|
8957
|
+
status: 'running'
|
|
8958
|
+
};
|
|
8959
|
+
this.processedSubSteps.push(this.waitLocatorGroupEntry);
|
|
8960
|
+
// Tick down every second
|
|
8961
|
+
this.countdownIntervalId = setInterval(() => {
|
|
8962
|
+
if (this.waitLocatorGroupEntry) {
|
|
8963
|
+
this.waitLocatorGroupEntry.remainingSeconds = Math.max(0, this.waitLocatorGroupEntry.remainingSeconds - 1);
|
|
8964
|
+
if (this.waitLocatorGroupEntry.remainingSeconds <= 0) {
|
|
8965
|
+
this.waitLocatorGroupEntry.status = 'failed';
|
|
8966
|
+
this.waitLocatorGroupEntry.remainingSeconds = null;
|
|
8967
|
+
this.clearCountdownTimer();
|
|
8968
|
+
this.waitLocatorGroupEntry = null;
|
|
8969
|
+
}
|
|
8970
|
+
}
|
|
8971
|
+
}, 1000);
|
|
8972
|
+
}
|
|
8973
|
+
else if (uiType === 'FIND_LOCATOR') {
|
|
8974
|
+
if (status === 'failed' || status === 'failure') {
|
|
8975
|
+
// Abort countdown, replace group entry with this failed log
|
|
8976
|
+
if (this.waitLocatorGroupEntry) {
|
|
8977
|
+
this.processedSubSteps = this.processedSubSteps.filter(entry => entry !== this.waitLocatorGroupEntry);
|
|
8978
|
+
this.clearCountdownTimer();
|
|
8979
|
+
this.waitLocatorGroupEntry = null;
|
|
8980
|
+
}
|
|
8981
|
+
this.processedSubSteps.push({ ...subStep, status: 'failed' });
|
|
8982
|
+
}
|
|
8983
|
+
else if (this.waitLocatorGroupEntry) {
|
|
8984
|
+
// Update the single group entry's text so the user sees progress
|
|
8985
|
+
const newText = subStep.description || subStep.text || subStep.title;
|
|
8986
|
+
if (newText)
|
|
8987
|
+
this.waitLocatorGroupEntry.description = newText;
|
|
8988
|
+
}
|
|
8989
|
+
}
|
|
8990
|
+
else if (uiType === 'LOCATOR_FOUND') {
|
|
8991
|
+
if (status === 'failed' || status === 'failure') {
|
|
8992
|
+
// Abort countdown, replace group entry with this failed log
|
|
8993
|
+
if (this.waitLocatorGroupEntry) {
|
|
8994
|
+
this.processedSubSteps = this.processedSubSteps.filter(entry => entry !== this.waitLocatorGroupEntry);
|
|
8995
|
+
this.clearCountdownTimer();
|
|
8996
|
+
this.waitLocatorGroupEntry = null;
|
|
8997
|
+
}
|
|
8998
|
+
this.processedSubSteps.push({ ...subStep, status: 'failed' });
|
|
8999
|
+
}
|
|
9000
|
+
else {
|
|
9001
|
+
// Sequence complete – update group entry to show LOCATOR_FOUND text as success
|
|
9002
|
+
if (this.waitLocatorGroupEntry) {
|
|
9003
|
+
const newText = subStep.description || subStep.text || subStep.title;
|
|
9004
|
+
if (newText)
|
|
9005
|
+
this.waitLocatorGroupEntry.description = newText;
|
|
9006
|
+
this.waitLocatorGroupEntry.status = 'success';
|
|
9007
|
+
this.waitLocatorGroupEntry.remainingSeconds = null;
|
|
9008
|
+
this.clearCountdownTimer();
|
|
9009
|
+
this.waitLocatorGroupEntry = null;
|
|
9010
|
+
}
|
|
9011
|
+
else {
|
|
9012
|
+
// No active group – push LOCATOR_FOUND normally
|
|
9013
|
+
this.processedSubSteps.push({ ...subStep });
|
|
9014
|
+
}
|
|
9015
|
+
}
|
|
9016
|
+
}
|
|
9017
|
+
else if (uiType === 'AI_AUTO_HEAL') {
|
|
9018
|
+
// Add single loading entry; will be replaced by AI_AUTO_HEAL_SUCCESS or AI_AUTO_HEAL_FAILED
|
|
9019
|
+
this.aiAutoHealGroupEntry = {
|
|
9020
|
+
...subStep,
|
|
9021
|
+
description: subStep.description || subStep.text || 'AI auto-heal started',
|
|
9022
|
+
status: 'running',
|
|
9023
|
+
uiType: 'AI_AUTO_HEAL'
|
|
9024
|
+
};
|
|
9025
|
+
this.processedSubSteps.push(this.aiAutoHealGroupEntry);
|
|
9026
|
+
}
|
|
9027
|
+
else if (uiType === 'AI_AUTO_HEAL_SUCCESS' || uiType === 'AI_AUTO_HEAL_FAILED') {
|
|
9028
|
+
// Remove loading entry and add TWO separate entries: value and reasoning (like AI_ANSWER)
|
|
9029
|
+
if (this.aiAutoHealGroupEntry) {
|
|
9030
|
+
this.processedSubSteps = this.processedSubSteps.filter(entry => entry !== this.aiAutoHealGroupEntry);
|
|
9031
|
+
this.aiAutoHealGroupEntry = null;
|
|
9032
|
+
}
|
|
9033
|
+
const isSuccess = uiType === 'AI_AUTO_HEAL_SUCCESS';
|
|
9034
|
+
const value = subStep.value ?? subStep.text ?? '';
|
|
9035
|
+
const reasoning = subStep.reasoning ?? subStep.Reasoning ?? '';
|
|
9036
|
+
const baseDuration = subStep.duration || 0;
|
|
9037
|
+
const finalStatus = isSuccess ? 'success' : 'failed';
|
|
9038
|
+
// First entry: value/description
|
|
9039
|
+
const valueDescription = subStep.text || subStep.description || (isSuccess
|
|
9040
|
+
? `AI auto-heal successful. New locator: ${value}`
|
|
9041
|
+
: `AI auto-heal failed for element: ${value}`);
|
|
9042
|
+
this.processedSubSteps.push({
|
|
9043
|
+
...subStep,
|
|
9044
|
+
description: valueDescription,
|
|
9045
|
+
value: value,
|
|
9046
|
+
reasoning: null,
|
|
9047
|
+
status: finalStatus,
|
|
9048
|
+
uiType: 'AI_AUTO_HEAL_VALUE',
|
|
9049
|
+
type: 'AI_AUTO_HEAL_VALUE',
|
|
9050
|
+
duration: baseDuration,
|
|
9051
|
+
isAiAutoHealResult: true
|
|
9052
|
+
});
|
|
9053
|
+
// Second entry: reasoning (only if present)
|
|
9054
|
+
if (reasoning) {
|
|
9055
|
+
this.processedSubSteps.push({
|
|
9056
|
+
...subStep,
|
|
9057
|
+
description: reasoning,
|
|
9058
|
+
value: null,
|
|
9059
|
+
reasoning: reasoning,
|
|
9060
|
+
status: finalStatus,
|
|
9061
|
+
uiType: 'AI_AUTO_HEAL_REASONING',
|
|
9062
|
+
type: 'AI_AUTO_HEAL_REASONING',
|
|
9063
|
+
duration: baseDuration,
|
|
9064
|
+
isAiAutoHealResult: true
|
|
9065
|
+
});
|
|
9066
|
+
}
|
|
9067
|
+
}
|
|
9068
|
+
else {
|
|
9069
|
+
// Any failed log while a countdown is active – resolve it as failed
|
|
9070
|
+
if ((status === 'failed' || status === 'failure') && this.waitLocatorGroupEntry) {
|
|
9071
|
+
this.waitLocatorGroupEntry.status = 'failed';
|
|
9072
|
+
this.waitLocatorGroupEntry.remainingSeconds = null;
|
|
9073
|
+
this.clearCountdownTimer();
|
|
9074
|
+
this.waitLocatorGroupEntry = null;
|
|
9075
|
+
}
|
|
9076
|
+
this.processedSubSteps.push(subStep);
|
|
9077
|
+
}
|
|
9078
|
+
}
|
|
9079
|
+
this.lastProcessedIndex = allSubSteps.length;
|
|
9080
|
+
}
|
|
9081
|
+
resetLiveProcessing() {
|
|
9082
|
+
this.clearCountdownTimer();
|
|
9083
|
+
this.processedSubSteps = [];
|
|
9084
|
+
this.lastProcessedIndex = 0;
|
|
9085
|
+
this.waitLocatorGroupEntry = null;
|
|
9086
|
+
this.aiAutoHealGroupEntry = null;
|
|
9087
|
+
}
|
|
9088
|
+
clearCountdownTimer() {
|
|
9089
|
+
if (this.countdownIntervalId !== null) {
|
|
9090
|
+
clearInterval(this.countdownIntervalId);
|
|
9091
|
+
this.countdownIntervalId = null;
|
|
9092
|
+
}
|
|
9093
|
+
}
|
|
9094
|
+
processSubStepsForRunResult() {
|
|
9095
|
+
const allSubSteps = (this.subSteps || []);
|
|
9096
|
+
this.processedSubStepsForRunResult = [];
|
|
9097
|
+
for (const subStep of allSubSteps) {
|
|
9098
|
+
const uiType = subStep?.uiType || subStep?.type || '';
|
|
9099
|
+
// Split AI_AUTO_HEAL_SUCCESS/FAILED into two entries
|
|
9100
|
+
if (uiType === 'AI_AUTO_HEAL_SUCCESS' || uiType === 'AI_AUTO_HEAL_FAILED') {
|
|
9101
|
+
const isSuccess = uiType === 'AI_AUTO_HEAL_SUCCESS';
|
|
9102
|
+
const value = subStep.value ?? subStep.text ?? '';
|
|
9103
|
+
const reasoning = subStep.reasoning ?? subStep.Reasoning ?? '';
|
|
9104
|
+
const baseDuration = subStep.duration || 0;
|
|
9105
|
+
const finalStatus = isSuccess ? 'success' : 'failed';
|
|
9106
|
+
// First entry: value/description
|
|
9107
|
+
const valueDescription = (isSuccess
|
|
9108
|
+
? `AI auto-heal successful. New locator: ${value}`
|
|
9109
|
+
: `AI auto-heal failed for element: ${value}`);
|
|
9110
|
+
this.processedSubStepsForRunResult.push({
|
|
9111
|
+
...subStep,
|
|
9112
|
+
description: valueDescription,
|
|
9113
|
+
value: value,
|
|
9114
|
+
reasoning: null,
|
|
9115
|
+
status: finalStatus,
|
|
9116
|
+
uiType: 'AI_AUTO_HEAL_VALUE',
|
|
9117
|
+
type: 'AI_AUTO_HEAL_VALUE',
|
|
9118
|
+
duration: baseDuration,
|
|
9119
|
+
isAiAutoHealResult: true
|
|
9120
|
+
});
|
|
9121
|
+
// Second entry: reasoning (only if present)
|
|
9122
|
+
if (reasoning) {
|
|
9123
|
+
this.processedSubStepsForRunResult.push({
|
|
9124
|
+
...subStep,
|
|
9125
|
+
description: reasoning,
|
|
9126
|
+
value: null,
|
|
9127
|
+
reasoning: reasoning,
|
|
9128
|
+
status: finalStatus,
|
|
9129
|
+
uiType: 'AI_AUTO_HEAL_REASONING',
|
|
9130
|
+
type: 'AI_AUTO_HEAL_REASONING',
|
|
9131
|
+
duration: baseDuration,
|
|
9132
|
+
isAiAutoHealResult: true
|
|
9133
|
+
});
|
|
9134
|
+
}
|
|
9135
|
+
}
|
|
9136
|
+
else {
|
|
9137
|
+
// All other logs pass through as-is
|
|
9138
|
+
this.processedSubStepsForRunResult.push(subStep);
|
|
9139
|
+
}
|
|
9140
|
+
}
|
|
9141
|
+
}
|
|
8862
9142
|
}
|
|
8863
9143
|
BasicStepComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: BasicStepComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
8864
|
-
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"] }] });
|
|
9144
|
+
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"] }] });
|
|
8865
9145
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: BasicStepComponent, decorators: [{
|
|
8866
9146
|
type: Component,
|
|
8867
|
-
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" }]
|
|
9147
|
+
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" }]
|
|
8868
9148
|
}], propDecorators: { id: [{
|
|
8869
9149
|
type: Input
|
|
8870
9150
|
}], testStepResultId: [{
|
|
@@ -9492,6 +9772,15 @@ class LoopStepComponent extends BaseStepComponent {
|
|
|
9492
9772
|
this.userManuallyClosed = false;
|
|
9493
9773
|
// Track which steps are still loading to show skeleton
|
|
9494
9774
|
this.loadingSteps = new Set();
|
|
9775
|
+
// Processed sub-steps for live mode WAIT_FOR_LOCATOR countdown grouping
|
|
9776
|
+
this.processedSubSteps = [];
|
|
9777
|
+
this.lastProcessedIndex = 0;
|
|
9778
|
+
this.waitLocatorGroupEntry = null;
|
|
9779
|
+
this.countdownIntervalId = null;
|
|
9780
|
+
// AI_AUTO_HEAL grouping: show loading until AI_AUTO_HEAL_SUCCESS or AI_AUTO_HEAL_FAILED
|
|
9781
|
+
this.aiAutoHealGroupEntry = null;
|
|
9782
|
+
// Processed sub-steps for run result screen (filter and split AI_AUTO_HEAL_SUCCESS/FAILED)
|
|
9783
|
+
this.processedSubStepsForRunResult = [];
|
|
9495
9784
|
}
|
|
9496
9785
|
/** Show debug icon when debug mode is on (shown on parent and all child steps). */
|
|
9497
9786
|
get showDebugIcon() {
|
|
@@ -9525,6 +9814,14 @@ class LoopStepComponent extends BaseStepComponent {
|
|
|
9525
9814
|
expanded: this.expanded,
|
|
9526
9815
|
};
|
|
9527
9816
|
super.ngOnInit();
|
|
9817
|
+
// Initialize live sub-step processing for WAIT_FOR_LOCATOR grouping
|
|
9818
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.subSteps && this.selectedIteration.subSteps.length > 0) {
|
|
9819
|
+
this.processLiveSubSteps();
|
|
9820
|
+
}
|
|
9821
|
+
else if (!this.isLive && this.selectedIteration && this.selectedIteration.subSteps && this.selectedIteration.subSteps.length > 0) {
|
|
9822
|
+
// Process for run result screen: filter and split AI_AUTO_HEAL_SUCCESS/FAILED
|
|
9823
|
+
this.processSubStepsForRunResult();
|
|
9824
|
+
}
|
|
9528
9825
|
// Initialize selection - prioritize selectedIterationId input, then default
|
|
9529
9826
|
if (this.selectedIterationId && this.iterations && this.iterations.length > 0) {
|
|
9530
9827
|
const found = this.iterations.find(iter => iter.id === this.selectedIterationId);
|
|
@@ -9564,9 +9861,20 @@ class LoopStepComponent extends BaseStepComponent {
|
|
|
9564
9861
|
if (currentValue) {
|
|
9565
9862
|
const found = this.iterations.find(iter => iter.id === currentValue);
|
|
9566
9863
|
if (found) {
|
|
9864
|
+
// Reset processing when switching to a different iteration
|
|
9865
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.id !== found.id) {
|
|
9866
|
+
this.resetLiveProcessing();
|
|
9867
|
+
}
|
|
9567
9868
|
this.selectedIteration = found;
|
|
9568
9869
|
// Sync userSelectedIterationId with the input value
|
|
9569
9870
|
this.userSelectedIterationId = currentValue;
|
|
9871
|
+
// Process live sub-steps when iteration changes
|
|
9872
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
9873
|
+
this.processLiveSubSteps();
|
|
9874
|
+
}
|
|
9875
|
+
else if (!this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
9876
|
+
this.processSubStepsForRunResult();
|
|
9877
|
+
}
|
|
9570
9878
|
}
|
|
9571
9879
|
else {
|
|
9572
9880
|
// If not found, select default
|
|
@@ -9585,14 +9893,35 @@ class LoopStepComponent extends BaseStepComponent {
|
|
|
9585
9893
|
if (this.userSelectedIterationId) {
|
|
9586
9894
|
const found = this.iterations.find(iter => iter.id === this.userSelectedIterationId);
|
|
9587
9895
|
if (found) {
|
|
9896
|
+
// Reset processing when switching to a different iteration
|
|
9897
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.id !== found.id) {
|
|
9898
|
+
this.resetLiveProcessing();
|
|
9899
|
+
}
|
|
9588
9900
|
this.selectedIteration = found;
|
|
9901
|
+
// Process live sub-steps when iteration changes
|
|
9902
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
9903
|
+
this.processLiveSubSteps();
|
|
9904
|
+
}
|
|
9905
|
+
else if (!this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
9906
|
+
this.processSubStepsForRunResult();
|
|
9907
|
+
}
|
|
9589
9908
|
}
|
|
9590
9909
|
else {
|
|
9591
9910
|
// User selection no longer valid, use selectedIterationId or default
|
|
9592
9911
|
if (this.selectedIterationId) {
|
|
9593
9912
|
const foundById = this.iterations.find(iter => iter.id === this.selectedIterationId);
|
|
9594
9913
|
if (foundById) {
|
|
9914
|
+
// Reset processing when switching to a different iteration
|
|
9915
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.id !== foundById.id) {
|
|
9916
|
+
this.resetLiveProcessing();
|
|
9917
|
+
}
|
|
9595
9918
|
this.selectedIteration = foundById;
|
|
9919
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
9920
|
+
this.processLiveSubSteps();
|
|
9921
|
+
}
|
|
9922
|
+
else if (!this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
9923
|
+
this.processSubStepsForRunResult();
|
|
9924
|
+
}
|
|
9596
9925
|
}
|
|
9597
9926
|
else {
|
|
9598
9927
|
this.selectDefaultIteration();
|
|
@@ -9608,7 +9937,14 @@ class LoopStepComponent extends BaseStepComponent {
|
|
|
9608
9937
|
if (this.selectedIterationId) {
|
|
9609
9938
|
const found = this.iterations.find(iter => iter.id === this.selectedIterationId);
|
|
9610
9939
|
if (found) {
|
|
9940
|
+
// Reset processing when switching to a different iteration
|
|
9941
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.id !== found.id) {
|
|
9942
|
+
this.resetLiveProcessing();
|
|
9943
|
+
}
|
|
9611
9944
|
this.selectedIteration = found;
|
|
9945
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
9946
|
+
this.processLiveSubSteps();
|
|
9947
|
+
}
|
|
9612
9948
|
}
|
|
9613
9949
|
else {
|
|
9614
9950
|
this.selectDefaultIteration();
|
|
@@ -9780,7 +10116,15 @@ class LoopStepComponent extends BaseStepComponent {
|
|
|
9780
10116
|
if (this.selectedIterationId) {
|
|
9781
10117
|
const found = this.iterations.find(iter => iter.id === this.selectedIterationId);
|
|
9782
10118
|
if (found) {
|
|
10119
|
+
// Reset processing when switching to a different iteration
|
|
10120
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.id !== found.id) {
|
|
10121
|
+
this.resetLiveProcessing();
|
|
10122
|
+
}
|
|
9783
10123
|
this.selectedIteration = found;
|
|
10124
|
+
// Process live sub-steps when iteration is selected
|
|
10125
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
10126
|
+
this.processLiveSubSteps();
|
|
10127
|
+
}
|
|
9784
10128
|
return;
|
|
9785
10129
|
}
|
|
9786
10130
|
}
|
|
@@ -9788,26 +10132,60 @@ class LoopStepComponent extends BaseStepComponent {
|
|
|
9788
10132
|
if (this.userSelectedIterationId) {
|
|
9789
10133
|
const found = this.iterations.find(iter => iter.id === this.userSelectedIterationId);
|
|
9790
10134
|
if (found) {
|
|
10135
|
+
// Reset processing when switching to a different iteration
|
|
10136
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.id !== found.id) {
|
|
10137
|
+
this.resetLiveProcessing();
|
|
10138
|
+
}
|
|
9791
10139
|
this.selectedIteration = found;
|
|
10140
|
+
// Process live sub-steps when iteration is selected
|
|
10141
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
10142
|
+
this.processLiveSubSteps();
|
|
10143
|
+
}
|
|
9792
10144
|
return;
|
|
9793
10145
|
}
|
|
9794
10146
|
}
|
|
9795
10147
|
// Apply default based on defaultIteration setting
|
|
9796
10148
|
if (this.defaultIteration === 'last' && this.iterations.length > 0) {
|
|
9797
10149
|
const lastIteration = this.iterations[this.iterations.length - 1];
|
|
10150
|
+
// Reset processing when switching to a different iteration
|
|
10151
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.id !== lastIteration.id) {
|
|
10152
|
+
this.resetLiveProcessing();
|
|
10153
|
+
}
|
|
9798
10154
|
this.selectedIteration = lastIteration;
|
|
9799
10155
|
// Set userSelectedIterationId to track the default selection
|
|
9800
10156
|
this.userSelectedIterationId = lastIteration.id;
|
|
10157
|
+
// Process live sub-steps when iteration is selected
|
|
10158
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
10159
|
+
this.processLiveSubSteps();
|
|
10160
|
+
}
|
|
10161
|
+
else if (!this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
10162
|
+
this.processSubStepsForRunResult();
|
|
10163
|
+
}
|
|
9801
10164
|
}
|
|
9802
10165
|
else if (this.iterations.length > 0) {
|
|
9803
10166
|
const firstIteration = this.iterations[0];
|
|
10167
|
+
// Reset processing when switching to a different iteration
|
|
10168
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.id !== firstIteration.id) {
|
|
10169
|
+
this.resetLiveProcessing();
|
|
10170
|
+
}
|
|
9804
10171
|
this.selectedIteration = firstIteration;
|
|
9805
10172
|
// Set userSelectedIterationId to track the default selection
|
|
9806
10173
|
this.userSelectedIterationId = firstIteration.id;
|
|
10174
|
+
// Process live sub-steps when iteration is selected
|
|
10175
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
10176
|
+
this.processLiveSubSteps();
|
|
10177
|
+
}
|
|
10178
|
+
else if (!this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
10179
|
+
this.processSubStepsForRunResult();
|
|
10180
|
+
}
|
|
9807
10181
|
}
|
|
9808
10182
|
}
|
|
9809
10183
|
handleIterationChange(iteration) {
|
|
9810
10184
|
console.log("ITERATION CHANGE", this.config, iteration);
|
|
10185
|
+
// Reset processing when switching iterations
|
|
10186
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.id !== iteration.id) {
|
|
10187
|
+
this.resetLiveProcessing();
|
|
10188
|
+
}
|
|
9811
10189
|
// Store the user's manual selection
|
|
9812
10190
|
this.selectedIteration = iteration;
|
|
9813
10191
|
this.userSelectedIterationId = iteration.id;
|
|
@@ -9833,6 +10211,13 @@ class LoopStepComponent extends BaseStepComponent {
|
|
|
9833
10211
|
};
|
|
9834
10212
|
}
|
|
9835
10213
|
}
|
|
10214
|
+
// Process live sub-steps when iteration changes
|
|
10215
|
+
if (this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
10216
|
+
this.processLiveSubSteps();
|
|
10217
|
+
}
|
|
10218
|
+
else if (!this.isLive && this.selectedIteration && this.selectedIteration.subSteps) {
|
|
10219
|
+
this.processSubStepsForRunResult();
|
|
10220
|
+
}
|
|
9836
10221
|
}
|
|
9837
10222
|
// Emit the event with the iteration ID
|
|
9838
10223
|
this.onIterationChange.emit(iteration.id);
|
|
@@ -10118,12 +10503,240 @@ class LoopStepComponent extends BaseStepComponent {
|
|
|
10118
10503
|
}
|
|
10119
10504
|
}
|
|
10120
10505
|
}
|
|
10506
|
+
ngDoCheck() {
|
|
10507
|
+
if (!this.isLive || !this.selectedIteration)
|
|
10508
|
+
return;
|
|
10509
|
+
const currentLength = (this.selectedIteration.subSteps || []).length;
|
|
10510
|
+
// Reset if iteration changed (detected by checking if we have a different iteration's subSteps)
|
|
10511
|
+
if (this.lastProcessedIndex > 0 && currentLength < this.lastProcessedIndex) {
|
|
10512
|
+
// Likely switched to a different iteration, reset
|
|
10513
|
+
this.resetLiveProcessing();
|
|
10514
|
+
}
|
|
10515
|
+
if (currentLength !== this.lastProcessedIndex) {
|
|
10516
|
+
this.processLiveSubSteps();
|
|
10517
|
+
}
|
|
10518
|
+
}
|
|
10519
|
+
ngOnDestroy() {
|
|
10520
|
+
this.clearCountdownTimer();
|
|
10521
|
+
}
|
|
10522
|
+
processLiveSubSteps() {
|
|
10523
|
+
if (!this.selectedIteration || !this.selectedIteration.subSteps) {
|
|
10524
|
+
this.resetLiveProcessing();
|
|
10525
|
+
return;
|
|
10526
|
+
}
|
|
10527
|
+
const allSubSteps = (this.selectedIteration.subSteps || []);
|
|
10528
|
+
// Reset if subSteps were cleared or replaced with fewer entries
|
|
10529
|
+
if (allSubSteps.length < this.lastProcessedIndex) {
|
|
10530
|
+
this.resetLiveProcessing();
|
|
10531
|
+
}
|
|
10532
|
+
for (let i = this.lastProcessedIndex; i < allSubSteps.length; i++) {
|
|
10533
|
+
const subStep = allSubSteps[i];
|
|
10534
|
+
const uiType = subStep?.uiType || subStep?.type || '';
|
|
10535
|
+
const status = (subStep?.status || '').toLowerCase();
|
|
10536
|
+
if (uiType === 'WAIT_FOR_LOCATOR') {
|
|
10537
|
+
// Create a single grouped entry with a countdown; absorbs FIND_LOCATOR and LOCATOR_FOUND
|
|
10538
|
+
const timeoutSeconds = typeof subStep.value === 'number'
|
|
10539
|
+
? subStep.value
|
|
10540
|
+
: (subStep.value ? parseFloat(subStep.value) : 30);
|
|
10541
|
+
this.clearCountdownTimer();
|
|
10542
|
+
this.waitLocatorGroupEntry = {
|
|
10543
|
+
...subStep,
|
|
10544
|
+
remainingSeconds: timeoutSeconds,
|
|
10545
|
+
status: 'running'
|
|
10546
|
+
};
|
|
10547
|
+
this.processedSubSteps.push(this.waitLocatorGroupEntry);
|
|
10548
|
+
// Tick down every second
|
|
10549
|
+
this.countdownIntervalId = setInterval(() => {
|
|
10550
|
+
if (this.waitLocatorGroupEntry) {
|
|
10551
|
+
this.waitLocatorGroupEntry.remainingSeconds = Math.max(0, this.waitLocatorGroupEntry.remainingSeconds - 1);
|
|
10552
|
+
if (this.waitLocatorGroupEntry.remainingSeconds <= 0) {
|
|
10553
|
+
this.waitLocatorGroupEntry.status = 'failed';
|
|
10554
|
+
this.waitLocatorGroupEntry.remainingSeconds = null;
|
|
10555
|
+
this.clearCountdownTimer();
|
|
10556
|
+
this.waitLocatorGroupEntry = null;
|
|
10557
|
+
}
|
|
10558
|
+
}
|
|
10559
|
+
}, 1000);
|
|
10560
|
+
}
|
|
10561
|
+
else if (uiType === 'FIND_LOCATOR') {
|
|
10562
|
+
if (status === 'failed' || status === 'failure') {
|
|
10563
|
+
// Abort countdown, replace group entry with this failed log
|
|
10564
|
+
if (this.waitLocatorGroupEntry) {
|
|
10565
|
+
this.processedSubSteps = this.processedSubSteps.filter(entry => entry !== this.waitLocatorGroupEntry);
|
|
10566
|
+
this.clearCountdownTimer();
|
|
10567
|
+
this.waitLocatorGroupEntry = null;
|
|
10568
|
+
}
|
|
10569
|
+
this.processedSubSteps.push({ ...subStep, status: 'failed' });
|
|
10570
|
+
}
|
|
10571
|
+
else if (this.waitLocatorGroupEntry) {
|
|
10572
|
+
// Update the single group entry's text so the user sees progress
|
|
10573
|
+
const newText = subStep.description || subStep.text || subStep.title;
|
|
10574
|
+
if (newText)
|
|
10575
|
+
this.waitLocatorGroupEntry.description = newText;
|
|
10576
|
+
}
|
|
10577
|
+
}
|
|
10578
|
+
else if (uiType === 'LOCATOR_FOUND') {
|
|
10579
|
+
if (status === 'failed' || status === 'failure') {
|
|
10580
|
+
// Abort countdown, replace group entry with this failed log
|
|
10581
|
+
if (this.waitLocatorGroupEntry) {
|
|
10582
|
+
this.processedSubSteps = this.processedSubSteps.filter(entry => entry !== this.waitLocatorGroupEntry);
|
|
10583
|
+
this.clearCountdownTimer();
|
|
10584
|
+
this.waitLocatorGroupEntry = null;
|
|
10585
|
+
}
|
|
10586
|
+
this.processedSubSteps.push({ ...subStep, status: 'failed' });
|
|
10587
|
+
}
|
|
10588
|
+
else {
|
|
10589
|
+
// Sequence complete – update group entry to show LOCATOR_FOUND text as success
|
|
10590
|
+
if (this.waitLocatorGroupEntry) {
|
|
10591
|
+
const newText = subStep.description || subStep.text || subStep.title;
|
|
10592
|
+
if (newText)
|
|
10593
|
+
this.waitLocatorGroupEntry.description = newText;
|
|
10594
|
+
this.waitLocatorGroupEntry.status = 'success';
|
|
10595
|
+
this.waitLocatorGroupEntry.remainingSeconds = null;
|
|
10596
|
+
this.clearCountdownTimer();
|
|
10597
|
+
this.waitLocatorGroupEntry = null;
|
|
10598
|
+
}
|
|
10599
|
+
else {
|
|
10600
|
+
// No active group – push LOCATOR_FOUND normally
|
|
10601
|
+
this.processedSubSteps.push({ ...subStep });
|
|
10602
|
+
}
|
|
10603
|
+
}
|
|
10604
|
+
}
|
|
10605
|
+
else if (uiType === 'AI_AUTO_HEAL') {
|
|
10606
|
+
// Add single loading entry; will be replaced by AI_AUTO_HEAL_SUCCESS or AI_AUTO_HEAL_FAILED
|
|
10607
|
+
this.aiAutoHealGroupEntry = {
|
|
10608
|
+
...subStep,
|
|
10609
|
+
description: subStep.description || subStep.text || 'AI auto-heal started',
|
|
10610
|
+
status: 'running',
|
|
10611
|
+
uiType: 'AI_AUTO_HEAL'
|
|
10612
|
+
};
|
|
10613
|
+
this.processedSubSteps.push(this.aiAutoHealGroupEntry);
|
|
10614
|
+
}
|
|
10615
|
+
else if (uiType === 'AI_AUTO_HEAL_SUCCESS' || uiType === 'AI_AUTO_HEAL_FAILED') {
|
|
10616
|
+
// Remove loading entry and add TWO separate entries: value and reasoning (like AI_ANSWER)
|
|
10617
|
+
if (this.aiAutoHealGroupEntry) {
|
|
10618
|
+
this.processedSubSteps = this.processedSubSteps.filter(entry => entry !== this.aiAutoHealGroupEntry);
|
|
10619
|
+
this.aiAutoHealGroupEntry = null;
|
|
10620
|
+
}
|
|
10621
|
+
const isSuccess = uiType === 'AI_AUTO_HEAL_SUCCESS';
|
|
10622
|
+
const value = subStep.value ?? subStep.text ?? '';
|
|
10623
|
+
const reasoning = subStep.reasoning ?? subStep.Reasoning ?? '';
|
|
10624
|
+
const baseDuration = subStep.duration || 0;
|
|
10625
|
+
const finalStatus = isSuccess ? 'success' : 'failed';
|
|
10626
|
+
// First entry: value/description
|
|
10627
|
+
const valueDescription = subStep.text || subStep.description || (isSuccess
|
|
10628
|
+
? `AI auto-heal successful. New locator: ${value}`
|
|
10629
|
+
: `AI auto-heal failed for element: ${value}`);
|
|
10630
|
+
this.processedSubSteps.push({
|
|
10631
|
+
...subStep,
|
|
10632
|
+
description: valueDescription,
|
|
10633
|
+
value: value,
|
|
10634
|
+
reasoning: null,
|
|
10635
|
+
status: finalStatus,
|
|
10636
|
+
uiType: 'AI_AUTO_HEAL_VALUE',
|
|
10637
|
+
type: 'AI_AUTO_HEAL_VALUE',
|
|
10638
|
+
duration: baseDuration,
|
|
10639
|
+
isAiAutoHealResult: true
|
|
10640
|
+
});
|
|
10641
|
+
// Second entry: reasoning (only if present)
|
|
10642
|
+
if (reasoning) {
|
|
10643
|
+
this.processedSubSteps.push({
|
|
10644
|
+
...subStep,
|
|
10645
|
+
description: reasoning,
|
|
10646
|
+
value: null,
|
|
10647
|
+
reasoning: reasoning,
|
|
10648
|
+
status: finalStatus,
|
|
10649
|
+
uiType: 'AI_AUTO_HEAL_REASONING',
|
|
10650
|
+
type: 'AI_AUTO_HEAL_REASONING',
|
|
10651
|
+
duration: baseDuration,
|
|
10652
|
+
isAiAutoHealResult: true
|
|
10653
|
+
});
|
|
10654
|
+
}
|
|
10655
|
+
}
|
|
10656
|
+
else {
|
|
10657
|
+
// Any failed log while a countdown is active – resolve it as failed
|
|
10658
|
+
if ((status === 'failed' || status === 'failure') && this.waitLocatorGroupEntry) {
|
|
10659
|
+
this.waitLocatorGroupEntry.status = 'failed';
|
|
10660
|
+
this.waitLocatorGroupEntry.remainingSeconds = null;
|
|
10661
|
+
this.clearCountdownTimer();
|
|
10662
|
+
this.waitLocatorGroupEntry = null;
|
|
10663
|
+
}
|
|
10664
|
+
this.processedSubSteps.push(subStep);
|
|
10665
|
+
}
|
|
10666
|
+
}
|
|
10667
|
+
this.lastProcessedIndex = allSubSteps.length;
|
|
10668
|
+
}
|
|
10669
|
+
resetLiveProcessing() {
|
|
10670
|
+
this.clearCountdownTimer();
|
|
10671
|
+
this.processedSubSteps = [];
|
|
10672
|
+
this.lastProcessedIndex = 0;
|
|
10673
|
+
this.waitLocatorGroupEntry = null;
|
|
10674
|
+
this.aiAutoHealGroupEntry = null;
|
|
10675
|
+
}
|
|
10676
|
+
clearCountdownTimer() {
|
|
10677
|
+
if (this.countdownIntervalId !== null) {
|
|
10678
|
+
clearInterval(this.countdownIntervalId);
|
|
10679
|
+
this.countdownIntervalId = null;
|
|
10680
|
+
}
|
|
10681
|
+
}
|
|
10682
|
+
processSubStepsForRunResult() {
|
|
10683
|
+
if (!this.selectedIteration || !this.selectedIteration.subSteps) {
|
|
10684
|
+
this.processedSubStepsForRunResult = [];
|
|
10685
|
+
return;
|
|
10686
|
+
}
|
|
10687
|
+
const allSubSteps = (this.selectedIteration.subSteps || []);
|
|
10688
|
+
this.processedSubStepsForRunResult = [];
|
|
10689
|
+
for (const subStep of allSubSteps) {
|
|
10690
|
+
const uiType = subStep?.uiType || subStep?.type || '';
|
|
10691
|
+
// Split AI_AUTO_HEAL_SUCCESS/FAILED into two entries
|
|
10692
|
+
if (uiType === 'AI_AUTO_HEAL_SUCCESS' || uiType === 'AI_AUTO_HEAL_FAILED') {
|
|
10693
|
+
const isSuccess = uiType === 'AI_AUTO_HEAL_SUCCESS';
|
|
10694
|
+
const value = subStep.value ?? subStep.text ?? '';
|
|
10695
|
+
const reasoning = subStep.reasoning ?? subStep.Reasoning ?? '';
|
|
10696
|
+
const baseDuration = subStep.duration || 0;
|
|
10697
|
+
const finalStatus = isSuccess ? 'success' : 'failed';
|
|
10698
|
+
// First entry: value/description
|
|
10699
|
+
const valueDescription = (isSuccess
|
|
10700
|
+
? `AI auto-heal successful. New locator: ${value}`
|
|
10701
|
+
: `AI auto-heal failed for element: ${value}`);
|
|
10702
|
+
this.processedSubStepsForRunResult.push({
|
|
10703
|
+
...subStep,
|
|
10704
|
+
description: valueDescription,
|
|
10705
|
+
value: value,
|
|
10706
|
+
reasoning: null,
|
|
10707
|
+
status: finalStatus,
|
|
10708
|
+
uiType: 'AI_AUTO_HEAL_VALUE',
|
|
10709
|
+
type: 'AI_AUTO_HEAL_VALUE',
|
|
10710
|
+
duration: baseDuration,
|
|
10711
|
+
isAiAutoHealResult: true
|
|
10712
|
+
});
|
|
10713
|
+
// Second entry: reasoning (only if present)
|
|
10714
|
+
if (reasoning) {
|
|
10715
|
+
this.processedSubStepsForRunResult.push({
|
|
10716
|
+
...subStep,
|
|
10717
|
+
description: reasoning,
|
|
10718
|
+
value: null,
|
|
10719
|
+
reasoning: reasoning,
|
|
10720
|
+
status: finalStatus,
|
|
10721
|
+
uiType: 'AI_AUTO_HEAL_REASONING',
|
|
10722
|
+
type: 'AI_AUTO_HEAL_REASONING',
|
|
10723
|
+
duration: baseDuration,
|
|
10724
|
+
isAiAutoHealResult: true
|
|
10725
|
+
});
|
|
10726
|
+
}
|
|
10727
|
+
}
|
|
10728
|
+
else {
|
|
10729
|
+
// All other logs pass through as-is
|
|
10730
|
+
this.processedSubStepsForRunResult.push(subStep);
|
|
10731
|
+
}
|
|
10732
|
+
}
|
|
10733
|
+
}
|
|
10121
10734
|
}
|
|
10122
10735
|
LoopStepComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: LoopStepComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
10123
|
-
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"] }] });
|
|
10736
|
+
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"] }] });
|
|
10124
10737
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: LoopStepComponent, decorators: [{
|
|
10125
10738
|
type: Component,
|
|
10126
|
-
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" }]
|
|
10739
|
+
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" }]
|
|
10127
10740
|
}], propDecorators: { id: [{
|
|
10128
10741
|
type: Input
|
|
10129
10742
|
}], testStepResultId: [{
|
|
@@ -11571,6 +12184,15 @@ class ApiStepComponent extends BaseStepComponent {
|
|
|
11571
12184
|
this.showFailedStepDetails = false;
|
|
11572
12185
|
this.userManuallyClosed = false;
|
|
11573
12186
|
this.showRequestSummaryCopied = false;
|
|
12187
|
+
// Processed initial actions for live mode WAIT_FOR_LOCATOR countdown grouping
|
|
12188
|
+
this.processedInitialActions = [];
|
|
12189
|
+
this.lastProcessedIndex = 0;
|
|
12190
|
+
this.waitLocatorGroupEntry = null;
|
|
12191
|
+
this.countdownIntervalId = null;
|
|
12192
|
+
// AI_AUTO_HEAL grouping: show loading until AI_AUTO_HEAL_SUCCESS or AI_AUTO_HEAL_FAILED
|
|
12193
|
+
this.aiAutoHealGroupEntry = null;
|
|
12194
|
+
// Processed initial actions for run result screen (filter and split AI_AUTO_HEAL_SUCCESS/FAILED)
|
|
12195
|
+
this.processedInitialActionsForRunResult = [];
|
|
11574
12196
|
this.showRequestHeadersCopied = false;
|
|
11575
12197
|
this.showResponseHeadersCopied = false;
|
|
11576
12198
|
this.showRequestBodyCopied = false;
|
|
@@ -11588,6 +12210,14 @@ class ApiStepComponent extends BaseStepComponent {
|
|
|
11588
12210
|
if (this.expanded !== undefined) {
|
|
11589
12211
|
this.isExpanded = this.expanded;
|
|
11590
12212
|
}
|
|
12213
|
+
// Initialize live initial actions processing for WAIT_FOR_LOCATOR grouping
|
|
12214
|
+
if (this.isLive && this.initialActions && this.initialActions.length > 0) {
|
|
12215
|
+
this.processLiveInitialActions();
|
|
12216
|
+
}
|
|
12217
|
+
else if (!this.isLive && this.initialActions && this.initialActions.length > 0) {
|
|
12218
|
+
// Process for run result screen: filter and split AI_AUTO_HEAL_SUCCESS/FAILED
|
|
12219
|
+
this.processInitialActionsForRunResult();
|
|
12220
|
+
}
|
|
11591
12221
|
}
|
|
11592
12222
|
ngOnChanges(changes) {
|
|
11593
12223
|
if (this.isLive) {
|
|
@@ -11606,6 +12236,13 @@ class ApiStepComponent extends BaseStepComponent {
|
|
|
11606
12236
|
if (changes['initialActions']) {
|
|
11607
12237
|
const previousActionsCount = changes['initialActions'].previousValue?.length || 0;
|
|
11608
12238
|
const currentActionsCount = (this.initialActions || []).length;
|
|
12239
|
+
// Process live initial actions
|
|
12240
|
+
if (this.isLive) {
|
|
12241
|
+
this.processLiveInitialActions();
|
|
12242
|
+
}
|
|
12243
|
+
else {
|
|
12244
|
+
this.processInitialActionsForRunResult();
|
|
12245
|
+
}
|
|
11609
12246
|
// Auto-expand if step is running and new initialActions are added (logs coming in)
|
|
11610
12247
|
if (!changes['initialActions'].firstChange &&
|
|
11611
12248
|
this.status === 'running' &&
|
|
@@ -12021,6 +12658,14 @@ class ApiStepComponent extends BaseStepComponent {
|
|
|
12021
12658
|
expanded: this.expanded,
|
|
12022
12659
|
};
|
|
12023
12660
|
}
|
|
12661
|
+
ngDoCheck() {
|
|
12662
|
+
if (!this.isLive)
|
|
12663
|
+
return;
|
|
12664
|
+
const currentLength = (this.initialActions || []).length;
|
|
12665
|
+
if (currentLength !== this.lastProcessedIndex) {
|
|
12666
|
+
this.processLiveInitialActions();
|
|
12667
|
+
}
|
|
12668
|
+
}
|
|
12024
12669
|
ngOnDestroy() {
|
|
12025
12670
|
// Clean up timeouts to prevent memory leaks
|
|
12026
12671
|
if (this.requestSummaryCopiedTimeout) {
|
|
@@ -12038,6 +12683,163 @@ class ApiStepComponent extends BaseStepComponent {
|
|
|
12038
12683
|
if (this.responseBodyCopiedTimeout) {
|
|
12039
12684
|
clearTimeout(this.responseBodyCopiedTimeout);
|
|
12040
12685
|
}
|
|
12686
|
+
this.clearCountdownTimer();
|
|
12687
|
+
}
|
|
12688
|
+
processLiveInitialActions() {
|
|
12689
|
+
const allInitialActions = (this.initialActions || []);
|
|
12690
|
+
// Reset if initialActions were cleared or replaced with fewer entries
|
|
12691
|
+
if (allInitialActions.length < this.lastProcessedIndex) {
|
|
12692
|
+
this.resetLiveProcessing();
|
|
12693
|
+
}
|
|
12694
|
+
for (let i = this.lastProcessedIndex; i < allInitialActions.length; i++) {
|
|
12695
|
+
const action = allInitialActions[i];
|
|
12696
|
+
const uiType = action?.uiType || action?.type || '';
|
|
12697
|
+
const status = (action?.status || '').toLowerCase();
|
|
12698
|
+
if (uiType === 'WAIT_FOR_LOCATOR') {
|
|
12699
|
+
// Create a single grouped entry with a countdown; absorbs FIND_LOCATOR and LOCATOR_FOUND
|
|
12700
|
+
const timeoutSeconds = typeof action.value === 'number'
|
|
12701
|
+
? action.value
|
|
12702
|
+
: (action.value ? parseFloat(action.value) : 30);
|
|
12703
|
+
this.clearCountdownTimer();
|
|
12704
|
+
this.waitLocatorGroupEntry = {
|
|
12705
|
+
...action,
|
|
12706
|
+
remainingSeconds: timeoutSeconds,
|
|
12707
|
+
status: 'running'
|
|
12708
|
+
};
|
|
12709
|
+
this.processedInitialActions.push(this.waitLocatorGroupEntry);
|
|
12710
|
+
// Tick down every second
|
|
12711
|
+
this.countdownIntervalId = setInterval(() => {
|
|
12712
|
+
if (this.waitLocatorGroupEntry) {
|
|
12713
|
+
this.waitLocatorGroupEntry.remainingSeconds = Math.max(0, this.waitLocatorGroupEntry.remainingSeconds - 1);
|
|
12714
|
+
if (this.waitLocatorGroupEntry.remainingSeconds <= 0) {
|
|
12715
|
+
this.waitLocatorGroupEntry.status = 'failed';
|
|
12716
|
+
this.waitLocatorGroupEntry.remainingSeconds = null;
|
|
12717
|
+
this.clearCountdownTimer();
|
|
12718
|
+
this.waitLocatorGroupEntry = null;
|
|
12719
|
+
}
|
|
12720
|
+
}
|
|
12721
|
+
}, 1000);
|
|
12722
|
+
}
|
|
12723
|
+
else if (uiType === 'FIND_LOCATOR') {
|
|
12724
|
+
if (status === 'failed' || status === 'failure') {
|
|
12725
|
+
// Abort countdown, replace group entry with this failed log
|
|
12726
|
+
if (this.waitLocatorGroupEntry) {
|
|
12727
|
+
this.processedInitialActions = this.processedInitialActions.filter(entry => entry !== this.waitLocatorGroupEntry);
|
|
12728
|
+
this.clearCountdownTimer();
|
|
12729
|
+
this.waitLocatorGroupEntry = null;
|
|
12730
|
+
}
|
|
12731
|
+
this.processedInitialActions.push({ ...action, status: 'failed' });
|
|
12732
|
+
}
|
|
12733
|
+
else if (this.waitLocatorGroupEntry) {
|
|
12734
|
+
// Update the single group entry's text so the user sees progress
|
|
12735
|
+
const newText = action.description || action.text || action.title;
|
|
12736
|
+
if (newText)
|
|
12737
|
+
this.waitLocatorGroupEntry.description = newText;
|
|
12738
|
+
}
|
|
12739
|
+
}
|
|
12740
|
+
else if (uiType === 'LOCATOR_FOUND') {
|
|
12741
|
+
if (status === 'failed' || status === 'failure') {
|
|
12742
|
+
// Abort countdown, replace group entry with this failed log
|
|
12743
|
+
if (this.waitLocatorGroupEntry) {
|
|
12744
|
+
this.processedInitialActions = this.processedInitialActions.filter(entry => entry !== this.waitLocatorGroupEntry);
|
|
12745
|
+
this.clearCountdownTimer();
|
|
12746
|
+
this.waitLocatorGroupEntry = null;
|
|
12747
|
+
}
|
|
12748
|
+
this.processedInitialActions.push({ ...action, status: 'failed' });
|
|
12749
|
+
}
|
|
12750
|
+
else {
|
|
12751
|
+
// Sequence complete – update group entry to show LOCATOR_FOUND text as success
|
|
12752
|
+
if (this.waitLocatorGroupEntry) {
|
|
12753
|
+
const newText = action.description || action.text || action.title;
|
|
12754
|
+
if (newText)
|
|
12755
|
+
this.waitLocatorGroupEntry.description = newText;
|
|
12756
|
+
this.waitLocatorGroupEntry.status = 'success';
|
|
12757
|
+
this.waitLocatorGroupEntry.remainingSeconds = null;
|
|
12758
|
+
this.clearCountdownTimer();
|
|
12759
|
+
this.waitLocatorGroupEntry = null;
|
|
12760
|
+
}
|
|
12761
|
+
else {
|
|
12762
|
+
// No active group – push LOCATOR_FOUND normally
|
|
12763
|
+
this.processedInitialActions.push({ ...action });
|
|
12764
|
+
}
|
|
12765
|
+
}
|
|
12766
|
+
}
|
|
12767
|
+
else if (uiType === 'AI_AUTO_HEAL') {
|
|
12768
|
+
// Add single loading entry; will be replaced by AI_AUTO_HEAL_SUCCESS or AI_AUTO_HEAL_FAILED
|
|
12769
|
+
this.aiAutoHealGroupEntry = {
|
|
12770
|
+
...action,
|
|
12771
|
+
description: action.description || action.text || 'AI auto-heal started',
|
|
12772
|
+
status: 'running',
|
|
12773
|
+
uiType: 'AI_AUTO_HEAL'
|
|
12774
|
+
};
|
|
12775
|
+
this.processedInitialActions.push(this.aiAutoHealGroupEntry);
|
|
12776
|
+
}
|
|
12777
|
+
else if (uiType === 'AI_AUTO_HEAL_SUCCESS' || uiType === 'AI_AUTO_HEAL_FAILED') {
|
|
12778
|
+
// Remove loading entry and add TWO separate entries: value and reasoning (like AI_ANSWER)
|
|
12779
|
+
if (this.aiAutoHealGroupEntry) {
|
|
12780
|
+
this.processedInitialActions = this.processedInitialActions.filter(entry => entry !== this.aiAutoHealGroupEntry);
|
|
12781
|
+
this.aiAutoHealGroupEntry = null;
|
|
12782
|
+
}
|
|
12783
|
+
const isSuccess = uiType === 'AI_AUTO_HEAL_SUCCESS';
|
|
12784
|
+
const value = action.value ?? action.text ?? '';
|
|
12785
|
+
const reasoning = action.reasoning ?? action.Reasoning ?? '';
|
|
12786
|
+
const baseDuration = action.duration || 0;
|
|
12787
|
+
const finalStatus = isSuccess ? 'success' : 'failed';
|
|
12788
|
+
// First entry: value/description
|
|
12789
|
+
const valueDescription = action.text || action.description || (isSuccess
|
|
12790
|
+
? `AI auto-heal successful. New locator: ${value}`
|
|
12791
|
+
: `AI auto-heal failed for element: ${value}`);
|
|
12792
|
+
this.processedInitialActions.push({
|
|
12793
|
+
...action,
|
|
12794
|
+
description: valueDescription,
|
|
12795
|
+
value: value,
|
|
12796
|
+
reasoning: null,
|
|
12797
|
+
status: finalStatus,
|
|
12798
|
+
uiType: 'AI_AUTO_HEAL_VALUE',
|
|
12799
|
+
type: 'AI_AUTO_HEAL_VALUE',
|
|
12800
|
+
duration: baseDuration,
|
|
12801
|
+
isAiAutoHealResult: true
|
|
12802
|
+
});
|
|
12803
|
+
// Second entry: reasoning (only if present)
|
|
12804
|
+
if (reasoning) {
|
|
12805
|
+
this.processedInitialActions.push({
|
|
12806
|
+
...action,
|
|
12807
|
+
description: reasoning,
|
|
12808
|
+
value: null,
|
|
12809
|
+
reasoning: reasoning,
|
|
12810
|
+
status: finalStatus,
|
|
12811
|
+
uiType: 'AI_AUTO_HEAL_REASONING',
|
|
12812
|
+
type: 'AI_AUTO_HEAL_REASONING',
|
|
12813
|
+
duration: baseDuration,
|
|
12814
|
+
isAiAutoHealResult: true
|
|
12815
|
+
});
|
|
12816
|
+
}
|
|
12817
|
+
}
|
|
12818
|
+
else {
|
|
12819
|
+
// Any failed log while a countdown is active – resolve it as failed
|
|
12820
|
+
if ((status === 'failed' || status === 'failure') && this.waitLocatorGroupEntry) {
|
|
12821
|
+
this.waitLocatorGroupEntry.status = 'failed';
|
|
12822
|
+
this.waitLocatorGroupEntry.remainingSeconds = null;
|
|
12823
|
+
this.clearCountdownTimer();
|
|
12824
|
+
this.waitLocatorGroupEntry = null;
|
|
12825
|
+
}
|
|
12826
|
+
this.processedInitialActions.push(action);
|
|
12827
|
+
}
|
|
12828
|
+
}
|
|
12829
|
+
this.lastProcessedIndex = allInitialActions.length;
|
|
12830
|
+
}
|
|
12831
|
+
resetLiveProcessing() {
|
|
12832
|
+
this.clearCountdownTimer();
|
|
12833
|
+
this.processedInitialActions = [];
|
|
12834
|
+
this.lastProcessedIndex = 0;
|
|
12835
|
+
this.waitLocatorGroupEntry = null;
|
|
12836
|
+
this.aiAutoHealGroupEntry = null;
|
|
12837
|
+
}
|
|
12838
|
+
clearCountdownTimer() {
|
|
12839
|
+
if (this.countdownIntervalId !== null) {
|
|
12840
|
+
clearInterval(this.countdownIntervalId);
|
|
12841
|
+
this.countdownIntervalId = null;
|
|
12842
|
+
}
|
|
12041
12843
|
}
|
|
12042
12844
|
onJumpToTimestamp(event) {
|
|
12043
12845
|
event.stopPropagation();
|
|
@@ -12051,12 +12853,60 @@ class ApiStepComponent extends BaseStepComponent {
|
|
|
12051
12853
|
}
|
|
12052
12854
|
}
|
|
12053
12855
|
}
|
|
12856
|
+
processInitialActionsForRunResult() {
|
|
12857
|
+
const allInitialActions = (this.initialActions || []);
|
|
12858
|
+
this.processedInitialActionsForRunResult = [];
|
|
12859
|
+
for (const action of allInitialActions) {
|
|
12860
|
+
const uiType = action?.uiType || action?.type || '';
|
|
12861
|
+
// Split AI_AUTO_HEAL_SUCCESS/FAILED into two entries
|
|
12862
|
+
if (uiType === 'AI_AUTO_HEAL_SUCCESS' || uiType === 'AI_AUTO_HEAL_FAILED') {
|
|
12863
|
+
const isSuccess = uiType === 'AI_AUTO_HEAL_SUCCESS';
|
|
12864
|
+
const value = action.value ?? action.text ?? '';
|
|
12865
|
+
const reasoning = action.reasoning ?? action.Reasoning ?? '';
|
|
12866
|
+
const baseDuration = action.duration || 0;
|
|
12867
|
+
const finalStatus = isSuccess ? 'success' : 'failed';
|
|
12868
|
+
// First entry: value/description
|
|
12869
|
+
const valueDescription = (isSuccess
|
|
12870
|
+
? `AI auto-heal successful. New locator: ${value}`
|
|
12871
|
+
: `AI auto-heal failed for element: ${value}`);
|
|
12872
|
+
this.processedInitialActionsForRunResult.push({
|
|
12873
|
+
...action,
|
|
12874
|
+
description: valueDescription,
|
|
12875
|
+
value: value,
|
|
12876
|
+
reasoning: null,
|
|
12877
|
+
status: finalStatus,
|
|
12878
|
+
uiType: 'AI_AUTO_HEAL_VALUE',
|
|
12879
|
+
type: 'AI_AUTO_HEAL_VALUE',
|
|
12880
|
+
duration: baseDuration,
|
|
12881
|
+
isAiAutoHealResult: true
|
|
12882
|
+
});
|
|
12883
|
+
// Second entry: reasoning (only if present)
|
|
12884
|
+
if (reasoning) {
|
|
12885
|
+
this.processedInitialActionsForRunResult.push({
|
|
12886
|
+
...action,
|
|
12887
|
+
description: reasoning,
|
|
12888
|
+
value: null,
|
|
12889
|
+
reasoning: reasoning,
|
|
12890
|
+
status: finalStatus,
|
|
12891
|
+
uiType: 'AI_AUTO_HEAL_REASONING',
|
|
12892
|
+
type: 'AI_AUTO_HEAL_REASONING',
|
|
12893
|
+
duration: baseDuration,
|
|
12894
|
+
isAiAutoHealResult: true
|
|
12895
|
+
});
|
|
12896
|
+
}
|
|
12897
|
+
}
|
|
12898
|
+
else {
|
|
12899
|
+
// All other logs pass through as-is
|
|
12900
|
+
this.processedInitialActionsForRunResult.push(action);
|
|
12901
|
+
}
|
|
12902
|
+
}
|
|
12903
|
+
}
|
|
12054
12904
|
}
|
|
12055
12905
|
ApiStepComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ApiStepComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
12056
|
-
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"] }] });
|
|
12906
|
+
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"] }] });
|
|
12057
12907
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ApiStepComponent, decorators: [{
|
|
12058
12908
|
type: Component,
|
|
12059
|
-
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: [] }]
|
|
12909
|
+
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: [] }]
|
|
12060
12910
|
}], propDecorators: { id: [{
|
|
12061
12911
|
type: Input
|
|
12062
12912
|
}], testStepResultId: [{
|
|
@@ -12487,6 +13337,13 @@ class LiveExecutionStepComponent extends BaseStepComponent {
|
|
|
12487
13337
|
this.stepMoreMenuOptions = DEFAULT_STEP_MORE_MENU_OPTIONS;
|
|
12488
13338
|
this.subSteps = [];
|
|
12489
13339
|
this.userManuallyClosed = false;
|
|
13340
|
+
// Processed sub-steps for WAIT_FOR_LOCATOR countdown grouping
|
|
13341
|
+
this.processedSubSteps = [];
|
|
13342
|
+
this.lastProcessedIndex = 0;
|
|
13343
|
+
this.waitLocatorGroupEntry = null;
|
|
13344
|
+
this.countdownIntervalId = null;
|
|
13345
|
+
// AI_AUTO_HEAL grouping: show loading until AI_AUTO_HEAL_SUCCESS or AI_AUTO_HEAL_FAILED
|
|
13346
|
+
this.aiAutoHealGroupEntry = null;
|
|
12490
13347
|
}
|
|
12491
13348
|
/** Show debug icon only when this step has no child steps (leaf step: always show when isDebug). */
|
|
12492
13349
|
get showDebugIcon() {
|
|
@@ -12509,6 +13366,10 @@ class LiveExecutionStepComponent extends BaseStepComponent {
|
|
|
12509
13366
|
super.ngOnInit();
|
|
12510
13367
|
// Initialize previous status
|
|
12511
13368
|
this.previousStatus = this.status;
|
|
13369
|
+
// Process any subSteps that were passed at init time
|
|
13370
|
+
if (this.subSteps && this.subSteps.length > 0) {
|
|
13371
|
+
this.processLiveSubSteps();
|
|
13372
|
+
}
|
|
12512
13373
|
// Auto-expand if step is running and has subSteps on init
|
|
12513
13374
|
if (this.status === 'running' && this.hasSubSteps && !this.isExpanded) {
|
|
12514
13375
|
this.autoExpand();
|
|
@@ -12523,6 +13384,8 @@ class LiveExecutionStepComponent extends BaseStepComponent {
|
|
|
12523
13384
|
if (this.config) {
|
|
12524
13385
|
this.config.subSteps = this.subSteps || [];
|
|
12525
13386
|
}
|
|
13387
|
+
// Process incoming subSteps for WAIT_FOR_LOCATOR grouping
|
|
13388
|
+
this.processLiveSubSteps();
|
|
12526
13389
|
// Auto-expand if step is running and new subSteps are added (logs coming in)
|
|
12527
13390
|
if (!changes['subSteps'].firstChange &&
|
|
12528
13391
|
this.status === 'running' &&
|
|
@@ -12561,6 +13424,12 @@ class LiveExecutionStepComponent extends BaseStepComponent {
|
|
|
12561
13424
|
this.config.stepDeleted = changes['stepDeleted'].currentValue;
|
|
12562
13425
|
}
|
|
12563
13426
|
}
|
|
13427
|
+
ngDoCheck() {
|
|
13428
|
+
const currentLength = (this.subSteps || []).length;
|
|
13429
|
+
if (currentLength !== this.lastProcessedIndex) {
|
|
13430
|
+
this.processLiveSubSteps();
|
|
13431
|
+
}
|
|
13432
|
+
}
|
|
12564
13433
|
onDebugPointClick(event) {
|
|
12565
13434
|
event.preventDefault();
|
|
12566
13435
|
event.stopPropagation();
|
|
@@ -12585,7 +13454,7 @@ class LiveExecutionStepComponent extends BaseStepComponent {
|
|
|
12585
13454
|
}
|
|
12586
13455
|
}
|
|
12587
13456
|
get hasSubSteps() {
|
|
12588
|
-
return this.
|
|
13457
|
+
return this.processedSubSteps && this.processedSubSteps.length > 0;
|
|
12589
13458
|
}
|
|
12590
13459
|
trackBySubStepId(index, subStep) {
|
|
12591
13460
|
return subStep.id;
|
|
@@ -12605,12 +13474,180 @@ class LiveExecutionStepComponent extends BaseStepComponent {
|
|
|
12605
13474
|
event.stopPropagation();
|
|
12606
13475
|
this.stepMoreOptionSelect.emit(option);
|
|
12607
13476
|
}
|
|
13477
|
+
ngOnDestroy() {
|
|
13478
|
+
this.clearCountdownTimer();
|
|
13479
|
+
}
|
|
13480
|
+
processLiveSubSteps() {
|
|
13481
|
+
const allSubSteps = (this.subSteps || []);
|
|
13482
|
+
// Reset if subSteps were cleared or replaced with fewer entries
|
|
13483
|
+
if (allSubSteps.length < this.lastProcessedIndex) {
|
|
13484
|
+
this.resetLiveProcessing();
|
|
13485
|
+
}
|
|
13486
|
+
for (let i = this.lastProcessedIndex; i < allSubSteps.length; i++) {
|
|
13487
|
+
const subStep = allSubSteps[i];
|
|
13488
|
+
const uiType = subStep?.uiType || subStep?.type || '';
|
|
13489
|
+
const status = (subStep?.status || '').toLowerCase();
|
|
13490
|
+
if (uiType === 'WAIT_FOR_LOCATOR') {
|
|
13491
|
+
// Create a single grouped entry with a countdown; absorbs FIND_LOCATOR and LOCATOR_FOUND
|
|
13492
|
+
const timeoutSeconds = typeof subStep.value === 'number'
|
|
13493
|
+
? subStep.value
|
|
13494
|
+
: (subStep.value ? parseFloat(subStep.value) : 30);
|
|
13495
|
+
this.clearCountdownTimer();
|
|
13496
|
+
this.waitLocatorGroupEntry = {
|
|
13497
|
+
...subStep,
|
|
13498
|
+
isRunning: true,
|
|
13499
|
+
remainingSeconds: timeoutSeconds,
|
|
13500
|
+
status: 'pending'
|
|
13501
|
+
};
|
|
13502
|
+
this.processedSubSteps.push(this.waitLocatorGroupEntry);
|
|
13503
|
+
// Tick down every second
|
|
13504
|
+
this.countdownIntervalId = setInterval(() => {
|
|
13505
|
+
if (this.waitLocatorGroupEntry) {
|
|
13506
|
+
this.waitLocatorGroupEntry.remainingSeconds = Math.max(0, this.waitLocatorGroupEntry.remainingSeconds - 1);
|
|
13507
|
+
if (this.waitLocatorGroupEntry.remainingSeconds <= 0) {
|
|
13508
|
+
this.waitLocatorGroupEntry.isRunning = false;
|
|
13509
|
+
this.waitLocatorGroupEntry.status = 'failed';
|
|
13510
|
+
this.waitLocatorGroupEntry.remainingSeconds = null;
|
|
13511
|
+
this.clearCountdownTimer();
|
|
13512
|
+
this.waitLocatorGroupEntry = null;
|
|
13513
|
+
}
|
|
13514
|
+
}
|
|
13515
|
+
}, 1000);
|
|
13516
|
+
}
|
|
13517
|
+
else if (uiType === 'FIND_LOCATOR') {
|
|
13518
|
+
if (status === 'failed' || status === 'failure') {
|
|
13519
|
+
// Abort countdown, replace group entry with this failed log
|
|
13520
|
+
if (this.waitLocatorGroupEntry) {
|
|
13521
|
+
this.processedSubSteps = this.processedSubSteps.filter(entry => entry !== this.waitLocatorGroupEntry);
|
|
13522
|
+
this.clearCountdownTimer();
|
|
13523
|
+
this.waitLocatorGroupEntry = null;
|
|
13524
|
+
}
|
|
13525
|
+
this.processedSubSteps.push({ ...subStep, isRunning: false, status: 'failed' });
|
|
13526
|
+
}
|
|
13527
|
+
else if (this.waitLocatorGroupEntry) {
|
|
13528
|
+
// Update the single group entry's text so the user sees progress
|
|
13529
|
+
const newText = subStep.text || subStep.description || subStep.title;
|
|
13530
|
+
if (newText)
|
|
13531
|
+
this.waitLocatorGroupEntry.text = newText;
|
|
13532
|
+
}
|
|
13533
|
+
}
|
|
13534
|
+
else if (uiType === 'LOCATOR_FOUND') {
|
|
13535
|
+
if (status === 'failed' || status === 'failure') {
|
|
13536
|
+
// Abort countdown, replace group entry with this failed log
|
|
13537
|
+
if (this.waitLocatorGroupEntry) {
|
|
13538
|
+
this.processedSubSteps = this.processedSubSteps.filter(entry => entry !== this.waitLocatorGroupEntry);
|
|
13539
|
+
this.clearCountdownTimer();
|
|
13540
|
+
this.waitLocatorGroupEntry = null;
|
|
13541
|
+
}
|
|
13542
|
+
this.processedSubSteps.push({ ...subStep, isRunning: false, status: 'failed' });
|
|
13543
|
+
}
|
|
13544
|
+
else {
|
|
13545
|
+
// Sequence complete – update the group entry to show LOCATOR_FOUND text as success
|
|
13546
|
+
if (this.waitLocatorGroupEntry) {
|
|
13547
|
+
const newText = subStep.text || subStep.description || subStep.title;
|
|
13548
|
+
if (newText)
|
|
13549
|
+
this.waitLocatorGroupEntry.text = newText;
|
|
13550
|
+
this.waitLocatorGroupEntry.isRunning = false;
|
|
13551
|
+
this.waitLocatorGroupEntry.status = 'success';
|
|
13552
|
+
this.waitLocatorGroupEntry.remainingSeconds = null;
|
|
13553
|
+
this.clearCountdownTimer();
|
|
13554
|
+
this.waitLocatorGroupEntry = null;
|
|
13555
|
+
}
|
|
13556
|
+
else {
|
|
13557
|
+
// No active group – just push LOCATOR_FOUND normally
|
|
13558
|
+
this.processedSubSteps.push({ ...subStep, isRunning: false });
|
|
13559
|
+
}
|
|
13560
|
+
}
|
|
13561
|
+
}
|
|
13562
|
+
else if (uiType === 'AI_AUTO_HEAL') {
|
|
13563
|
+
// Add single loading entry; will be replaced by AI_AUTO_HEAL_SUCCESS or AI_AUTO_HEAL_FAILED
|
|
13564
|
+
this.aiAutoHealGroupEntry = {
|
|
13565
|
+
...subStep,
|
|
13566
|
+
text: subStep.text || subStep.description || 'AI auto-heal started',
|
|
13567
|
+
isRunning: true,
|
|
13568
|
+
status: 'pending',
|
|
13569
|
+
uiType: 'AI_AUTO_HEAL'
|
|
13570
|
+
};
|
|
13571
|
+
this.processedSubSteps.push(this.aiAutoHealGroupEntry);
|
|
13572
|
+
}
|
|
13573
|
+
else if (uiType === 'AI_AUTO_HEAL_SUCCESS' || uiType === 'AI_AUTO_HEAL_FAILED') {
|
|
13574
|
+
// Remove loading entry and add TWO separate entries: value and reasoning (like AI_ANSWER)
|
|
13575
|
+
if (this.aiAutoHealGroupEntry) {
|
|
13576
|
+
this.processedSubSteps = this.processedSubSteps.filter(entry => entry !== this.aiAutoHealGroupEntry);
|
|
13577
|
+
this.aiAutoHealGroupEntry = null;
|
|
13578
|
+
}
|
|
13579
|
+
const isSuccess = uiType === 'AI_AUTO_HEAL_SUCCESS';
|
|
13580
|
+
const value = subStep.value ?? subStep.text ?? '';
|
|
13581
|
+
const reasoning = subStep.reasoning ?? subStep.Reasoning ?? '';
|
|
13582
|
+
const baseDuration = subStep.duration || 0;
|
|
13583
|
+
const finalStatus = isSuccess ? 'success' : 'failed';
|
|
13584
|
+
// First entry: value/description
|
|
13585
|
+
const valueDescription = subStep.text || subStep.description || (isSuccess
|
|
13586
|
+
? `AI auto-heal successful. New locator: ${value}`
|
|
13587
|
+
: `AI auto-heal failed for element: ${value}`);
|
|
13588
|
+
this.processedSubSteps.push({
|
|
13589
|
+
...subStep,
|
|
13590
|
+
text: valueDescription,
|
|
13591
|
+
description: valueDescription,
|
|
13592
|
+
value: value,
|
|
13593
|
+
reasoning: null,
|
|
13594
|
+
isRunning: false,
|
|
13595
|
+
status: finalStatus,
|
|
13596
|
+
uiType: 'AI_AUTO_HEAL_VALUE',
|
|
13597
|
+
type: 'AI_AUTO_HEAL_VALUE',
|
|
13598
|
+
duration: baseDuration,
|
|
13599
|
+
isAiAutoHealResult: true
|
|
13600
|
+
});
|
|
13601
|
+
// Second entry: reasoning (only if present)
|
|
13602
|
+
if (reasoning) {
|
|
13603
|
+
this.processedSubSteps.push({
|
|
13604
|
+
...subStep,
|
|
13605
|
+
text: reasoning,
|
|
13606
|
+
description: reasoning,
|
|
13607
|
+
value: null,
|
|
13608
|
+
reasoning: reasoning,
|
|
13609
|
+
isRunning: false,
|
|
13610
|
+
status: finalStatus,
|
|
13611
|
+
uiType: 'AI_AUTO_HEAL_REASONING',
|
|
13612
|
+
type: 'AI_AUTO_HEAL_REASONING',
|
|
13613
|
+
duration: baseDuration,
|
|
13614
|
+
isAiAutoHealResult: true
|
|
13615
|
+
});
|
|
13616
|
+
}
|
|
13617
|
+
}
|
|
13618
|
+
else {
|
|
13619
|
+
// Any failed log while a countdown is active – resolve it as failed
|
|
13620
|
+
if ((status === 'failed' || status === 'failure') && this.waitLocatorGroupEntry) {
|
|
13621
|
+
this.waitLocatorGroupEntry.isRunning = false;
|
|
13622
|
+
this.waitLocatorGroupEntry.status = 'failed';
|
|
13623
|
+
this.waitLocatorGroupEntry.remainingSeconds = null;
|
|
13624
|
+
this.clearCountdownTimer();
|
|
13625
|
+
this.waitLocatorGroupEntry = null;
|
|
13626
|
+
}
|
|
13627
|
+
this.processedSubSteps.push(subStep);
|
|
13628
|
+
}
|
|
13629
|
+
}
|
|
13630
|
+
this.lastProcessedIndex = allSubSteps.length;
|
|
13631
|
+
}
|
|
13632
|
+
resetLiveProcessing() {
|
|
13633
|
+
this.clearCountdownTimer();
|
|
13634
|
+
this.processedSubSteps = [];
|
|
13635
|
+
this.lastProcessedIndex = 0;
|
|
13636
|
+
this.waitLocatorGroupEntry = null;
|
|
13637
|
+
this.aiAutoHealGroupEntry = null;
|
|
13638
|
+
}
|
|
13639
|
+
clearCountdownTimer() {
|
|
13640
|
+
if (this.countdownIntervalId !== null) {
|
|
13641
|
+
clearInterval(this.countdownIntervalId);
|
|
13642
|
+
this.countdownIntervalId = null;
|
|
13643
|
+
}
|
|
13644
|
+
}
|
|
12608
13645
|
}
|
|
12609
13646
|
LiveExecutionStepComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: LiveExecutionStepComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
12610
|
-
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"] }] });
|
|
13647
|
+
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"] }] });
|
|
12611
13648
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: LiveExecutionStepComponent, decorators: [{
|
|
12612
13649
|
type: Component,
|
|
12613
|
-
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: [] }]
|
|
13650
|
+
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: [] }]
|
|
12614
13651
|
}], propDecorators: { id: [{
|
|
12615
13652
|
type: Input
|
|
12616
13653
|
}], testStepResultId: [{
|
|
@@ -29316,6 +30353,7 @@ UiKitModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "1
|
|
|
29316
30353
|
FileDownloadStepComponent,
|
|
29317
30354
|
DocumentVerificationStepComponent,
|
|
29318
30355
|
LiveExecutionStepComponent,
|
|
30356
|
+
AiLogsWithReasoningComponent,
|
|
29319
30357
|
JumpToStepModalComponent,
|
|
29320
30358
|
BreakpointsModalComponent,
|
|
29321
30359
|
MainStepCollapseComponent,
|
|
@@ -29459,6 +30497,7 @@ UiKitModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "1
|
|
|
29459
30497
|
FileDownloadStepComponent,
|
|
29460
30498
|
DocumentVerificationStepComponent,
|
|
29461
30499
|
LiveExecutionStepComponent,
|
|
30500
|
+
AiLogsWithReasoningComponent,
|
|
29462
30501
|
JumpToStepModalComponent,
|
|
29463
30502
|
BreakpointsModalComponent,
|
|
29464
30503
|
MainStepCollapseComponent,
|
|
@@ -29649,6 +30688,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
29649
30688
|
FileDownloadStepComponent,
|
|
29650
30689
|
DocumentVerificationStepComponent,
|
|
29651
30690
|
LiveExecutionStepComponent,
|
|
30691
|
+
AiLogsWithReasoningComponent,
|
|
29652
30692
|
JumpToStepModalComponent,
|
|
29653
30693
|
BreakpointsModalComponent,
|
|
29654
30694
|
MainStepCollapseComponent,
|
|
@@ -29798,6 +30838,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
29798
30838
|
FileDownloadStepComponent,
|
|
29799
30839
|
DocumentVerificationStepComponent,
|
|
29800
30840
|
LiveExecutionStepComponent,
|
|
30841
|
+
AiLogsWithReasoningComponent,
|
|
29801
30842
|
JumpToStepModalComponent,
|
|
29802
30843
|
BreakpointsModalComponent,
|
|
29803
30844
|
MainStepCollapseComponent,
|
|
@@ -30539,5 +31580,5 @@ function buildTestCaseDetailsFromApi(data, options) {
|
|
|
30539
31580
|
* Generated bundle index. Do not edit.
|
|
30540
31581
|
*/
|
|
30541
31582
|
|
|
30542
|
-
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 };
|
|
31583
|
+
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 };
|
|
30543
31584
|
//# sourceMappingURL=cqa-lib-cqa-ui.mjs.map
|