@memberjunction/ng-core-entity-forms 2.129.0 → 2.130.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/dist/lib/custom/Tests/entity-link-pill.component.d.ts +44 -0
  2. package/dist/lib/custom/Tests/entity-link-pill.component.d.ts.map +1 -0
  3. package/dist/lib/custom/Tests/entity-link-pill.component.js +124 -0
  4. package/dist/lib/custom/Tests/entity-link-pill.component.js.map +1 -0
  5. package/dist/lib/custom/Tests/test-form.component.d.ts +96 -9
  6. package/dist/lib/custom/Tests/test-form.component.d.ts.map +1 -1
  7. package/dist/lib/custom/Tests/test-form.component.js +1529 -277
  8. package/dist/lib/custom/Tests/test-form.component.js.map +1 -1
  9. package/dist/lib/custom/Tests/test-run-form.component.d.ts +50 -9
  10. package/dist/lib/custom/Tests/test-run-form.component.d.ts.map +1 -1
  11. package/dist/lib/custom/Tests/test-run-form.component.js +1079 -426
  12. package/dist/lib/custom/Tests/test-run-form.component.js.map +1 -1
  13. package/dist/lib/custom/Tests/test-suite-form.component.d.ts +228 -5
  14. package/dist/lib/custom/Tests/test-suite-form.component.d.ts.map +1 -1
  15. package/dist/lib/custom/Tests/test-suite-form.component.js +3309 -201
  16. package/dist/lib/custom/Tests/test-suite-form.component.js.map +1 -1
  17. package/dist/lib/custom/Tests/test-suite-run-form.component.d.ts +88 -3
  18. package/dist/lib/custom/Tests/test-suite-run-form.component.d.ts.map +1 -1
  19. package/dist/lib/custom/Tests/test-suite-run-form.component.js +1976 -262
  20. package/dist/lib/custom/Tests/test-suite-run-form.component.js.map +1 -1
  21. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.d.ts +9 -2
  22. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.d.ts.map +1 -1
  23. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js +275 -244
  24. package/dist/lib/custom/ai-agent-run/ai-agent-run.component.js.map +1 -1
  25. package/dist/lib/custom/custom-forms.module.d.ts +27 -26
  26. package/dist/lib/custom/custom-forms.module.d.ts.map +1 -1
  27. package/dist/lib/custom/custom-forms.module.js +9 -3
  28. package/dist/lib/custom/custom-forms.module.js.map +1 -1
  29. package/dist/lib/generated/Entities/AIAgent/aiagent.form.component.d.ts.map +1 -1
  30. package/dist/lib/generated/Entities/AIAgent/aiagent.form.component.js +154 -122
  31. package/dist/lib/generated/Entities/AIAgent/aiagent.form.component.js.map +1 -1
  32. package/dist/lib/generated/Entities/AIAgentModality/aiagentmodality.form.component.d.ts +11 -0
  33. package/dist/lib/generated/Entities/AIAgentModality/aiagentmodality.form.component.d.ts.map +1 -0
  34. package/dist/lib/generated/Entities/AIAgentModality/aiagentmodality.form.component.js +75 -0
  35. package/dist/lib/generated/Entities/AIAgentModality/aiagentmodality.form.component.js.map +1 -0
  36. package/dist/lib/generated/Entities/AIArchitecture/aiarchitecture.form.component.d.ts +11 -0
  37. package/dist/lib/generated/Entities/AIArchitecture/aiarchitecture.form.component.d.ts.map +1 -0
  38. package/dist/lib/generated/Entities/AIArchitecture/aiarchitecture.form.component.js +121 -0
  39. package/dist/lib/generated/Entities/AIArchitecture/aiarchitecture.form.component.js.map +1 -0
  40. package/dist/lib/generated/Entities/AIConfiguration/aiconfiguration.form.component.d.ts.map +1 -1
  41. package/dist/lib/generated/Entities/AIConfiguration/aiconfiguration.form.component.js +77 -41
  42. package/dist/lib/generated/Entities/AIConfiguration/aiconfiguration.form.component.js.map +1 -1
  43. package/dist/lib/generated/Entities/AIModality/aimodality.form.component.d.ts +11 -0
  44. package/dist/lib/generated/Entities/AIModality/aimodality.form.component.d.ts.map +1 -0
  45. package/dist/lib/generated/Entities/AIModality/aimodality.form.component.js +167 -0
  46. package/dist/lib/generated/Entities/AIModality/aimodality.form.component.js.map +1 -0
  47. package/dist/lib/generated/Entities/AIModel/aimodel.form.component.d.ts.map +1 -1
  48. package/dist/lib/generated/Entities/AIModel/aimodel.form.component.js +160 -102
  49. package/dist/lib/generated/Entities/AIModel/aimodel.form.component.js.map +1 -1
  50. package/dist/lib/generated/Entities/AIModelArchitecture/aimodelarchitecture.form.component.d.ts +11 -0
  51. package/dist/lib/generated/Entities/AIModelArchitecture/aimodelarchitecture.form.component.d.ts.map +1 -0
  52. package/dist/lib/generated/Entities/AIModelArchitecture/aimodelarchitecture.form.component.js +73 -0
  53. package/dist/lib/generated/Entities/AIModelArchitecture/aimodelarchitecture.form.component.js.map +1 -0
  54. package/dist/lib/generated/Entities/AIModelModality/aimodelmodality.form.component.d.ts +11 -0
  55. package/dist/lib/generated/Entities/AIModelModality/aimodelmodality.form.component.d.ts.map +1 -0
  56. package/dist/lib/generated/Entities/AIModelModality/aimodelmodality.form.component.js +89 -0
  57. package/dist/lib/generated/Entities/AIModelModality/aimodelmodality.form.component.js.map +1 -0
  58. package/dist/lib/generated/Entities/AIModelType/aimodeltype.form.component.d.ts.map +1 -1
  59. package/dist/lib/generated/Entities/AIModelType/aimodeltype.form.component.js +27 -13
  60. package/dist/lib/generated/Entities/AIModelType/aimodeltype.form.component.js.map +1 -1
  61. package/dist/lib/generated/Entities/ConversationDetail/conversationdetail.form.component.d.ts.map +1 -1
  62. package/dist/lib/generated/Entities/ConversationDetail/conversationdetail.form.component.js +39 -21
  63. package/dist/lib/generated/Entities/ConversationDetail/conversationdetail.form.component.js.map +1 -1
  64. package/dist/lib/generated/Entities/ConversationDetailAttachment/conversationdetailattachment.form.component.d.ts +11 -0
  65. package/dist/lib/generated/Entities/ConversationDetailAttachment/conversationdetailattachment.form.component.d.ts.map +1 -0
  66. package/dist/lib/generated/Entities/ConversationDetailAttachment/conversationdetailattachment.form.component.js +95 -0
  67. package/dist/lib/generated/Entities/ConversationDetailAttachment/conversationdetailattachment.form.component.js.map +1 -0
  68. package/dist/lib/generated/Entities/Entity/entity.form.component.d.ts.map +1 -1
  69. package/dist/lib/generated/Entities/Entity/entity.form.component.js +61 -43
  70. package/dist/lib/generated/Entities/Entity/entity.form.component.js.map +1 -1
  71. package/dist/lib/generated/Entities/File/file.form.component.d.ts.map +1 -1
  72. package/dist/lib/generated/Entities/File/file.form.component.js +22 -4
  73. package/dist/lib/generated/Entities/File/file.form.component.js.map +1 -1
  74. package/dist/lib/generated/Entities/FileStorageProvider/filestorageprovider.form.component.d.ts.map +1 -1
  75. package/dist/lib/generated/Entities/FileStorageProvider/filestorageprovider.form.component.js +40 -4
  76. package/dist/lib/generated/Entities/FileStorageProvider/filestorageprovider.form.component.js.map +1 -1
  77. package/dist/lib/generated/Entities/Test/test.form.component.js +17 -15
  78. package/dist/lib/generated/Entities/Test/test.form.component.js.map +1 -1
  79. package/dist/lib/generated/Entities/TestRun/testrun.form.component.d.ts.map +1 -1
  80. package/dist/lib/generated/Entities/TestRun/testrun.form.component.js +55 -43
  81. package/dist/lib/generated/Entities/TestRun/testrun.form.component.js.map +1 -1
  82. package/dist/lib/generated/Entities/TestRunFeedback/testrunfeedback.form.component.d.ts.map +1 -1
  83. package/dist/lib/generated/Entities/TestRunFeedback/testrunfeedback.form.component.js +9 -15
  84. package/dist/lib/generated/Entities/TestRunFeedback/testrunfeedback.form.component.js.map +1 -1
  85. package/dist/lib/generated/Entities/TestSuite/testsuite.form.component.d.ts.map +1 -1
  86. package/dist/lib/generated/Entities/TestSuite/testsuite.form.component.js +39 -19
  87. package/dist/lib/generated/Entities/TestSuite/testsuite.form.component.js.map +1 -1
  88. package/dist/lib/generated/Entities/TestSuiteRun/testsuiterun.form.component.d.ts.map +1 -1
  89. package/dist/lib/generated/Entities/TestSuiteRun/testsuiterun.form.component.js +40 -16
  90. package/dist/lib/generated/Entities/TestSuiteRun/testsuiterun.form.component.js.map +1 -1
  91. package/dist/lib/generated/generated-forms.module.d.ts +145 -134
  92. package/dist/lib/generated/generated-forms.module.d.ts.map +1 -1
  93. package/dist/lib/generated/generated-forms.module.js +168 -87
  94. package/dist/lib/generated/generated-forms.module.js.map +1 -1
  95. package/package.json +28 -27
@@ -4,58 +4,243 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { Component, ChangeDetectionStrategy } from '@angular/core';
8
- import { Subject } from 'rxjs';
7
+ import { Component, ChangeDetectionStrategy, HostListener } from '@angular/core';
8
+ import { Subject, interval } from 'rxjs';
9
+ import { takeUntil } from 'rxjs/operators';
9
10
  import { CompositeKey, Metadata, RunView } from '@memberjunction/core';
10
11
  import { BaseFormComponent } from '@memberjunction/ng-base-forms';
11
12
  import { RegisterClass } from '@memberjunction/global';
12
13
  import { SharedService } from '@memberjunction/ng-shared';
13
14
  import { TestRunFormComponent } from '../../generated/Entities/TestRun/testrun.form.component';
15
+ import { TagsHelper } from '@memberjunction/ng-testing';
16
+ import { createCopyOnlyToolbar } from '@memberjunction/ng-code-editor';
14
17
  import * as i0 from "@angular/core";
15
18
  import * as i1 from "@memberjunction/ng-shared";
16
19
  import * as i2 from "@angular/router";
17
- import * as i3 from "@angular/common";
18
- import * as i4 from "@progress/kendo-angular-buttons";
19
- function TestRunFormComponentExtended_a_3_Template(rf, ctx) { if (rf & 1) {
20
+ import * as i3 from "@memberjunction/ng-testing";
21
+ import * as i4 from "@memberjunction/ng-base-application";
22
+ import * as i5 from "@angular/common";
23
+ import * as i6 from "@angular/forms";
24
+ import * as i7 from "@progress/kendo-angular-buttons";
25
+ import * as i8 from "@memberjunction/ng-code-editor";
26
+ import * as i9 from "./entity-link-pill.component";
27
+ const _c0 = () => [1, 2, 3];
28
+ const _c1 = () => [1, 2];
29
+ const _c2 = () => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
30
+ function TestRunFormComponentExtended_div_1_Template(rf, ctx) { if (rf & 1) {
20
31
  const _r1 = i0.ɵɵgetCurrentView();
21
- i0.ɵɵelementStart(0, "a", 37);
22
- i0.ɵɵlistener("click", function TestRunFormComponentExtended_a_3_Template_a_click_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.openTest()); });
23
- i0.ɵɵelement(1, "i", 8);
32
+ i0.ɵɵelementStart(0, "div", 65);
33
+ i0.ɵɵlistener("click", function TestRunFormComponentExtended_div_1_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.retryLoad()); });
34
+ i0.ɵɵelement(1, "i", 66);
35
+ i0.ɵɵelementStart(2, "span");
36
+ i0.ɵɵtext(3);
37
+ i0.ɵɵelementEnd();
38
+ i0.ɵɵelementStart(4, "button", 67);
39
+ i0.ɵɵelement(5, "i", 21);
40
+ i0.ɵɵtext(6, " Retry ");
41
+ i0.ɵɵelementEnd()();
42
+ } if (rf & 2) {
43
+ const ctx_r1 = i0.ɵɵnextContext();
44
+ i0.ɵɵadvance(3);
45
+ i0.ɵɵtextInterpolate(ctx_r1.error);
46
+ } }
47
+ function TestRunFormComponentExtended_li_10_Template(rf, ctx) { if (rf & 1) {
48
+ const _r3 = i0.ɵɵgetCurrentView();
49
+ i0.ɵɵelementStart(0, "li");
50
+ i0.ɵɵelement(1, "i", 9);
51
+ i0.ɵɵelementStart(2, "a", 4);
52
+ i0.ɵɵlistener("click", function TestRunFormComponentExtended_li_10_Template_a_click_2_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.openTest()); });
53
+ i0.ɵɵelement(3, "i", 68);
54
+ i0.ɵɵelementStart(4, "span", 6);
55
+ i0.ɵɵtext(5);
56
+ i0.ɵɵelementEnd()()();
57
+ } if (rf & 2) {
58
+ const ctx_r1 = i0.ɵɵnextContext();
59
+ i0.ɵɵadvance(5);
60
+ i0.ɵɵtextInterpolate(ctx_r1.test.Name);
61
+ } }
62
+ function TestRunFormComponentExtended_span_27_Template(rf, ctx) { if (rf & 1) {
63
+ i0.ɵɵelementStart(0, "span", 69);
64
+ i0.ɵɵelement(1, "i", 68);
24
65
  i0.ɵɵtext(2);
25
66
  i0.ɵɵelementEnd();
26
67
  } if (rf & 2) {
27
68
  const ctx_r1 = i0.ɵɵnextContext();
28
69
  i0.ɵɵadvance(2);
29
- i0.ɵɵtextInterpolate1(" ", ctx_r1.test.Name, " ");
70
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.test.Type, " ");
71
+ } }
72
+ function TestRunFormComponentExtended_span_28_Template(rf, ctx) { if (rf & 1) {
73
+ i0.ɵɵelementStart(0, "span", 69);
74
+ i0.ɵɵelement(1, "i", 70);
75
+ i0.ɵɵtext(2, " Auto-refreshing ");
76
+ i0.ɵɵelementEnd();
77
+ } }
78
+ function TestRunFormComponentExtended_div_66_Template(rf, ctx) { if (rf & 1) {
79
+ i0.ɵɵelementStart(0, "div", 71);
80
+ i0.ɵɵelement(1, "div", 72);
81
+ i0.ɵɵelementEnd();
82
+ } if (rf & 2) {
83
+ const ctx_r1 = i0.ɵɵnextContext();
84
+ i0.ɵɵadvance();
85
+ i0.ɵɵstyleProp("width", ctx_r1.getScorePercentage(), "%")("background-color", ctx_r1.getStatusColor());
30
86
  } }
31
- function TestRunFormComponentExtended_i_4_Template(rf, ctx) { if (rf & 1) {
32
- i0.ɵɵelement(0, "i", 38);
87
+ function TestRunFormComponentExtended_div_75_Template(rf, ctx) { if (rf & 1) {
88
+ i0.ɵɵelementStart(0, "div", 71);
89
+ i0.ɵɵelement(1, "div", 72);
90
+ i0.ɵɵelementEnd();
91
+ } if (rf & 2) {
92
+ const ctx_r1 = i0.ɵɵnextContext();
93
+ i0.ɵɵadvance();
94
+ i0.ɵɵstyleProp("width", ctx_r1.getPassRatePercentage(), "%")("background-color", ctx_r1.getStatusColor());
33
95
  } }
34
- function TestRunFormComponentExtended_span_18_Template(rf, ctx) { if (rf & 1) {
35
- i0.ɵɵelementStart(0, "span", 39);
96
+ function TestRunFormComponentExtended_div_84_span_1_Template(rf, ctx) { if (rf & 1) {
97
+ i0.ɵɵelementStart(0, "span", 77);
98
+ i0.ɵɵelement(1, "i", 78);
99
+ i0.ɵɵtext(2);
100
+ i0.ɵɵelementEnd();
101
+ } if (rf & 2) {
102
+ const ctx_r1 = i0.ɵɵnextContext(2);
103
+ i0.ɵɵadvance(2);
104
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.record.RunByUser, " ");
105
+ } }
106
+ function TestRunFormComponentExtended_div_84_span_2_Template(rf, ctx) { if (rf & 1) {
107
+ const _r4 = i0.ɵɵgetCurrentView();
108
+ i0.ɵɵelementStart(0, "span", 79);
109
+ i0.ɵɵlistener("click", function TestRunFormComponentExtended_div_84_span_2_Template_span_click_0_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.openTestSuiteRun()); });
110
+ i0.ɵɵelement(1, "i", 80);
111
+ i0.ɵɵtext(2);
112
+ i0.ɵɵelementEnd();
113
+ } if (rf & 2) {
114
+ const ctx_r1 = i0.ɵɵnextContext(2);
115
+ i0.ɵɵadvance(2);
116
+ i0.ɵɵtextInterpolate1(" Part of Suite Run (Seq: ", ctx_r1.record.Sequence, ") ");
117
+ } }
118
+ function TestRunFormComponentExtended_div_84_mj_entity_link_pill_3_Template(rf, ctx) { if (rf & 1) {
119
+ i0.ɵɵelement(0, "mj-entity-link-pill", 81);
120
+ } if (rf & 2) {
121
+ const ctx_r1 = i0.ɵɵnextContext(2);
122
+ i0.ɵɵproperty("entityName", ctx_r1.record.TargetLogEntity)("recordId", ctx_r1.record.TargetLogID);
123
+ } }
124
+ function TestRunFormComponentExtended_div_84_Template(rf, ctx) { if (rf & 1) {
125
+ i0.ɵɵelementStart(0, "div", 73);
126
+ i0.ɵɵtemplate(1, TestRunFormComponentExtended_div_84_span_1_Template, 3, 1, "span", 74)(2, TestRunFormComponentExtended_div_84_span_2_Template, 3, 1, "span", 75)(3, TestRunFormComponentExtended_div_84_mj_entity_link_pill_3_Template, 1, 2, "mj-entity-link-pill", 76);
127
+ i0.ɵɵelementEnd();
128
+ } if (rf & 2) {
129
+ const ctx_r1 = i0.ɵɵnextContext();
130
+ i0.ɵɵadvance();
131
+ i0.ɵɵproperty("ngIf", ctx_r1.record.RunByUser);
132
+ i0.ɵɵadvance();
133
+ i0.ɵɵproperty("ngIf", ctx_r1.testSuiteRun);
134
+ i0.ɵɵadvance();
135
+ i0.ɵɵproperty("ngIf", ctx_r1.record.TargetLogEntityID && ctx_r1.record.TargetLogID);
136
+ } }
137
+ function TestRunFormComponentExtended_div_85_div_4_span_1_Template(rf, ctx) { if (rf & 1) {
138
+ i0.ɵɵelementStart(0, "span", 92);
36
139
  i0.ɵɵtext(1);
37
140
  i0.ɵɵelementEnd();
141
+ } if (rf & 2) {
142
+ const tag_r6 = ctx.$implicit;
143
+ i0.ɵɵadvance();
144
+ i0.ɵɵtextInterpolate(tag_r6);
145
+ } }
146
+ function TestRunFormComponentExtended_div_85_div_4_Template(rf, ctx) { if (rf & 1) {
147
+ i0.ɵɵelementStart(0, "div", 90);
148
+ i0.ɵɵtemplate(1, TestRunFormComponentExtended_div_85_div_4_span_1_Template, 2, 1, "span", 91);
149
+ i0.ɵɵelementEnd();
150
+ } if (rf & 2) {
151
+ const ctx_r1 = i0.ɵɵnextContext(2);
152
+ i0.ɵɵadvance();
153
+ i0.ɵɵproperty("ngForOf", ctx_r1.tags);
154
+ } }
155
+ function TestRunFormComponentExtended_div_85_span_5_Template(rf, ctx) { if (rf & 1) {
156
+ i0.ɵɵelementStart(0, "span", 93);
157
+ i0.ɵɵtext(1, "No tags");
158
+ i0.ɵɵelementEnd();
159
+ } }
160
+ function TestRunFormComponentExtended_div_85_Template(rf, ctx) { if (rf & 1) {
161
+ const _r5 = i0.ɵɵgetCurrentView();
162
+ i0.ɵɵelementStart(0, "div", 82)(1, "div", 83)(2, "span", 84);
163
+ i0.ɵɵelement(3, "i", 85);
164
+ i0.ɵɵelementEnd();
165
+ i0.ɵɵtemplate(4, TestRunFormComponentExtended_div_85_div_4_Template, 2, 1, "div", 86)(5, TestRunFormComponentExtended_div_85_span_5_Template, 2, 0, "span", 87);
166
+ i0.ɵɵelementStart(6, "button", 88);
167
+ i0.ɵɵlistener("click", function TestRunFormComponentExtended_div_85_Template_button_click_6_listener() { i0.ɵɵrestoreView(_r5); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.startEditingTags()); });
168
+ i0.ɵɵelement(7, "i", 89);
169
+ i0.ɵɵtext(8, " Add ");
170
+ i0.ɵɵelementEnd()()();
38
171
  } if (rf & 2) {
39
172
  const ctx_r1 = i0.ɵɵnextContext();
173
+ i0.ɵɵadvance(4);
174
+ i0.ɵɵproperty("ngIf", ctx_r1.tags.length > 0);
40
175
  i0.ɵɵadvance();
41
- i0.ɵɵtextInterpolate(ctx_r1.test.Type);
176
+ i0.ɵɵproperty("ngIf", ctx_r1.tags.length === 0);
42
177
  } }
43
- function TestRunFormComponentExtended_div_63_Template(rf, ctx) { if (rf & 1) {
44
- const _r3 = i0.ɵɵgetCurrentView();
45
- i0.ɵɵelementStart(0, "div", 22)(1, "span", 19);
46
- i0.ɵɵtext(2, "Part of Suite:");
178
+ function TestRunFormComponentExtended_div_86_span_7_Template(rf, ctx) { if (rf & 1) {
179
+ const _r8 = i0.ɵɵgetCurrentView();
180
+ i0.ɵɵelementStart(0, "span", 108);
181
+ i0.ɵɵtext(1);
182
+ i0.ɵɵelementStart(2, "button", 109);
183
+ i0.ɵɵlistener("click", function TestRunFormComponentExtended_div_86_span_7_Template_button_click_2_listener() { const tag_r9 = i0.ɵɵrestoreView(_r8).$implicit; const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.removeTag(tag_r9)); });
184
+ i0.ɵɵelement(3, "i", 110);
185
+ i0.ɵɵelementEnd()();
186
+ } if (rf & 2) {
187
+ const tag_r9 = ctx.$implicit;
188
+ i0.ɵɵadvance();
189
+ i0.ɵɵtextInterpolate1(" ", tag_r9, " ");
190
+ } }
191
+ function TestRunFormComponentExtended_div_86_span_8_Template(rf, ctx) { if (rf & 1) {
192
+ i0.ɵɵelementStart(0, "span", 111);
193
+ i0.ɵɵtext(1, "No tags yet");
47
194
  i0.ɵɵelementEnd();
48
- i0.ɵɵelementStart(3, "a", 37);
49
- i0.ɵɵlistener("click", function TestRunFormComponentExtended_div_63_Template_a_click_3_listener() { i0.ɵɵrestoreView(_r3); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.openTestSuiteRun()); });
50
- i0.ɵɵtext(4);
195
+ } }
196
+ function TestRunFormComponentExtended_div_86_i_15_Template(rf, ctx) { if (rf & 1) {
197
+ i0.ɵɵelement(0, "i", 112);
198
+ } }
199
+ function TestRunFormComponentExtended_div_86_Template(rf, ctx) { if (rf & 1) {
200
+ const _r7 = i0.ɵɵgetCurrentView();
201
+ i0.ɵɵelementStart(0, "div", 94)(1, "div", 95)(2, "span", 96);
202
+ i0.ɵɵelement(3, "i", 85);
203
+ i0.ɵɵtext(4, " Edit Tags");
51
204
  i0.ɵɵelementEnd()();
205
+ i0.ɵɵelementStart(5, "div", 97)(6, "div", 98);
206
+ i0.ɵɵtemplate(7, TestRunFormComponentExtended_div_86_span_7_Template, 4, 1, "span", 99)(8, TestRunFormComponentExtended_div_86_span_8_Template, 2, 0, "span", 100);
207
+ i0.ɵɵelementEnd();
208
+ i0.ɵɵelementStart(9, "div", 101)(10, "input", 102);
209
+ i0.ɵɵtwoWayListener("ngModelChange", function TestRunFormComponentExtended_div_86_Template_input_ngModelChange_10_listener($event) { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r1.newTag, $event) || (ctx_r1.newTag = $event); return i0.ɵɵresetView($event); });
210
+ i0.ɵɵlistener("keyup.enter", function TestRunFormComponentExtended_div_86_Template_input_keyup_enter_10_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.addTag()); });
211
+ i0.ɵɵelementEnd();
212
+ i0.ɵɵelementStart(11, "button", 103);
213
+ i0.ɵɵlistener("click", function TestRunFormComponentExtended_div_86_Template_button_click_11_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.addTag()); });
214
+ i0.ɵɵelement(12, "i", 89);
215
+ i0.ɵɵelementEnd()()();
216
+ i0.ɵɵelementStart(13, "div", 104)(14, "button", 105);
217
+ i0.ɵɵlistener("click", function TestRunFormComponentExtended_div_86_Template_button_click_14_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.saveTags()); });
218
+ i0.ɵɵtemplate(15, TestRunFormComponentExtended_div_86_i_15_Template, 1, 0, "i", 106);
219
+ i0.ɵɵtext(16);
220
+ i0.ɵɵelementEnd();
221
+ i0.ɵɵelementStart(17, "button", 107);
222
+ i0.ɵɵlistener("click", function TestRunFormComponentExtended_div_86_Template_button_click_17_listener() { i0.ɵɵrestoreView(_r7); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.cancelEditingTags()); });
223
+ i0.ɵɵtext(18, "Cancel");
224
+ i0.ɵɵelementEnd()()();
52
225
  } if (rf & 2) {
53
226
  const ctx_r1 = i0.ɵɵnextContext();
54
- i0.ɵɵadvance(4);
55
- i0.ɵɵtextInterpolate2(" ", ctx_r1.testSuiteRun.ID, " (Seq: ", ctx_r1.record.Sequence, ") ");
227
+ i0.ɵɵadvance(7);
228
+ i0.ɵɵproperty("ngForOf", ctx_r1.tags);
229
+ i0.ɵɵadvance();
230
+ i0.ɵɵproperty("ngIf", ctx_r1.tags.length === 0);
231
+ i0.ɵɵadvance(2);
232
+ i0.ɵɵtwoWayProperty("ngModel", ctx_r1.newTag);
233
+ i0.ɵɵadvance();
234
+ i0.ɵɵproperty("disabled", !ctx_r1.newTag.trim());
235
+ i0.ɵɵadvance(3);
236
+ i0.ɵɵproperty("disabled", ctx_r1.savingTags);
237
+ i0.ɵɵadvance();
238
+ i0.ɵɵproperty("ngIf", ctx_r1.savingTags);
239
+ i0.ɵɵadvance();
240
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.savingTags ? "Saving..." : "Save", " ");
56
241
  } }
57
- function TestRunFormComponentExtended_span_78_Template(rf, ctx) { if (rf & 1) {
58
- i0.ɵɵelementStart(0, "span", 40);
242
+ function TestRunFormComponentExtended_span_101_Template(rf, ctx) { if (rf & 1) {
243
+ i0.ɵɵelementStart(0, "span", 113);
59
244
  i0.ɵɵtext(1);
60
245
  i0.ɵɵelementEnd();
61
246
  } if (rf & 2) {
@@ -63,8 +248,8 @@ function TestRunFormComponentExtended_span_78_Template(rf, ctx) { if (rf & 1) {
63
248
  i0.ɵɵadvance();
64
249
  i0.ɵɵtextInterpolate(ctx_r1.aiAgentRuns.length + ctx_r1.aiPromptRuns.length);
65
250
  } }
66
- function TestRunFormComponentExtended_span_83_Template(rf, ctx) { if (rf & 1) {
67
- i0.ɵɵelementStart(0, "span", 40);
251
+ function TestRunFormComponentExtended_span_106_Template(rf, ctx) { if (rf & 1) {
252
+ i0.ɵɵelementStart(0, "span", 113);
68
253
  i0.ɵɵtext(1);
69
254
  i0.ɵɵelementEnd();
70
255
  } if (rf & 2) {
@@ -72,450 +257,585 @@ function TestRunFormComponentExtended_span_83_Template(rf, ctx) { if (rf & 1) {
72
257
  i0.ɵɵadvance();
73
258
  i0.ɵɵtextInterpolate(ctx_r1.feedbacks.length);
74
259
  } }
75
- function TestRunFormComponentExtended_div_85_div_11_div_4_div_8_Template(rf, ctx) { if (rf & 1) {
76
- i0.ɵɵelementStart(0, "div", 62);
260
+ function TestRunFormComponentExtended_button_111_Template(rf, ctx) { if (rf & 1) {
261
+ const _r10 = i0.ɵɵgetCurrentView();
262
+ i0.ɵɵelementStart(0, "button", 114);
263
+ i0.ɵɵlistener("click", function TestRunFormComponentExtended_button_111_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r10); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.changeTab("log")); });
264
+ i0.ɵɵelement(1, "i", 115);
265
+ i0.ɵɵelementStart(2, "span");
266
+ i0.ɵɵtext(3, "Log");
267
+ i0.ɵɵelementEnd()();
268
+ } if (rf & 2) {
269
+ const ctx_r1 = i0.ɵɵnextContext();
270
+ i0.ɵɵclassProp("active", ctx_r1.activeTab === "log");
271
+ i0.ɵɵattribute("aria-selected", ctx_r1.activeTab === "log");
272
+ } }
273
+ function TestRunFormComponentExtended_div_113_div_5_Template(rf, ctx) { if (rf & 1) {
274
+ i0.ɵɵelement(0, "div", 137);
275
+ } }
276
+ function TestRunFormComponentExtended_div_113_div_16_div_8_div_6_Template(rf, ctx) { if (rf & 1) {
277
+ i0.ɵɵelementStart(0, "div", 150);
77
278
  i0.ɵɵtext(1);
78
279
  i0.ɵɵelementEnd();
79
280
  } if (rf & 2) {
80
- const check_r5 = i0.ɵɵnextContext().$implicit;
281
+ const check_r12 = i0.ɵɵnextContext().$implicit;
81
282
  i0.ɵɵadvance();
82
- i0.ɵɵtextInterpolate1("Weight: ", check_r5.weight, "");
283
+ i0.ɵɵtextInterpolate(check_r12.message);
284
+ } }
285
+ function TestRunFormComponentExtended_div_113_div_16_div_8_div_7_Template(rf, ctx) { if (rf & 1) {
286
+ i0.ɵɵelementStart(0, "div", 151)(1, "span", 152);
287
+ i0.ɵɵtext(2, "Weight:");
288
+ i0.ɵɵelementEnd();
289
+ i0.ɵɵtext(3);
290
+ i0.ɵɵelementEnd();
291
+ } if (rf & 2) {
292
+ const check_r12 = i0.ɵɵnextContext().$implicit;
293
+ i0.ɵɵadvance(3);
294
+ i0.ɵɵtextInterpolate1(" ", check_r12.weight, " ");
83
295
  } }
84
- function TestRunFormComponentExtended_div_85_div_11_div_4_Template(rf, ctx) { if (rf & 1) {
85
- i0.ɵɵelementStart(0, "div", 55)(1, "div", 56);
86
- i0.ɵɵelement(2, "i", 57);
296
+ function TestRunFormComponentExtended_div_113_div_16_div_8_Template(rf, ctx) { if (rf & 1) {
297
+ i0.ɵɵelementStart(0, "div", 143)(1, "div", 144);
298
+ i0.ɵɵelement(2, "i", 145);
87
299
  i0.ɵɵelementEnd();
88
- i0.ɵɵelementStart(3, "div", 58)(4, "div", 59);
300
+ i0.ɵɵelementStart(3, "div", 146)(4, "div", 147);
89
301
  i0.ɵɵtext(5);
90
302
  i0.ɵɵelementEnd();
91
- i0.ɵɵelementStart(6, "div", 60);
92
- i0.ɵɵtext(7);
303
+ i0.ɵɵtemplate(6, TestRunFormComponentExtended_div_113_div_16_div_8_div_6_Template, 2, 1, "div", 148);
304
+ i0.ɵɵelementEnd();
305
+ i0.ɵɵtemplate(7, TestRunFormComponentExtended_div_113_div_16_div_8_div_7_Template, 4, 1, "div", 149);
93
306
  i0.ɵɵelementEnd();
94
- i0.ɵɵtemplate(8, TestRunFormComponentExtended_div_85_div_11_div_4_div_8_Template, 2, 1, "div", 61);
95
- i0.ɵɵelementEnd()();
96
307
  } if (rf & 2) {
97
- const check_r5 = ctx.$implicit;
98
- i0.ɵɵclassProp("passed", check_r5.passed)("failed", !check_r5.passed);
308
+ const check_r12 = ctx.$implicit;
309
+ const i_r13 = ctx.index;
310
+ i0.ɵɵstyleProp("animation-delay", i_r13 * 50, "ms");
311
+ i0.ɵɵclassProp("passed", check_r12.passed)("failed", !check_r12.passed);
99
312
  i0.ɵɵadvance(2);
100
- i0.ɵɵclassProp("fa-check-circle", check_r5.passed)("fa-times-circle", !check_r5.passed);
313
+ i0.ɵɵclassProp("fa-check-circle", check_r12.passed)("fa-times-circle", !check_r12.passed);
101
314
  i0.ɵɵadvance(3);
102
- i0.ɵɵtextInterpolate(check_r5.name);
103
- i0.ɵɵadvance(2);
104
- i0.ɵɵtextInterpolate(check_r5.message);
315
+ i0.ɵɵtextInterpolate(check_r12.name);
105
316
  i0.ɵɵadvance();
106
- i0.ɵɵproperty("ngIf", check_r5.weight);
317
+ i0.ɵɵproperty("ngIf", check_r12.message);
318
+ i0.ɵɵadvance();
319
+ i0.ɵɵproperty("ngIf", check_r12.weight);
107
320
  } }
108
- function TestRunFormComponentExtended_div_85_div_11_Template(rf, ctx) { if (rf & 1) {
109
- i0.ɵɵelementStart(0, "div", 52)(1, "h3");
110
- i0.ɵɵtext(2, "Check Results");
321
+ function TestRunFormComponentExtended_div_113_div_16_Template(rf, ctx) { if (rf & 1) {
322
+ i0.ɵɵelementStart(0, "div", 138)(1, "div", 128)(2, "h3");
323
+ i0.ɵɵelement(3, "i", 139);
324
+ i0.ɵɵtext(4, " Check Results");
111
325
  i0.ɵɵelementEnd();
112
- i0.ɵɵelementStart(3, "div", 53);
113
- i0.ɵɵtemplate(4, TestRunFormComponentExtended_div_85_div_11_div_4_Template, 9, 11, "div", 54);
326
+ i0.ɵɵelementStart(5, "span", 140);
327
+ i0.ɵɵtext(6);
328
+ i0.ɵɵelementEnd()();
329
+ i0.ɵɵelementStart(7, "div", 141);
330
+ i0.ɵɵtemplate(8, TestRunFormComponentExtended_div_113_div_16_div_8_Template, 8, 13, "div", 142);
114
331
  i0.ɵɵelementEnd()();
115
332
  } if (rf & 2) {
116
333
  const ctx_r1 = i0.ɵɵnextContext(2);
117
- i0.ɵɵadvance(4);
334
+ i0.ɵɵadvance(6);
335
+ i0.ɵɵtextInterpolate2("", ctx_r1.record.PassedChecks, " passed, ", ctx_r1.record.FailedChecks, " failed");
336
+ i0.ɵɵadvance(2);
118
337
  i0.ɵɵproperty("ngForOf", ctx_r1.getCheckResults());
119
338
  } }
120
- function TestRunFormComponentExtended_div_85_Template(rf, ctx) { if (rf & 1) {
121
- const _r4 = i0.ɵɵgetCurrentView();
122
- i0.ɵɵelementStart(0, "div", 41)(1, "div", 42)(2, "div", 43);
123
- i0.ɵɵelement(3, "i", 12);
339
+ function TestRunFormComponentExtended_div_113_Template(rf, ctx) { if (rf & 1) {
340
+ const _r11 = i0.ɵɵgetCurrentView();
341
+ i0.ɵɵelementStart(0, "div", 116)(1, "div", 117)(2, "div", 118)(3, "div", 119);
342
+ i0.ɵɵelement(4, "i", 13);
124
343
  i0.ɵɵelementEnd();
125
- i0.ɵɵelementStart(4, "div", 44)(5, "h2");
126
- i0.ɵɵtext(6);
344
+ i0.ɵɵtemplate(5, TestRunFormComponentExtended_div_113_div_5_Template, 1, 0, "div", 120);
127
345
  i0.ɵɵelementEnd();
128
- i0.ɵɵelementStart(7, "div", 45);
346
+ i0.ɵɵelementStart(6, "div", 121)(7, "h2");
129
347
  i0.ɵɵtext(8);
130
348
  i0.ɵɵelementEnd();
131
- i0.ɵɵelementStart(9, "div", 46);
132
- i0.ɵɵtext(10);
133
- i0.ɵɵelementEnd()()();
134
- i0.ɵɵtemplate(11, TestRunFormComponentExtended_div_85_div_11_Template, 5, 1, "div", 47);
135
- i0.ɵɵelementStart(12, "div", 48)(13, "h3");
136
- i0.ɵɵtext(14, "Data Comparison");
349
+ i0.ɵɵelementStart(9, "div", 122)(10, "span", 123);
350
+ i0.ɵɵtext(11);
137
351
  i0.ɵɵelementEnd();
138
- i0.ɵɵelementStart(15, "div", 49)(16, "button", 50);
139
- i0.ɵɵlistener("click", function TestRunFormComponentExtended_div_85_Template_button_click_16_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.setComparisonView("input")); });
140
- i0.ɵɵtext(17, " Input ");
352
+ i0.ɵɵelementStart(12, "span", 124);
353
+ i0.ɵɵtext(13, "|");
141
354
  i0.ɵɵelementEnd();
142
- i0.ɵɵelementStart(18, "button", 50);
143
- i0.ɵɵlistener("click", function TestRunFormComponentExtended_div_85_Template_button_click_18_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.setComparisonView("expected")); });
144
- i0.ɵɵtext(19, " Expected ");
355
+ i0.ɵɵelementStart(14, "span", 125);
356
+ i0.ɵɵtext(15);
357
+ i0.ɵɵelementEnd()()()();
358
+ i0.ɵɵtemplate(16, TestRunFormComponentExtended_div_113_div_16_Template, 9, 3, "div", 126);
359
+ i0.ɵɵelementStart(17, "div", 127)(18, "div", 128)(19, "h3");
360
+ i0.ɵɵelement(20, "i", 129);
361
+ i0.ɵɵtext(21, " Data Comparison");
362
+ i0.ɵɵelementEnd()();
363
+ i0.ɵɵelementStart(22, "div", 130)(23, "button", 131);
364
+ i0.ɵɵlistener("click", function TestRunFormComponentExtended_div_113_Template_button_click_23_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.setComparisonView("input")); });
365
+ i0.ɵɵelement(24, "i", 132);
366
+ i0.ɵɵtext(25, " Input ");
367
+ i0.ɵɵelementEnd();
368
+ i0.ɵɵelementStart(26, "button", 131);
369
+ i0.ɵɵlistener("click", function TestRunFormComponentExtended_div_113_Template_button_click_26_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.setComparisonView("expected")); });
370
+ i0.ɵɵelement(27, "i", 133);
371
+ i0.ɵɵtext(28, " Expected ");
145
372
  i0.ɵɵelementEnd();
146
- i0.ɵɵelementStart(20, "button", 50);
147
- i0.ɵɵlistener("click", function TestRunFormComponentExtended_div_85_Template_button_click_20_listener() { i0.ɵɵrestoreView(_r4); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.setComparisonView("actual")); });
148
- i0.ɵɵtext(21, " Actual ");
373
+ i0.ɵɵelementStart(29, "button", 131);
374
+ i0.ɵɵlistener("click", function TestRunFormComponentExtended_div_113_Template_button_click_29_listener() { i0.ɵɵrestoreView(_r11); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.setComparisonView("actual")); });
375
+ i0.ɵɵelement(30, "i", 134);
376
+ i0.ɵɵtext(31, " Actual ");
149
377
  i0.ɵɵelementEnd()();
150
- i0.ɵɵelementStart(22, "div", 51)(23, "pre");
151
- i0.ɵɵtext(24);
152
- i0.ɵɵpipe(25, "json");
153
- i0.ɵɵelementEnd()()()();
378
+ i0.ɵɵelementStart(32, "div", 135);
379
+ i0.ɵɵelement(33, "mj-code-editor", 136);
380
+ i0.ɵɵelementEnd()()();
154
381
  } if (rf & 2) {
155
382
  const ctx_r1 = i0.ɵɵnextContext();
383
+ i0.ɵɵproperty("@fadeIn", undefined);
156
384
  i0.ɵɵadvance();
157
- i0.ɵɵclassProp("passed", ctx_r1.record.Status === "Passed")("failed", ctx_r1.record.Status === "Failed");
158
- i0.ɵɵadvance(2);
385
+ i0.ɵɵclassMap(ctx_r1.getStatusClass());
386
+ i0.ɵɵadvance(3);
159
387
  i0.ɵɵproperty("ngClass", ctx_r1.getStatusIcon());
388
+ i0.ɵɵadvance();
389
+ i0.ɵɵproperty("ngIf", ctx_r1.record.Status === "Running");
160
390
  i0.ɵɵadvance(3);
161
391
  i0.ɵɵtextInterpolate1("TEST ", ctx_r1.record.Status.toUpperCase(), "");
162
- i0.ɵɵadvance(2);
163
- i0.ɵɵtextInterpolate1("Score: ", ctx_r1.formatScore(ctx_r1.record.Score), " / 1.0000");
164
- i0.ɵɵadvance(2);
392
+ i0.ɵɵadvance(3);
393
+ i0.ɵɵtextInterpolate1("Score: ", ctx_r1.formatScore(ctx_r1.record.Score), "");
394
+ i0.ɵɵadvance(4);
165
395
  i0.ɵɵtextInterpolate2("", ctx_r1.record.PassedChecks, " of ", ctx_r1.record.TotalChecks, " checks passed");
166
396
  i0.ɵɵadvance();
167
397
  i0.ɵɵproperty("ngIf", ctx_r1.getCheckResults().length > 0);
168
- i0.ɵɵadvance(5);
398
+ i0.ɵɵadvance(7);
169
399
  i0.ɵɵclassProp("active", ctx_r1.comparisonView === "input");
170
- i0.ɵɵadvance(2);
400
+ i0.ɵɵadvance(3);
171
401
  i0.ɵɵclassProp("active", ctx_r1.comparisonView === "expected");
172
- i0.ɵɵadvance(2);
402
+ i0.ɵɵadvance(3);
173
403
  i0.ɵɵclassProp("active", ctx_r1.comparisonView === "actual");
174
404
  i0.ɵɵadvance(4);
175
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(25, 17, ctx_r1.getComparisonData()));
405
+ i0.ɵɵproperty("value", ctx_r1.getComparisonData())("readonly", true)("toolbar", ctx_r1.jsonToolbar)("lineWrapping", true);
176
406
  } }
177
- function TestRunFormComponentExtended_div_86_a_11_Template(rf, ctx) { if (rf & 1) {
178
- const _r6 = i0.ɵɵgetCurrentView();
179
- i0.ɵɵelementStart(0, "a", 37);
180
- i0.ɵɵlistener("click", function TestRunFormComponentExtended_div_86_a_11_Template_a_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.openTest()); });
181
- i0.ɵɵtext(1);
407
+ function TestRunFormComponentExtended_div_114_div_10_Template(rf, ctx) { if (rf & 1) {
408
+ const _r14 = i0.ɵɵgetCurrentView();
409
+ i0.ɵɵelementStart(0, "div", 169);
410
+ i0.ɵɵlistener("click", function TestRunFormComponentExtended_div_114_div_10_Template_div_click_0_listener() { i0.ɵɵrestoreView(_r14); const ctx_r1 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r1.openTest()); });
411
+ i0.ɵɵelementStart(1, "div", 156);
412
+ i0.ɵɵelement(2, "i", 68);
413
+ i0.ɵɵelementEnd();
414
+ i0.ɵɵelementStart(3, "div", 158)(4, "div", 159);
415
+ i0.ɵɵtext(5, "Test");
416
+ i0.ɵɵelementEnd();
417
+ i0.ɵɵelementStart(6, "div", 170);
418
+ i0.ɵɵtext(7);
419
+ i0.ɵɵelementEnd()();
420
+ i0.ɵɵelement(8, "i", 171);
182
421
  i0.ɵɵelementEnd();
183
422
  } if (rf & 2) {
184
423
  const ctx_r1 = i0.ɵɵnextContext(2);
185
- i0.ɵɵadvance();
424
+ i0.ɵɵadvance(7);
186
425
  i0.ɵɵtextInterpolate(ctx_r1.test.Name);
187
426
  } }
188
- function TestRunFormComponentExtended_div_86_div_64_Template(rf, ctx) { if (rf & 1) {
189
- i0.ɵɵelementStart(0, "div", 70)(1, "h4");
190
- i0.ɵɵtext(2, "Error Message");
191
- i0.ɵɵelementEnd();
192
- i0.ɵɵelementStart(3, "pre");
193
- i0.ɵɵtext(4);
427
+ function TestRunFormComponentExtended_div_114_div_45_Template(rf, ctx) { if (rf & 1) {
428
+ i0.ɵɵelementStart(0, "div", 172)(1, "div", 173)(2, "h3");
429
+ i0.ɵɵelement(3, "i", 66);
430
+ i0.ɵɵtext(4, " Error Message");
431
+ i0.ɵɵelementEnd()();
432
+ i0.ɵɵelementStart(5, "div", 174);
433
+ i0.ɵɵelement(6, "mj-code-editor", 175);
194
434
  i0.ɵɵelementEnd()();
195
435
  } if (rf & 2) {
196
436
  const ctx_r1 = i0.ɵɵnextContext(2);
197
- i0.ɵɵadvance(4);
198
- i0.ɵɵtextInterpolate(ctx_r1.record.ErrorMessage);
437
+ i0.ɵɵadvance(6);
438
+ i0.ɵɵproperty("value", ctx_r1.record.ErrorMessage)("readonly", true)("toolbar", ctx_r1.jsonToolbar)("lineWrapping", true);
199
439
  } }
200
- function TestRunFormComponentExtended_div_86_div_65_Template(rf, ctx) { if (rf & 1) {
201
- i0.ɵɵelementStart(0, "div", 71)(1, "h4");
202
- i0.ɵɵtext(2, "Full Result Details (JSON)");
203
- i0.ɵɵelementEnd();
204
- i0.ɵɵelementStart(3, "pre");
205
- i0.ɵɵtext(4);
206
- i0.ɵɵpipe(5, "json");
440
+ function TestRunFormComponentExtended_div_114_div_46_Template(rf, ctx) { if (rf & 1) {
441
+ i0.ɵɵelementStart(0, "div", 176)(1, "div", 128)(2, "h3");
442
+ i0.ɵɵelement(3, "i", 177);
443
+ i0.ɵɵtext(4, " Result Details");
444
+ i0.ɵɵelementEnd()();
445
+ i0.ɵɵelementStart(5, "div", 178);
446
+ i0.ɵɵelement(6, "mj-code-editor", 136);
207
447
  i0.ɵɵelementEnd()();
208
448
  } if (rf & 2) {
209
449
  const ctx_r1 = i0.ɵɵnextContext(2);
210
- i0.ɵɵadvance(4);
211
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(5, 1, ctx_r1.parsedData.resultDetails));
450
+ i0.ɵɵadvance(6);
451
+ i0.ɵɵproperty("value", ctx_r1.getFormattedResultDetails())("readonly", true)("toolbar", ctx_r1.jsonToolbar)("lineWrapping", true);
212
452
  } }
213
- function TestRunFormComponentExtended_div_86_Template(rf, ctx) { if (rf & 1) {
214
- i0.ɵɵelementStart(0, "div", 63)(1, "div", 64)(2, "div", 65)(3, "div", 66);
215
- i0.ɵɵtext(4, "Test Run ID");
453
+ function TestRunFormComponentExtended_div_114_Template(rf, ctx) { if (rf & 1) {
454
+ i0.ɵɵelementStart(0, "div", 153)(1, "div", 154)(2, "div", 155)(3, "div", 156);
455
+ i0.ɵɵelement(4, "i", 157);
216
456
  i0.ɵɵelementEnd();
217
- i0.ɵɵelementStart(5, "div", 67);
218
- i0.ɵɵtext(6);
219
- i0.ɵɵelementEnd()();
220
- i0.ɵɵelementStart(7, "div", 65)(8, "div", 66);
221
- i0.ɵɵtext(9, "Test");
457
+ i0.ɵɵelementStart(5, "div", 158)(6, "div", 159);
458
+ i0.ɵɵtext(7, "Test Run ID");
222
459
  i0.ɵɵelementEnd();
223
- i0.ɵɵelementStart(10, "div", 67);
224
- i0.ɵɵtemplate(11, TestRunFormComponentExtended_div_86_a_11_Template, 2, 1, "a", 3);
225
- i0.ɵɵelementEnd()();
226
- i0.ɵɵelementStart(12, "div", 65)(13, "div", 66);
227
- i0.ɵɵtext(14, "Status");
460
+ i0.ɵɵelementStart(8, "div", 160);
461
+ i0.ɵɵtext(9);
462
+ i0.ɵɵelementEnd()()();
463
+ i0.ɵɵtemplate(10, TestRunFormComponentExtended_div_114_div_10_Template, 9, 1, "div", 161);
464
+ i0.ɵɵelementStart(11, "div", 155)(12, "div", 156);
465
+ i0.ɵɵelement(13, "i", 162);
228
466
  i0.ɵɵelementEnd();
229
- i0.ɵɵelementStart(15, "div", 67);
230
- i0.ɵɵtext(16);
231
- i0.ɵɵelementEnd()();
232
- i0.ɵɵelementStart(17, "div", 65)(18, "div", 66);
233
- i0.ɵɵtext(19, "Target Type");
467
+ i0.ɵɵelementStart(14, "div", 158)(15, "div", 159);
468
+ i0.ɵɵtext(16, "Target Type");
234
469
  i0.ɵɵelementEnd();
235
- i0.ɵɵelementStart(20, "div", 67);
236
- i0.ɵɵtext(21);
237
- i0.ɵɵelementEnd()();
238
- i0.ɵɵelementStart(22, "div", 65)(23, "div", 66);
470
+ i0.ɵɵelementStart(17, "div", 163);
471
+ i0.ɵɵtext(18);
472
+ i0.ɵɵelementEnd()()();
473
+ i0.ɵɵelementStart(19, "div", 155)(20, "div", 156);
474
+ i0.ɵɵelement(21, "i", 164);
475
+ i0.ɵɵelementEnd();
476
+ i0.ɵɵelementStart(22, "div", 158)(23, "div", 159);
239
477
  i0.ɵɵtext(24, "Started At");
240
478
  i0.ɵɵelementEnd();
241
- i0.ɵɵelementStart(25, "div", 67);
479
+ i0.ɵɵelementStart(25, "div", 163);
242
480
  i0.ɵɵtext(26);
243
481
  i0.ɵɵpipe(27, "date");
244
- i0.ɵɵelementEnd()();
245
- i0.ɵɵelementStart(28, "div", 65)(29, "div", 66);
246
- i0.ɵɵtext(30, "Completed At");
247
- i0.ɵɵelementEnd();
248
- i0.ɵɵelementStart(31, "div", 67);
249
- i0.ɵɵtext(32);
250
- i0.ɵɵpipe(33, "date");
251
- i0.ɵɵelementEnd()();
252
- i0.ɵɵelementStart(34, "div", 65)(35, "div", 66);
253
- i0.ɵɵtext(36, "Duration");
254
- i0.ɵɵelementEnd();
255
- i0.ɵɵelementStart(37, "div", 67);
256
- i0.ɵɵtext(38);
257
- i0.ɵɵelementEnd()();
258
- i0.ɵɵelementStart(39, "div", 65)(40, "div", 66);
259
- i0.ɵɵtext(41, "Score");
260
- i0.ɵɵelementEnd();
261
- i0.ɵɵelementStart(42, "div", 67);
262
- i0.ɵɵtext(43);
263
- i0.ɵɵelementEnd()();
264
- i0.ɵɵelementStart(44, "div", 65)(45, "div", 66);
265
- i0.ɵɵtext(46, "Cost");
482
+ i0.ɵɵelementEnd()()();
483
+ i0.ɵɵelementStart(28, "div", 155)(29, "div", 156);
484
+ i0.ɵɵelement(30, "i", 165);
266
485
  i0.ɵɵelementEnd();
267
- i0.ɵɵelementStart(47, "div", 67);
268
- i0.ɵɵtext(48);
269
- i0.ɵɵelementEnd()();
270
- i0.ɵɵelementStart(49, "div", 65)(50, "div", 66);
271
- i0.ɵɵtext(51, "Passed Checks");
486
+ i0.ɵɵelementStart(31, "div", 158)(32, "div", 159);
487
+ i0.ɵɵtext(33, "Completed At");
272
488
  i0.ɵɵelementEnd();
273
- i0.ɵɵelementStart(52, "div", 67);
274
- i0.ɵɵtext(53);
275
- i0.ɵɵelementEnd()();
276
- i0.ɵɵelementStart(54, "div", 65)(55, "div", 66);
277
- i0.ɵɵtext(56, "Failed Checks");
489
+ i0.ɵɵelementStart(34, "div", 163);
490
+ i0.ɵɵtext(35);
491
+ i0.ɵɵpipe(36, "date");
492
+ i0.ɵɵelementEnd()()();
493
+ i0.ɵɵelementStart(37, "div", 155)(38, "div", 156);
494
+ i0.ɵɵelement(39, "i", 166);
278
495
  i0.ɵɵelementEnd();
279
- i0.ɵɵelementStart(57, "div", 67);
280
- i0.ɵɵtext(58);
281
- i0.ɵɵelementEnd()();
282
- i0.ɵɵelementStart(59, "div", 65)(60, "div", 66);
283
- i0.ɵɵtext(61, "Total Checks");
496
+ i0.ɵɵelementStart(40, "div", 158)(41, "div", 159);
497
+ i0.ɵɵtext(42, "Duration");
284
498
  i0.ɵɵelementEnd();
285
- i0.ɵɵelementStart(62, "div", 67);
286
- i0.ɵɵtext(63);
287
- i0.ɵɵelementEnd()()();
288
- i0.ɵɵtemplate(64, TestRunFormComponentExtended_div_86_div_64_Template, 5, 1, "div", 68)(65, TestRunFormComponentExtended_div_86_div_65_Template, 6, 3, "div", 69);
499
+ i0.ɵɵelementStart(43, "div", 163);
500
+ i0.ɵɵtext(44);
501
+ i0.ɵɵelementEnd()()()();
502
+ i0.ɵɵtemplate(45, TestRunFormComponentExtended_div_114_div_45_Template, 7, 4, "div", 167)(46, TestRunFormComponentExtended_div_114_div_46_Template, 7, 4, "div", 168);
289
503
  i0.ɵɵelementEnd();
290
504
  } if (rf & 2) {
291
505
  const ctx_r1 = i0.ɵɵnextContext();
292
- i0.ɵɵadvance(6);
506
+ i0.ɵɵproperty("@fadeIn", undefined);
507
+ i0.ɵɵadvance(9);
293
508
  i0.ɵɵtextInterpolate(ctx_r1.record.ID);
294
- i0.ɵɵadvance(5);
509
+ i0.ɵɵadvance();
295
510
  i0.ɵɵproperty("ngIf", ctx_r1.test);
296
- i0.ɵɵadvance(5);
297
- i0.ɵɵtextInterpolate(ctx_r1.record.Status);
298
- i0.ɵɵadvance(5);
511
+ i0.ɵɵadvance(8);
299
512
  i0.ɵɵtextInterpolate(ctx_r1.record.TargetType || "N/A");
300
- i0.ɵɵadvance(5);
301
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(27, 14, ctx_r1.record.StartedAt, "medium"));
302
- i0.ɵɵadvance(6);
303
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(33, 17, ctx_r1.record.CompletedAt, "medium"));
304
- i0.ɵɵadvance(6);
513
+ i0.ɵɵadvance(8);
514
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(27, 9, ctx_r1.record.StartedAt, "medium"));
515
+ i0.ɵɵadvance(9);
516
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(36, 12, ctx_r1.record.CompletedAt, "medium"));
517
+ i0.ɵɵadvance(9);
305
518
  i0.ɵɵtextInterpolate(ctx_r1.calculateDuration());
306
- i0.ɵɵadvance(5);
307
- i0.ɵɵtextInterpolate(ctx_r1.formatScore(ctx_r1.record.Score));
308
- i0.ɵɵadvance(5);
309
- i0.ɵɵtextInterpolate(ctx_r1.formatCost(ctx_r1.record.CostUSD));
310
- i0.ɵɵadvance(5);
311
- i0.ɵɵtextInterpolate(ctx_r1.record.PassedChecks);
312
- i0.ɵɵadvance(5);
313
- i0.ɵɵtextInterpolate(ctx_r1.record.FailedChecks);
314
- i0.ɵɵadvance(5);
315
- i0.ɵɵtextInterpolate(ctx_r1.record.TotalChecks);
316
519
  i0.ɵɵadvance();
317
520
  i0.ɵɵproperty("ngIf", ctx_r1.record.ErrorMessage);
318
521
  i0.ɵɵadvance();
319
- i0.ɵɵproperty("ngIf", ctx_r1.record.ResultDetails);
522
+ i0.ɵɵproperty("ngIf", ctx_r1.parsedData.resultDetails);
320
523
  } }
321
- function TestRunFormComponentExtended_div_87_div_1_div_4_span_9_Template(rf, ctx) { if (rf & 1) {
322
- i0.ɵɵelementStart(0, "span");
323
- i0.ɵɵtext(1);
524
+ function TestRunFormComponentExtended_div_115_div_1_div_2_Template(rf, ctx) { if (rf & 1) {
525
+ i0.ɵɵelementStart(0, "div", 186);
526
+ i0.ɵɵelement(1, "div", 187);
527
+ i0.ɵɵelementStart(2, "div", 188);
528
+ i0.ɵɵelement(3, "div", 189)(4, "div", 190);
529
+ i0.ɵɵelementEnd()();
530
+ } }
531
+ function TestRunFormComponentExtended_div_115_div_1_Template(rf, ctx) { if (rf & 1) {
532
+ i0.ɵɵelementStart(0, "div", 183)(1, "div", 184);
533
+ i0.ɵɵtemplate(2, TestRunFormComponentExtended_div_115_div_1_div_2_Template, 5, 0, "div", 185);
534
+ i0.ɵɵelementEnd()();
535
+ } if (rf & 2) {
536
+ i0.ɵɵadvance(2);
537
+ i0.ɵɵproperty("ngForOf", i0.ɵɵpureFunction0(1, _c0));
538
+ } }
539
+ function TestRunFormComponentExtended_div_115_div_2_div_8_span_9_Template(rf, ctx) { if (rf & 1) {
540
+ i0.ɵɵelementStart(0, "span", 203);
541
+ i0.ɵɵelement(1, "i", 37);
542
+ i0.ɵɵtext(2);
543
+ i0.ɵɵpipe(3, "number");
324
544
  i0.ɵɵelementEnd();
325
545
  } if (rf & 2) {
326
- const run_r8 = i0.ɵɵnextContext().$implicit;
327
- i0.ɵɵadvance();
328
- i0.ɵɵtextInterpolate1("$", run_r8.TotalCost, "");
546
+ const run_r16 = i0.ɵɵnextContext().$implicit;
547
+ i0.ɵɵadvance(2);
548
+ i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind2(3, 1, run_r16.TotalCost, "1.4-4"), " ");
329
549
  } }
330
- function TestRunFormComponentExtended_div_87_div_1_div_4_Template(rf, ctx) { if (rf & 1) {
331
- const _r7 = i0.ɵɵgetCurrentView();
332
- i0.ɵɵelementStart(0, "div", 78);
333
- i0.ɵɵlistener("click", function TestRunFormComponentExtended_div_87_div_1_div_4_Template_div_click_0_listener() { const run_r8 = i0.ɵɵrestoreView(_r7).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.openAIAgentRun(run_r8.ID)); });
334
- i0.ɵɵelementStart(1, "div", 79);
335
- i0.ɵɵelement(2, "i", 29);
550
+ function TestRunFormComponentExtended_div_115_div_2_div_8_Template(rf, ctx) { if (rf & 1) {
551
+ const _r15 = i0.ɵɵgetCurrentView();
552
+ i0.ɵɵelementStart(0, "div", 195);
553
+ i0.ɵɵlistener("click", function TestRunFormComponentExtended_div_115_div_2_div_8_Template_div_click_0_listener() { const run_r16 = i0.ɵɵrestoreView(_r15).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.openAIAgentRun(run_r16.ID)); });
554
+ i0.ɵɵelementStart(1, "div", 196);
555
+ i0.ɵɵelement(2, "i", 48);
336
556
  i0.ɵɵelementEnd();
337
- i0.ɵɵelementStart(3, "div", 80)(4, "div", 81);
557
+ i0.ɵɵelementStart(3, "div", 197)(4, "div", 198);
338
558
  i0.ɵɵtext(5);
339
559
  i0.ɵɵelementEnd();
340
- i0.ɵɵelementStart(6, "div", 82)(7, "span");
560
+ i0.ɵɵelementStart(6, "div", 199)(7, "span", 200);
341
561
  i0.ɵɵtext(8);
342
562
  i0.ɵɵelementEnd();
343
- i0.ɵɵtemplate(9, TestRunFormComponentExtended_div_87_div_1_div_4_span_9_Template, 2, 1, "span", 83);
563
+ i0.ɵɵtemplate(9, TestRunFormComponentExtended_div_115_div_2_div_8_span_9_Template, 4, 4, "span", 201);
344
564
  i0.ɵɵelementEnd()();
345
- i0.ɵɵelement(10, "i", 84);
565
+ i0.ɵɵelement(10, "i", 202);
346
566
  i0.ɵɵelementEnd();
347
567
  } if (rf & 2) {
348
- const run_r8 = ctx.$implicit;
568
+ const run_r16 = ctx.$implicit;
349
569
  i0.ɵɵadvance(5);
350
- i0.ɵɵtextInterpolate(run_r8.Agent);
351
- i0.ɵɵadvance(3);
352
- i0.ɵɵtextInterpolate(run_r8.Status);
570
+ i0.ɵɵtextInterpolate(run_r16.Agent);
571
+ i0.ɵɵadvance(2);
572
+ i0.ɵɵclassMap(run_r16.Status.toLowerCase());
353
573
  i0.ɵɵadvance();
354
- i0.ɵɵproperty("ngIf", run_r8.TotalCost);
574
+ i0.ɵɵtextInterpolate(run_r16.Status);
575
+ i0.ɵɵadvance();
576
+ i0.ɵɵproperty("ngIf", run_r16.TotalCost);
355
577
  } }
356
- function TestRunFormComponentExtended_div_87_div_1_Template(rf, ctx) { if (rf & 1) {
357
- i0.ɵɵelementStart(0, "div", 75)(1, "h3");
358
- i0.ɵɵtext(2);
578
+ function TestRunFormComponentExtended_div_115_div_2_Template(rf, ctx) { if (rf & 1) {
579
+ i0.ɵɵelementStart(0, "div", 191)(1, "div", 128)(2, "h3");
580
+ i0.ɵɵelement(3, "i", 48);
581
+ i0.ɵɵtext(4, " AI Agent Runs");
359
582
  i0.ɵɵelementEnd();
360
- i0.ɵɵelementStart(3, "div", 76);
361
- i0.ɵɵtemplate(4, TestRunFormComponentExtended_div_87_div_1_div_4_Template, 11, 3, "div", 77);
583
+ i0.ɵɵelementStart(5, "span", 192);
584
+ i0.ɵɵtext(6);
585
+ i0.ɵɵelementEnd()();
586
+ i0.ɵɵelementStart(7, "div", 193);
587
+ i0.ɵɵtemplate(8, TestRunFormComponentExtended_div_115_div_2_div_8_Template, 11, 5, "div", 194);
362
588
  i0.ɵɵelementEnd()();
363
589
  } if (rf & 2) {
364
590
  const ctx_r1 = i0.ɵɵnextContext(2);
365
- i0.ɵɵadvance(2);
366
- i0.ɵɵtextInterpolate1("AI Agent Runs (", ctx_r1.aiAgentRuns.length, ")");
591
+ i0.ɵɵadvance(6);
592
+ i0.ɵɵtextInterpolate(ctx_r1.aiAgentRuns.length);
367
593
  i0.ɵɵadvance(2);
368
594
  i0.ɵɵproperty("ngForOf", ctx_r1.aiAgentRuns);
369
595
  } }
370
- function TestRunFormComponentExtended_div_87_div_2_div_4_span_7_Template(rf, ctx) { if (rf & 1) {
371
- i0.ɵɵelementStart(0, "span");
372
- i0.ɵɵtext(1);
596
+ function TestRunFormComponentExtended_div_115_div_3_div_8_span_7_Template(rf, ctx) { if (rf & 1) {
597
+ i0.ɵɵelementStart(0, "span", 203);
598
+ i0.ɵɵelement(1, "i", 37);
599
+ i0.ɵɵtext(2);
600
+ i0.ɵɵpipe(3, "number");
373
601
  i0.ɵɵelementEnd();
374
602
  } if (rf & 2) {
375
- const run_r10 = i0.ɵɵnextContext().$implicit;
376
- i0.ɵɵadvance();
377
- i0.ɵɵtextInterpolate1("$", run_r10.TotalCost, "");
603
+ const run_r18 = i0.ɵɵnextContext().$implicit;
604
+ i0.ɵɵadvance(2);
605
+ i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind2(3, 1, run_r18.TotalCost, "1.4-4"), " ");
378
606
  } }
379
- function TestRunFormComponentExtended_div_87_div_2_div_4_Template(rf, ctx) { if (rf & 1) {
380
- const _r9 = i0.ɵɵgetCurrentView();
381
- i0.ɵɵelementStart(0, "div", 78);
382
- i0.ɵɵlistener("click", function TestRunFormComponentExtended_div_87_div_2_div_4_Template_div_click_0_listener() { const run_r10 = i0.ɵɵrestoreView(_r9).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.openAIPromptRun(run_r10.ID)); });
383
- i0.ɵɵelementStart(1, "div", 85);
384
- i0.ɵɵelement(2, "i", 86);
607
+ function TestRunFormComponentExtended_div_115_div_3_div_8_Template(rf, ctx) { if (rf & 1) {
608
+ const _r17 = i0.ɵɵgetCurrentView();
609
+ i0.ɵɵelementStart(0, "div", 195);
610
+ i0.ɵɵlistener("click", function TestRunFormComponentExtended_div_115_div_3_div_8_Template_div_click_0_listener() { const run_r18 = i0.ɵɵrestoreView(_r17).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.openAIPromptRun(run_r18.ID)); });
611
+ i0.ɵɵelementStart(1, "div", 205);
612
+ i0.ɵɵelement(2, "i", 204);
385
613
  i0.ɵɵelementEnd();
386
- i0.ɵɵelementStart(3, "div", 80)(4, "div", 81);
614
+ i0.ɵɵelementStart(3, "div", 197)(4, "div", 198);
387
615
  i0.ɵɵtext(5);
388
616
  i0.ɵɵelementEnd();
389
- i0.ɵɵelementStart(6, "div", 82);
390
- i0.ɵɵtemplate(7, TestRunFormComponentExtended_div_87_div_2_div_4_span_7_Template, 2, 1, "span", 83);
617
+ i0.ɵɵelementStart(6, "div", 199);
618
+ i0.ɵɵtemplate(7, TestRunFormComponentExtended_div_115_div_3_div_8_span_7_Template, 4, 4, "span", 201);
391
619
  i0.ɵɵelementEnd()();
392
- i0.ɵɵelement(8, "i", 84);
620
+ i0.ɵɵelement(8, "i", 202);
393
621
  i0.ɵɵelementEnd();
394
622
  } if (rf & 2) {
395
- const run_r10 = ctx.$implicit;
623
+ const run_r18 = ctx.$implicit;
396
624
  i0.ɵɵadvance(5);
397
- i0.ɵɵtextInterpolate(run_r10.Prompt || run_r10.Model);
625
+ i0.ɵɵtextInterpolate(run_r18.Prompt || run_r18.Model);
398
626
  i0.ɵɵadvance(2);
399
- i0.ɵɵproperty("ngIf", run_r10.TotalCost);
627
+ i0.ɵɵproperty("ngIf", run_r18.TotalCost);
400
628
  } }
401
- function TestRunFormComponentExtended_div_87_div_2_Template(rf, ctx) { if (rf & 1) {
402
- i0.ɵɵelementStart(0, "div", 75)(1, "h3");
403
- i0.ɵɵtext(2);
629
+ function TestRunFormComponentExtended_div_115_div_3_Template(rf, ctx) { if (rf & 1) {
630
+ i0.ɵɵelementStart(0, "div", 191)(1, "div", 128)(2, "h3");
631
+ i0.ɵɵelement(3, "i", 204);
632
+ i0.ɵɵtext(4, " AI Prompt Runs");
404
633
  i0.ɵɵelementEnd();
405
- i0.ɵɵelementStart(3, "div", 76);
406
- i0.ɵɵtemplate(4, TestRunFormComponentExtended_div_87_div_2_div_4_Template, 9, 2, "div", 77);
634
+ i0.ɵɵelementStart(5, "span", 192);
635
+ i0.ɵɵtext(6);
636
+ i0.ɵɵelementEnd()();
637
+ i0.ɵɵelementStart(7, "div", 193);
638
+ i0.ɵɵtemplate(8, TestRunFormComponentExtended_div_115_div_3_div_8_Template, 9, 2, "div", 194);
407
639
  i0.ɵɵelementEnd()();
408
640
  } if (rf & 2) {
409
641
  const ctx_r1 = i0.ɵɵnextContext(2);
410
- i0.ɵɵadvance(2);
411
- i0.ɵɵtextInterpolate1("AI Prompt Runs (", ctx_r1.aiPromptRuns.length, ")");
642
+ i0.ɵɵadvance(6);
643
+ i0.ɵɵtextInterpolate(ctx_r1.aiPromptRuns.length);
412
644
  i0.ɵɵadvance(2);
413
645
  i0.ɵɵproperty("ngForOf", ctx_r1.aiPromptRuns);
414
646
  } }
415
- function TestRunFormComponentExtended_div_87_div_3_Template(rf, ctx) { if (rf & 1) {
416
- i0.ɵɵelementStart(0, "div", 87);
417
- i0.ɵɵelement(1, "i", 88);
418
- i0.ɵɵelementStart(2, "p");
419
- i0.ɵɵtext(3, "No AI runs associated with this test execution");
647
+ function TestRunFormComponentExtended_div_115_div_4_Template(rf, ctx) { if (rf & 1) {
648
+ i0.ɵɵelementStart(0, "div", 206)(1, "div", 207);
649
+ i0.ɵɵelement(2, "i", 48);
650
+ i0.ɵɵelementEnd();
651
+ i0.ɵɵelementStart(3, "h3");
652
+ i0.ɵɵtext(4, "No AI Runs");
653
+ i0.ɵɵelementEnd();
654
+ i0.ɵɵelementStart(5, "p");
655
+ i0.ɵɵtext(6, "This test execution didn't involve any AI agent or prompt runs.");
420
656
  i0.ɵɵelementEnd()();
421
657
  } }
422
- function TestRunFormComponentExtended_div_87_Template(rf, ctx) { if (rf & 1) {
423
- i0.ɵɵelementStart(0, "div", 72);
424
- i0.ɵɵtemplate(1, TestRunFormComponentExtended_div_87_div_1_Template, 5, 2, "div", 73)(2, TestRunFormComponentExtended_div_87_div_2_Template, 5, 2, "div", 73)(3, TestRunFormComponentExtended_div_87_div_3_Template, 4, 0, "div", 74);
658
+ function TestRunFormComponentExtended_div_115_Template(rf, ctx) { if (rf & 1) {
659
+ i0.ɵɵelementStart(0, "div", 179);
660
+ i0.ɵɵtemplate(1, TestRunFormComponentExtended_div_115_div_1_Template, 3, 2, "div", 180)(2, TestRunFormComponentExtended_div_115_div_2_Template, 9, 2, "div", 181)(3, TestRunFormComponentExtended_div_115_div_3_Template, 9, 2, "div", 181)(4, TestRunFormComponentExtended_div_115_div_4_Template, 7, 0, "div", 182);
425
661
  i0.ɵɵelementEnd();
426
662
  } if (rf & 2) {
427
663
  const ctx_r1 = i0.ɵɵnextContext();
664
+ i0.ɵɵproperty("@fadeIn", undefined);
665
+ i0.ɵɵadvance();
666
+ i0.ɵɵproperty("ngIf", ctx_r1.loadingAIRuns);
428
667
  i0.ɵɵadvance();
429
- i0.ɵɵproperty("ngIf", ctx_r1.aiAgentRuns.length > 0);
668
+ i0.ɵɵproperty("ngIf", !ctx_r1.loadingAIRuns && ctx_r1.aiAgentRuns.length > 0);
430
669
  i0.ɵɵadvance();
431
- i0.ɵɵproperty("ngIf", ctx_r1.aiPromptRuns.length > 0);
670
+ i0.ɵɵproperty("ngIf", !ctx_r1.loadingAIRuns && ctx_r1.aiPromptRuns.length > 0);
432
671
  i0.ɵɵadvance();
433
672
  i0.ɵɵproperty("ngIf", ctx_r1.aiRunsLoaded && ctx_r1.aiAgentRuns.length === 0 && ctx_r1.aiPromptRuns.length === 0);
434
673
  } }
435
- function TestRunFormComponentExtended_div_88_div_1_div_1_div_10_Template(rf, ctx) { if (rf & 1) {
436
- i0.ɵɵelementStart(0, "div", 101);
437
- i0.ɵɵtext(1);
438
- i0.ɵɵelementEnd();
674
+ function TestRunFormComponentExtended_div_116_div_1_div_2_Template(rf, ctx) { if (rf & 1) {
675
+ i0.ɵɵelementStart(0, "div", 186);
676
+ i0.ɵɵelement(1, "div", 210);
677
+ i0.ɵɵelementStart(2, "div", 188);
678
+ i0.ɵɵelement(3, "div", 189)(4, "div", 190)(5, "div", 211);
679
+ i0.ɵɵelementEnd()();
680
+ } }
681
+ function TestRunFormComponentExtended_div_116_div_1_Template(rf, ctx) { if (rf & 1) {
682
+ i0.ɵɵelementStart(0, "div", 183)(1, "div", 184);
683
+ i0.ɵɵtemplate(2, TestRunFormComponentExtended_div_116_div_1_div_2_Template, 6, 0, "div", 185);
684
+ i0.ɵɵelementEnd()();
439
685
  } if (rf & 2) {
440
- const feedback_r11 = i0.ɵɵnextContext().$implicit;
441
- i0.ɵɵadvance();
442
- i0.ɵɵtextInterpolate1(" Automated Result: ", feedback_r11.IsCorrect ? "Correct" : "Incorrect", " ");
686
+ i0.ɵɵadvance(2);
687
+ i0.ɵɵproperty("ngForOf", i0.ɵɵpureFunction0(1, _c1));
443
688
  } }
444
- function TestRunFormComponentExtended_div_88_div_1_div_1_div_11_Template(rf, ctx) { if (rf & 1) {
445
- i0.ɵɵelementStart(0, "div", 102);
446
- i0.ɵɵtext(1);
447
- i0.ɵɵelementEnd();
689
+ function TestRunFormComponentExtended_div_116_div_2_div_1_i_12_Template(rf, ctx) { if (rf & 1) {
690
+ i0.ɵɵelement(0, "i", 34);
448
691
  } if (rf & 2) {
449
- const feedback_r11 = i0.ɵɵnextContext().$implicit;
692
+ const s_r19 = ctx.$implicit;
693
+ const feedback_r20 = i0.ɵɵnextContext().$implicit;
694
+ i0.ɵɵclassProp("filled", s_r19 <= (feedback_r20.Rating || 0));
695
+ } }
696
+ function TestRunFormComponentExtended_div_116_div_2_div_1_div_15_Template(rf, ctx) { if (rf & 1) {
697
+ i0.ɵɵelementStart(0, "div", 227)(1, "span", 228);
698
+ i0.ɵɵelement(2, "i", 145);
699
+ i0.ɵɵtext(3);
700
+ i0.ɵɵelementEnd()();
701
+ } if (rf & 2) {
702
+ const feedback_r20 = i0.ɵɵnextContext().$implicit;
703
+ i0.ɵɵadvance();
704
+ i0.ɵɵclassProp("correct", feedback_r20.IsCorrect)("incorrect", !feedback_r20.IsCorrect);
450
705
  i0.ɵɵadvance();
451
- i0.ɵɵtextInterpolate1(" ", feedback_r11.CorrectionSummary, " ");
706
+ i0.ɵɵclassProp("fa-check", feedback_r20.IsCorrect)("fa-times", !feedback_r20.IsCorrect);
707
+ i0.ɵɵadvance();
708
+ i0.ɵɵtextInterpolate1(" ", feedback_r20.IsCorrect ? "Marked Correct" : "Marked Incorrect", " ");
709
+ } }
710
+ function TestRunFormComponentExtended_div_116_div_2_div_1_div_16_Template(rf, ctx) { if (rf & 1) {
711
+ i0.ɵɵelementStart(0, "div", 229)(1, "p");
712
+ i0.ɵɵtext(2);
713
+ i0.ɵɵelementEnd()();
714
+ } if (rf & 2) {
715
+ const feedback_r20 = i0.ɵɵnextContext().$implicit;
716
+ i0.ɵɵadvance(2);
717
+ i0.ɵɵtextInterpolate(feedback_r20.CorrectionSummary);
452
718
  } }
453
- function TestRunFormComponentExtended_div_88_div_1_div_1_Template(rf, ctx) { if (rf & 1) {
454
- i0.ɵɵelementStart(0, "div", 93)(1, "div", 94)(2, "div", 95);
455
- i0.ɵɵelement(3, "i", 96);
456
- i0.ɵɵtext(4);
719
+ function TestRunFormComponentExtended_div_116_div_2_div_1_Template(rf, ctx) { if (rf & 1) {
720
+ i0.ɵɵelementStart(0, "div", 214)(1, "div", 215)(2, "div", 216)(3, "div", 217);
721
+ i0.ɵɵelement(4, "i", 78);
457
722
  i0.ɵɵelementEnd();
458
- i0.ɵɵelementStart(5, "div", 97);
723
+ i0.ɵɵelementStart(5, "span", 218);
459
724
  i0.ɵɵtext(6);
460
- i0.ɵɵpipe(7, "date");
461
725
  i0.ɵɵelementEnd()();
462
- i0.ɵɵelementStart(8, "div", 98);
463
- i0.ɵɵtext(9);
464
- i0.ɵɵelementEnd();
465
- i0.ɵɵtemplate(10, TestRunFormComponentExtended_div_88_div_1_div_1_div_10_Template, 2, 1, "div", 99)(11, TestRunFormComponentExtended_div_88_div_1_div_1_div_11_Template, 2, 1, "div", 100);
726
+ i0.ɵɵelementStart(7, "div", 219);
727
+ i0.ɵɵtext(8);
728
+ i0.ɵɵelementEnd()();
729
+ i0.ɵɵelementStart(9, "div", 220)(10, "div", 221)(11, "div", 222);
730
+ i0.ɵɵtemplate(12, TestRunFormComponentExtended_div_116_div_2_div_1_i_12_Template, 1, 2, "i", 223);
466
731
  i0.ɵɵelementEnd();
732
+ i0.ɵɵelementStart(13, "span", 224);
733
+ i0.ɵɵtext(14);
734
+ i0.ɵɵelementEnd()();
735
+ i0.ɵɵtemplate(15, TestRunFormComponentExtended_div_116_div_2_div_1_div_15_Template, 4, 9, "div", 225)(16, TestRunFormComponentExtended_div_116_div_2_div_1_div_16_Template, 3, 1, "div", 226);
736
+ i0.ɵɵelementEnd()();
467
737
  } if (rf & 2) {
468
- const feedback_r11 = ctx.$implicit;
738
+ const feedback_r20 = ctx.$implicit;
739
+ const ctx_r1 = i0.ɵɵnextContext(3);
740
+ i0.ɵɵadvance(6);
741
+ i0.ɵɵtextInterpolate(feedback_r20.ReviewerUser);
742
+ i0.ɵɵadvance(2);
743
+ i0.ɵɵtextInterpolate1(" ", ctx_r1.getRelativeTime(feedback_r20.__mj_CreatedAt), " ");
469
744
  i0.ɵɵadvance(4);
470
- i0.ɵɵtextInterpolate1(" ", feedback_r11.ReviewerUserID, " ");
745
+ i0.ɵɵproperty("ngForOf", i0.ɵɵpureFunction0(6, _c2));
471
746
  i0.ɵɵadvance(2);
472
- i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind2(7, 5, feedback_r11.__mj_CreatedAt, "medium"), " ");
473
- i0.ɵɵadvance(3);
474
- i0.ɵɵtextInterpolate1(" Rating: ", feedback_r11.Rating, "/10 ");
747
+ i0.ɵɵtextInterpolate1("", feedback_r20.Rating, "/10");
475
748
  i0.ɵɵadvance();
476
- i0.ɵɵproperty("ngIf", feedback_r11.IsCorrect !== null);
749
+ i0.ɵɵproperty("ngIf", feedback_r20.IsCorrect !== null);
477
750
  i0.ɵɵadvance();
478
- i0.ɵɵproperty("ngIf", feedback_r11.CorrectionSummary);
751
+ i0.ɵɵproperty("ngIf", feedback_r20.CorrectionSummary);
479
752
  } }
480
- function TestRunFormComponentExtended_div_88_div_1_Template(rf, ctx) { if (rf & 1) {
481
- i0.ɵɵelementStart(0, "div", 91);
482
- i0.ɵɵtemplate(1, TestRunFormComponentExtended_div_88_div_1_div_1_Template, 12, 8, "div", 92);
753
+ function TestRunFormComponentExtended_div_116_div_2_Template(rf, ctx) { if (rf & 1) {
754
+ i0.ɵɵelementStart(0, "div", 212);
755
+ i0.ɵɵtemplate(1, TestRunFormComponentExtended_div_116_div_2_div_1_Template, 17, 7, "div", 213);
483
756
  i0.ɵɵelementEnd();
484
757
  } if (rf & 2) {
485
758
  const ctx_r1 = i0.ɵɵnextContext(2);
486
759
  i0.ɵɵadvance();
487
760
  i0.ɵɵproperty("ngForOf", ctx_r1.feedbacks);
488
761
  } }
489
- function TestRunFormComponentExtended_div_88_div_2_Template(rf, ctx) { if (rf & 1) {
490
- i0.ɵɵelementStart(0, "div", 87);
491
- i0.ɵɵelement(1, "i", 88);
492
- i0.ɵɵelementStart(2, "p");
493
- i0.ɵɵtext(3, "No feedback submitted for this test run");
762
+ function TestRunFormComponentExtended_div_116_div_3_Template(rf, ctx) { if (rf & 1) {
763
+ i0.ɵɵelementStart(0, "div", 206)(1, "div", 207);
764
+ i0.ɵɵelement(2, "i", 51);
765
+ i0.ɵɵelementEnd();
766
+ i0.ɵɵelementStart(3, "h3");
767
+ i0.ɵɵtext(4, "No Feedback Yet");
768
+ i0.ɵɵelementEnd();
769
+ i0.ɵɵelementStart(5, "p");
770
+ i0.ɵɵtext(6, "No one has reviewed this test run yet. Be the first to provide feedback!");
494
771
  i0.ɵɵelementEnd()();
495
772
  } }
496
- function TestRunFormComponentExtended_div_88_Template(rf, ctx) { if (rf & 1) {
497
- i0.ɵɵelementStart(0, "div", 89);
498
- i0.ɵɵtemplate(1, TestRunFormComponentExtended_div_88_div_1_Template, 2, 1, "div", 90)(2, TestRunFormComponentExtended_div_88_div_2_Template, 4, 0, "div", 74);
773
+ function TestRunFormComponentExtended_div_116_Template(rf, ctx) { if (rf & 1) {
774
+ i0.ɵɵelementStart(0, "div", 208);
775
+ i0.ɵɵtemplate(1, TestRunFormComponentExtended_div_116_div_1_Template, 3, 2, "div", 180)(2, TestRunFormComponentExtended_div_116_div_2_Template, 2, 1, "div", 209)(3, TestRunFormComponentExtended_div_116_div_3_Template, 7, 0, "div", 182);
499
776
  i0.ɵɵelementEnd();
500
777
  } if (rf & 2) {
501
778
  const ctx_r1 = i0.ɵɵnextContext();
779
+ i0.ɵɵproperty("@fadeIn", undefined);
780
+ i0.ɵɵadvance();
781
+ i0.ɵɵproperty("ngIf", ctx_r1.loadingFeedback);
502
782
  i0.ɵɵadvance();
503
- i0.ɵɵproperty("ngIf", ctx_r1.feedbacks.length > 0);
783
+ i0.ɵɵproperty("ngIf", !ctx_r1.loadingFeedback && ctx_r1.feedbacks.length > 0);
504
784
  i0.ɵɵadvance();
505
785
  i0.ɵɵproperty("ngIf", ctx_r1.feedbackLoaded && ctx_r1.feedbacks.length === 0);
506
786
  } }
787
+ function TestRunFormComponentExtended_div_117_Template(rf, ctx) { if (rf & 1) {
788
+ i0.ɵɵelementStart(0, "div", 230);
789
+ i0.ɵɵelement(1, "mj-execution-context", 231);
790
+ i0.ɵɵelementEnd();
791
+ } if (rf & 2) {
792
+ const ctx_r1 = i0.ɵɵnextContext();
793
+ i0.ɵɵproperty("@fadeIn", undefined);
794
+ i0.ɵɵadvance();
795
+ i0.ɵɵproperty("machineName", ctx_r1.record.MachineName)("machineId", ctx_r1.record.MachineID)("runByUserName", ctx_r1.record.RunByUserName)("runByUserEmail", ctx_r1.record.RunByUserEmail)("runContextDetailsJson", ctx_r1.record.RunContextDetails);
796
+ } }
797
+ function TestRunFormComponentExtended_div_118_Template(rf, ctx) { if (rf & 1) {
798
+ const _r21 = i0.ɵɵgetCurrentView();
799
+ i0.ɵɵelementStart(0, "div", 232)(1, "div", 233)(2, "div", 234);
800
+ i0.ɵɵelement(3, "i", 115);
801
+ i0.ɵɵelementStart(4, "h3");
802
+ i0.ɵɵtext(5, "Execution Log");
803
+ i0.ɵɵelementEnd()();
804
+ i0.ɵɵelementStart(6, "div", 235)(7, "button", 236);
805
+ i0.ɵɵlistener("click", function TestRunFormComponentExtended_div_118_Template_button_click_7_listener() { i0.ɵɵrestoreView(_r21); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.copyLogToClipboard()); });
806
+ i0.ɵɵelement(8, "i", 237);
807
+ i0.ɵɵelementStart(9, "span", 22);
808
+ i0.ɵɵtext(10, "Copy");
809
+ i0.ɵɵelementEnd()()()();
810
+ i0.ɵɵelementStart(11, "div", 238);
811
+ i0.ɵɵelement(12, "mj-code-editor", 175);
812
+ i0.ɵɵelementEnd()();
813
+ } if (rf & 2) {
814
+ const ctx_r1 = i0.ɵɵnextContext();
815
+ i0.ɵɵproperty("@fadeIn", undefined);
816
+ i0.ɵɵadvance(12);
817
+ i0.ɵɵproperty("value", ctx_r1.record.Log || "")("readonly", true)("toolbar", ctx_r1.jsonToolbar)("lineWrapping", true);
818
+ } }
507
819
  let TestRunFormComponentExtended = class TestRunFormComponentExtended extends TestRunFormComponent {
508
- constructor(elementRef, sharedService, router, route, cdr) {
820
+ constructor(elementRef, sharedService, router, route, cdr, testingDialogService, navigationService, appManager, viewContainerRef) {
509
821
  super(elementRef, sharedService, router, route, cdr);
510
822
  this.router = router;
511
823
  this.cdr = cdr;
824
+ this.testingDialogService = testingDialogService;
825
+ this.navigationService = navigationService;
826
+ this.appManager = appManager;
827
+ this.viewContainerRef = viewContainerRef;
512
828
  this.destroy$ = new Subject();
513
829
  // UI state
514
830
  this.activeTab = 'overview';
515
831
  this.loading = false;
832
+ this.loadingAIRuns = false;
833
+ this.loadingFeedback = false;
516
834
  this.error = null;
517
835
  this.aiRunsLoaded = false;
518
836
  this.feedbackLoaded = false;
837
+ this.isRefreshing = false;
838
+ this.autoRefreshEnabled = false;
519
839
  // Related entities
520
840
  this.test = null;
521
841
  this.testSuiteRun = null;
@@ -526,20 +846,153 @@ let TestRunFormComponentExtended = class TestRunFormComponentExtended extends Te
526
846
  this.parsedData = {};
527
847
  // Active comparison view
528
848
  this.comparisonView = 'input';
849
+ // Code editor configuration
850
+ this.jsonToolbar = createCopyOnlyToolbar();
851
+ // Keyboard shortcuts active
852
+ this.keyboardShortcutsEnabled = true;
853
+ // Tags management
854
+ this.tags = [];
855
+ this.newTag = '';
856
+ this.editingTags = false;
857
+ this.savingTags = false;
858
+ this.originalTags = [];
529
859
  }
530
860
  async ngOnInit() {
531
861
  await super.ngOnInit();
532
862
  if (this.record && this.record.ID) {
533
863
  await this.loadRelatedData();
534
864
  this.parseJsonFields();
865
+ this.loadTags();
866
+ // Auto-refresh for running tests
867
+ if (this.record.Status === 'Running' || this.record.Status === 'Pending') {
868
+ this.startAutoRefresh();
869
+ }
870
+ }
871
+ }
872
+ loadTags() {
873
+ this.tags = TagsHelper.parseTags(this.record.Tags);
874
+ this.originalTags = [...this.tags];
875
+ }
876
+ startEditingTags() {
877
+ this.originalTags = [...this.tags];
878
+ this.editingTags = true;
879
+ this.cdr.markForCheck();
880
+ }
881
+ cancelEditingTags() {
882
+ this.tags = [...this.originalTags];
883
+ this.newTag = '';
884
+ this.editingTags = false;
885
+ this.cdr.markForCheck();
886
+ }
887
+ addTag() {
888
+ const tag = this.newTag.trim();
889
+ if (tag && !this.tags.includes(tag)) {
890
+ this.tags = [...this.tags, tag];
891
+ this.newTag = '';
892
+ this.cdr.markForCheck();
893
+ }
894
+ }
895
+ removeTag(tag) {
896
+ this.tags = this.tags.filter(t => t !== tag);
897
+ this.cdr.markForCheck();
898
+ }
899
+ async saveTags() {
900
+ // Auto-add any pending tag in the input before saving
901
+ const pendingTag = this.newTag.trim();
902
+ if (pendingTag && !this.tags.includes(pendingTag)) {
903
+ this.tags = [...this.tags, pendingTag];
904
+ this.newTag = '';
905
+ }
906
+ this.savingTags = true;
907
+ this.cdr.markForCheck();
908
+ try {
909
+ this.record.Tags = TagsHelper.toJson(this.tags);
910
+ const result = await this.record.Save();
911
+ if (result) {
912
+ this.originalTags = [...this.tags];
913
+ this.editingTags = false;
914
+ SharedService.Instance.CreateSimpleNotification('Tags saved', 'success', 2000);
915
+ }
916
+ else {
917
+ SharedService.Instance.CreateSimpleNotification('Failed to save tags', 'error', 3000);
918
+ }
919
+ }
920
+ catch {
921
+ SharedService.Instance.CreateSimpleNotification('Failed to save tags', 'error', 3000);
922
+ }
923
+ finally {
924
+ this.savingTags = false;
925
+ this.cdr.markForCheck();
535
926
  }
536
927
  }
537
928
  ngOnDestroy() {
538
929
  this.destroy$.next();
539
930
  this.destroy$.complete();
540
931
  }
932
+ // Keyboard shortcuts
933
+ handleKeyboardShortcut(event) {
934
+ if (!this.keyboardShortcutsEnabled)
935
+ return;
936
+ // Cmd/Ctrl + R: Refresh
937
+ if ((event.metaKey || event.ctrlKey) && event.key === 'r' && !event.shiftKey) {
938
+ event.preventDefault();
939
+ this.refresh();
940
+ return;
941
+ }
942
+ // Cmd/Ctrl + Shift + R: Re-run test
943
+ if ((event.metaKey || event.ctrlKey) && event.shiftKey && event.key === 'r') {
944
+ event.preventDefault();
945
+ this.reRunTest();
946
+ return;
947
+ }
948
+ // Number keys for tabs (1-5)
949
+ if (!event.metaKey && !event.ctrlKey && !event.altKey) {
950
+ switch (event.key) {
951
+ case '1':
952
+ this.changeTab('overview');
953
+ break;
954
+ case '2':
955
+ this.changeTab('details');
956
+ break;
957
+ case '3':
958
+ this.changeTab('ai-runs');
959
+ break;
960
+ case '4':
961
+ this.changeTab('feedback');
962
+ break;
963
+ case '5':
964
+ if (this.record.Log)
965
+ this.changeTab('log');
966
+ break;
967
+ }
968
+ }
969
+ }
970
+ startAutoRefresh() {
971
+ this.autoRefreshEnabled = true;
972
+ interval(5000)
973
+ .pipe(takeUntil(this.destroy$))
974
+ .subscribe(() => {
975
+ if (this.autoRefreshEnabled && (this.record.Status === 'Running' || this.record.Status === 'Pending')) {
976
+ this.silentRefresh();
977
+ }
978
+ else {
979
+ this.autoRefreshEnabled = false;
980
+ }
981
+ });
982
+ }
983
+ async silentRefresh() {
984
+ try {
985
+ await this.record.Load(this.record.ID);
986
+ this.parseJsonFields();
987
+ this.cdr.markForCheck();
988
+ }
989
+ catch {
990
+ // Silently fail on auto-refresh
991
+ }
992
+ }
541
993
  async loadRelatedData() {
542
994
  this.loading = true;
995
+ this.error = null;
543
996
  try {
544
997
  // Load test
545
998
  if (this.record.TestID) {
@@ -561,16 +1014,22 @@ let TestRunFormComponentExtended = class TestRunFormComponentExtended extends Te
561
1014
  }
562
1015
  catch (error) {
563
1016
  console.error('Error loading related data:', error);
564
- this.error = 'Failed to load related data';
1017
+ this.error = 'Failed to load related data. Click to retry.';
565
1018
  }
566
1019
  finally {
567
1020
  this.loading = false;
568
1021
  this.cdr.markForCheck();
569
1022
  }
570
1023
  }
1024
+ async retryLoad() {
1025
+ this.error = null;
1026
+ await this.loadRelatedData();
1027
+ }
571
1028
  async loadAIRuns() {
572
1029
  if (this.aiRunsLoaded)
573
1030
  return;
1031
+ this.loadingAIRuns = true;
1032
+ this.cdr.markForCheck();
574
1033
  try {
575
1034
  const rv = new RunView();
576
1035
  const [agentRuns, promptRuns] = await rv.RunViews([
@@ -583,7 +1042,7 @@ let TestRunFormComponentExtended = class TestRunFormComponentExtended extends Te
583
1042
  {
584
1043
  EntityName: 'MJ: AI Prompt Runs',
585
1044
  ExtraFilter: `TestRunID='${this.record.ID}'`,
586
- OrderBy: 'StartedAt',
1045
+ OrderBy: 'RunAt',
587
1046
  ResultType: 'entity_object'
588
1047
  }
589
1048
  ]);
@@ -594,15 +1053,21 @@ let TestRunFormComponentExtended = class TestRunFormComponentExtended extends Te
594
1053
  this.aiPromptRuns = promptRuns.Results || [];
595
1054
  }
596
1055
  this.aiRunsLoaded = true;
597
- this.cdr.markForCheck();
598
1056
  }
599
1057
  catch (error) {
600
1058
  console.error('Error loading AI runs:', error);
1059
+ SharedService.Instance.CreateSimpleNotification('Failed to load AI runs', 'error', 3000);
1060
+ }
1061
+ finally {
1062
+ this.loadingAIRuns = false;
1063
+ this.cdr.markForCheck();
601
1064
  }
602
1065
  }
603
1066
  async loadFeedback() {
604
1067
  if (this.feedbackLoaded)
605
1068
  return;
1069
+ this.loadingFeedback = true;
1070
+ this.cdr.markForCheck();
606
1071
  try {
607
1072
  const rv = new RunView();
608
1073
  const result = await rv.RunView({
@@ -615,10 +1080,14 @@ let TestRunFormComponentExtended = class TestRunFormComponentExtended extends Te
615
1080
  this.feedbacks = result.Results || [];
616
1081
  }
617
1082
  this.feedbackLoaded = true;
618
- this.cdr.markForCheck();
619
1083
  }
620
1084
  catch (error) {
621
1085
  console.error('Error loading feedback:', error);
1086
+ SharedService.Instance.CreateSimpleNotification('Failed to load feedback', 'error', 3000);
1087
+ }
1088
+ finally {
1089
+ this.loadingFeedback = false;
1090
+ this.cdr.markForCheck();
622
1091
  }
623
1092
  }
624
1093
  parseJsonFields() {
@@ -657,26 +1126,31 @@ let TestRunFormComponentExtended = class TestRunFormComponentExtended extends Te
657
1126
  }
658
1127
  getStatusColor() {
659
1128
  switch (this.record.Status) {
660
- case 'Passed': return '#4caf50';
661
- case 'Failed': return '#f44336';
662
- case 'Error': return '#ff9800';
663
- case 'Running': return '#2196f3';
664
- case 'Pending': return '#ffc107';
665
- case 'Skipped': return '#9e9e9e';
666
- default: return '#999';
1129
+ case 'Passed': return '#10b981';
1130
+ case 'Failed': return '#ef4444';
1131
+ case 'Error': return '#f59e0b';
1132
+ case 'Timeout': return '#f97316';
1133
+ case 'Running': return '#3b82f6';
1134
+ case 'Pending': return '#8b5cf6';
1135
+ case 'Skipped': return '#6b7280';
1136
+ default: return '#9ca3af';
667
1137
  }
668
1138
  }
669
1139
  getStatusIcon() {
670
1140
  switch (this.record.Status) {
671
1141
  case 'Passed': return 'fa-check-circle';
672
1142
  case 'Failed': return 'fa-times-circle';
673
- case 'Error': return 'fa-exclamation-circle';
674
- case 'Running': return 'fa-spinner fa-spin';
675
- case 'Pending': return 'fa-clock';
1143
+ case 'Error': return 'fa-exclamation-triangle';
1144
+ case 'Timeout': return 'fa-stopwatch';
1145
+ case 'Running': return 'fa-circle-notch fa-spin';
1146
+ case 'Pending': return 'fa-hourglass-half';
676
1147
  case 'Skipped': return 'fa-forward';
677
1148
  default: return 'fa-question-circle';
678
1149
  }
679
1150
  }
1151
+ getStatusClass() {
1152
+ return `status-${this.record.Status?.toLowerCase() || 'unknown'}`;
1153
+ }
680
1154
  calculateDuration() {
681
1155
  if (!this.record.DurationSeconds)
682
1156
  return 'N/A';
@@ -702,11 +1176,29 @@ let TestRunFormComponentExtended = class TestRunFormComponentExtended extends Te
702
1176
  return 'N/A';
703
1177
  return `$${cost.toFixed(6)}`;
704
1178
  }
1179
+ getScorePercentage() {
1180
+ if (this.record.Score === null || this.record.Score === undefined)
1181
+ return 0;
1182
+ return Math.round(this.record.Score * 100);
1183
+ }
1184
+ getPassRatePercentage() {
1185
+ const total = this.record.TotalChecks || 0;
1186
+ const passed = this.record.PassedChecks || 0;
1187
+ if (total === 0)
1188
+ return 0;
1189
+ return Math.round((passed / total) * 100);
1190
+ }
705
1191
  openTest() {
706
1192
  if (this.test) {
707
1193
  SharedService.Instance.OpenEntityRecord('MJ: Tests', CompositeKey.FromID(this.test.ID));
708
1194
  }
709
1195
  }
1196
+ navigateToTestingDashboard() {
1197
+ const testingApp = this.appManager.GetAppByName('Testing');
1198
+ if (testingApp) {
1199
+ this.navigationService.SwitchToApp(testingApp.ID);
1200
+ }
1201
+ }
710
1202
  openTestSuiteRun() {
711
1203
  if (this.testSuiteRun) {
712
1204
  SharedService.Instance.OpenEntityRecord('MJ: Test Suite Runs', CompositeKey.FromID(this.testSuiteRun.ID));
@@ -719,25 +1211,62 @@ let TestRunFormComponentExtended = class TestRunFormComponentExtended extends Te
719
1211
  SharedService.Instance.OpenEntityRecord('MJ: AI Prompt Runs', CompositeKey.FromID(runId));
720
1212
  }
721
1213
  async reRunTest() {
722
- // TODO: Implement test re-run functionality
723
- console.log('Re-run test:', this.record.TestID);
1214
+ if (!this.record.TestID) {
1215
+ SharedService.Instance.CreateSimpleNotification('Cannot re-run: Test ID not available', 'error', 3000);
1216
+ return;
1217
+ }
1218
+ this.testingDialogService.OpenTestDialog(this.record.TestID, this.viewContainerRef);
724
1219
  }
725
1220
  async refresh() {
726
- await this.loadRelatedData();
1221
+ this.isRefreshing = true;
727
1222
  this.cdr.markForCheck();
1223
+ try {
1224
+ await this.record.Load(this.record.ID);
1225
+ await this.loadRelatedData();
1226
+ this.parseJsonFields();
1227
+ // Reset lazy-loaded data to force reload
1228
+ this.aiRunsLoaded = false;
1229
+ this.feedbackLoaded = false;
1230
+ this.aiAgentRuns = [];
1231
+ this.aiPromptRuns = [];
1232
+ this.feedbacks = [];
1233
+ // Reload current tab data if needed
1234
+ if (this.activeTab === 'ai-runs') {
1235
+ await this.loadAIRuns();
1236
+ }
1237
+ else if (this.activeTab === 'feedback') {
1238
+ await this.loadFeedback();
1239
+ }
1240
+ SharedService.Instance.CreateSimpleNotification('Refreshed successfully', 'success', 2000);
1241
+ }
1242
+ catch {
1243
+ SharedService.Instance.CreateSimpleNotification('Failed to refresh', 'error', 3000);
1244
+ }
1245
+ finally {
1246
+ this.isRefreshing = false;
1247
+ this.cdr.markForCheck();
1248
+ }
728
1249
  }
729
1250
  getComparisonData() {
1251
+ let data;
730
1252
  switch (this.comparisonView) {
731
- case 'input': return this.parsedData.input;
732
- case 'expected': return this.parsedData.expected;
733
- case 'actual': return this.parsedData.actual;
734
- default: return null;
1253
+ case 'input':
1254
+ data = this.parsedData.input;
1255
+ break;
1256
+ case 'expected':
1257
+ data = this.parsedData.expected;
1258
+ break;
1259
+ case 'actual':
1260
+ data = this.parsedData.actual;
1261
+ break;
735
1262
  }
1263
+ return data ? JSON.stringify(data, null, 2) : '// No data available';
736
1264
  }
737
1265
  getCheckResults() {
738
- if (!this.parsedData.resultDetails?.checkResults)
1266
+ const details = this.parsedData.resultDetails;
1267
+ if (!details?.checkResults)
739
1268
  return [];
740
- return this.parsedData.resultDetails.checkResults;
1269
+ return details.checkResults;
741
1270
  }
742
1271
  getPassRate() {
743
1272
  const total = this.record.TotalChecks || 0;
@@ -746,155 +1275,272 @@ let TestRunFormComponentExtended = class TestRunFormComponentExtended extends Te
746
1275
  return 0;
747
1276
  return (passed / total) * 100;
748
1277
  }
749
- static { this.ɵfac = function TestRunFormComponentExtended_Factory(t) { return new (t || TestRunFormComponentExtended)(i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i1.SharedService), i0.ɵɵdirectiveInject(i2.Router), i0.ɵɵdirectiveInject(i2.ActivatedRoute), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); }; }
750
- static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TestRunFormComponentExtended, selectors: [["mj-test-run-form"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 89, vars: 39, consts: [[1, "test-run-form"], [1, "test-run-header"], [1, "breadcrumb"], ["href", "javascript:void(0)", 3, "click", 4, "ngIf"], ["class", "fas fa-chevron-right", 4, "ngIf"], [1, "header-content"], [1, "header-left"], [1, "test-run-icon"], [1, "fas", "fa-flask"], [1, "test-run-info"], [1, "test-run-meta"], [1, "status-badge"], [1, "fas", 3, "ngClass"], ["class", "test-type", 4, "ngIf"], [1, "header-actions"], ["kendoButton", "", "icon", "refresh", 3, "click"], ["kendoButton", "", "icon", "sync", 3, "click"], [1, "metrics-bar"], [1, "metric-card"], [1, "metric-label"], [1, "metric-value"], [1, "secondary-metrics"], [1, "metric-item"], ["class", "metric-item", 4, "ngIf"], [1, "tabs-container"], [1, "tabs"], [1, "tab", 3, "click"], [1, "fas", "fa-th-large"], [1, "fas", "fa-list"], [1, "fas", "fa-robot"], ["class", "tab-badge", 4, "ngIf"], [1, "fas", "fa-comments"], [1, "tab-content"], ["class", "overview-tab", 4, "ngIf"], ["class", "details-tab", 4, "ngIf"], ["class", "ai-runs-tab", 4, "ngIf"], ["class", "feedback-tab", 4, "ngIf"], ["href", "javascript:void(0)", 3, "click"], [1, "fas", "fa-chevron-right"], [1, "test-type"], [1, "tab-badge"], [1, "overview-tab"], [1, "result-hero"], [1, "result-icon"], [1, "result-text"], [1, "result-score"], [1, "result-checks"], ["class", "check-results", 4, "ngIf"], [1, "comparison-section"], [1, "comparison-tabs"], [1, "comparison-tab", 3, "click"], [1, "comparison-content"], [1, "check-results"], [1, "check-list"], ["class", "check-item", 3, "passed", "failed", 4, "ngFor", "ngForOf"], [1, "check-item"], [1, "check-icon"], [1, "fas"], [1, "check-content"], [1, "check-name"], [1, "check-details"], ["class", "check-weight", 4, "ngIf"], [1, "check-weight"], [1, "details-tab"], [1, "details-grid"], [1, "detail-item"], [1, "detail-label"], [1, "detail-value"], ["class", "error-message", 4, "ngIf"], ["class", "result-details-json", 4, "ngIf"], [1, "error-message"], [1, "result-details-json"], [1, "ai-runs-tab"], ["class", "ai-runs-section", 4, "ngIf"], ["class", "no-data", 4, "ngIf"], [1, "ai-runs-section"], [1, "ai-run-list"], ["class", "ai-run-card", 3, "click", 4, "ngFor", "ngForOf"], [1, "ai-run-card", 3, "click"], [1, "ai-run-icon"], [1, "ai-run-content"], [1, "ai-run-name"], [1, "ai-run-meta"], [4, "ngIf"], [1, "fas", "fa-external-link-alt"], [1, "ai-run-icon", "prompt"], [1, "fas", "fa-comment-dots"], [1, "no-data"], [1, "fas", "fa-inbox"], [1, "feedback-tab"], ["class", "feedback-list", 4, "ngIf"], [1, "feedback-list"], ["class", "feedback-item", 4, "ngFor", "ngForOf"], [1, "feedback-item"], [1, "feedback-header"], [1, "feedback-user"], [1, "fas", "fa-user"], [1, "feedback-date"], [1, "feedback-rating"], ["class", "feedback-correct", 4, "ngIf"], ["class", "feedback-comments", 4, "ngIf"], [1, "feedback-correct"], [1, "feedback-comments"]], template: function TestRunFormComponentExtended_Template(rf, ctx) { if (rf & 1) {
751
- i0.ɵɵelementStart(0, "div", 0)(1, "div", 1)(2, "div", 2);
752
- i0.ɵɵtemplate(3, TestRunFormComponentExtended_a_3_Template, 3, 1, "a", 3)(4, TestRunFormComponentExtended_i_4_Template, 1, 0, "i", 4);
753
- i0.ɵɵelementStart(5, "span");
754
- i0.ɵɵtext(6);
1278
+ async copyLogToClipboard() {
1279
+ if (this.record.Log) {
1280
+ try {
1281
+ await navigator.clipboard.writeText(this.record.Log);
1282
+ SharedService.Instance.CreateSimpleNotification('Log copied to clipboard', 'success', 2000);
1283
+ }
1284
+ catch {
1285
+ SharedService.Instance.CreateSimpleNotification('Failed to copy log', 'error', 2000);
1286
+ }
1287
+ }
1288
+ }
1289
+ getFormattedResultDetails() {
1290
+ return this.parsedData.resultDetails
1291
+ ? JSON.stringify(this.parsedData.resultDetails, null, 2)
1292
+ : '// No result details available';
1293
+ }
1294
+ // Helper for relative time display
1295
+ getRelativeTime(date) {
1296
+ if (!date)
1297
+ return 'N/A';
1298
+ const d = new Date(date);
1299
+ const now = new Date();
1300
+ const diffMs = now.getTime() - d.getTime();
1301
+ const diffMins = Math.floor(diffMs / 60000);
1302
+ const diffHours = Math.floor(diffMs / 3600000);
1303
+ const diffDays = Math.floor(diffMs / 86400000);
1304
+ if (diffMins < 1)
1305
+ return 'Just now';
1306
+ if (diffMins < 60)
1307
+ return `${diffMins}m ago`;
1308
+ if (diffHours < 24)
1309
+ return `${diffHours}h ago`;
1310
+ if (diffDays < 7)
1311
+ return `${diffDays}d ago`;
1312
+ return d.toLocaleDateString();
1313
+ }
1314
+ static { this.ɵfac = function TestRunFormComponentExtended_Factory(t) { return new (t || TestRunFormComponentExtended)(i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i1.SharedService), i0.ɵɵdirectiveInject(i2.Router), i0.ɵɵdirectiveInject(i2.ActivatedRoute), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i3.TestingDialogService), i0.ɵɵdirectiveInject(i1.NavigationService), i0.ɵɵdirectiveInject(i4.ApplicationManager), i0.ɵɵdirectiveInject(i0.ViewContainerRef)); }; }
1315
+ static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TestRunFormComponentExtended, selectors: [["mj-test-run-form"]], hostBindings: function TestRunFormComponentExtended_HostBindings(rf, ctx) { if (rf & 1) {
1316
+ i0.ɵɵlistener("keydown", function TestRunFormComponentExtended_keydown_HostBindingHandler($event) { return ctx.handleKeyboardShortcut($event); }, false, i0.ɵɵresolveDocument);
1317
+ } }, features: [i0.ɵɵInheritDefinitionFeature], decls: 137, vars: 59, consts: [[1, "test-run-form"], ["class", "error-banner", 3, "click", 4, "ngIf"], [1, "test-run-header"], ["aria-label", "Breadcrumb", 1, "breadcrumb"], ["href", "javascript:void(0)", 3, "click"], [1, "fas", "fa-vial"], [1, "breadcrumb-text"], [4, "ngIf"], [1, "current"], [1, "fas", "fa-chevron-right", "separator"], [1, "header-content"], [1, "header-left"], [1, "status-indicator"], [1, "fas", 3, "ngClass"], [1, "test-run-info"], [1, "run-id"], [1, "test-run-meta"], [1, "status-badge"], ["class", "meta-item", 4, "ngIf"], [1, "header-actions"], ["kendoButton", "", "title", "Re-run this test (Cmd+Shift+R)", 3, "click", "disabled"], [1, "fas", "fa-redo"], [1, "btn-text"], ["kendoButton", "", "title", "Refresh (Cmd+R)", 3, "click", "disabled"], [1, "fas", "fa-sync-alt"], [1, "metrics-bar"], [1, "metric-card"], [1, "metric-icon"], [1, "fas", "fa-clock"], [1, "metric-content"], [1, "metric-label"], [1, "metric-value"], [1, "metric-detail"], [1, "fas", "fa-stopwatch"], [1, "fas", "fa-star"], ["class", "metric-progress", 4, "ngIf"], [1, "fas", "fa-check-double"], [1, "fas", "fa-dollar-sign"], ["class", "secondary-info", 4, "ngIf"], ["class", "tags-bar", 4, "ngIf"], ["class", "tags-editor-panel", 4, "ngIf"], [1, "tabs-container"], ["role", "tablist", 1, "tabs"], ["role", "tab", "title", "Press 1", 1, "tab", 3, "click"], [1, "fas", "fa-chart-pie"], ["role", "tab", "title", "Press 2", 1, "tab", 3, "click"], [1, "fas", "fa-info-circle"], ["role", "tab", "title", "Press 3", 1, "tab", 3, "click"], [1, "fas", "fa-robot"], ["class", "tab-badge", 4, "ngIf"], ["role", "tab", "title", "Press 4", 1, "tab", 3, "click"], [1, "fas", "fa-comments"], ["role", "tab", "title", "Press 5", 1, "tab", 3, "click"], [1, "fas", "fa-microchip"], ["class", "tab", "role", "tab", "title", "Press 6", 3, "active", "click", 4, "ngIf"], [1, "tab-content"], ["class", "overview-tab", 4, "ngIf"], ["class", "details-tab", 4, "ngIf"], ["class", "ai-runs-tab", 4, "ngIf"], ["class", "feedback-tab", 4, "ngIf"], ["class", "execution-tab", 4, "ngIf"], ["class", "log-tab", 4, "ngIf"], ["title", "Keyboard Shortcuts", 1, "shortcuts-hint"], [1, "fas", "fa-keyboard"], [1, "shortcuts-popup"], [1, "error-banner", 3, "click"], [1, "fas", "fa-exclamation-triangle"], [1, "retry-btn"], [1, "fas", "fa-flask"], [1, "meta-item"], [1, "fas", "fa-sync-alt", "fa-spin"], [1, "metric-progress"], [1, "progress-bar"], [1, "secondary-info"], ["class", "info-chip", 4, "ngIf"], ["class", "info-chip clickable", 3, "click", 4, "ngIf"], [3, "entityName", "recordId", 4, "ngIf"], [1, "info-chip"], [1, "fas", "fa-user"], [1, "info-chip", "clickable", 3, "click"], [1, "fas", "fa-layer-group"], [3, "entityName", "recordId"], [1, "tags-bar"], [1, "tags-bar-content"], [1, "tags-bar-label"], [1, "fas", "fa-tags"], ["class", "tags-bar-chips", 4, "ngIf"], ["class", "tags-bar-empty", 4, "ngIf"], ["title", "Edit tags", 1, "tags-bar-edit", 3, "click"], [1, "fas", "fa-plus"], [1, "tags-bar-chips"], ["class", "tag-inline", 4, "ngFor", "ngForOf"], [1, "tag-inline"], [1, "tags-bar-empty"], [1, "tags-editor-panel"], [1, "tags-editor-header"], [1, "tags-editor-title"], [1, "tags-editor-body"], [1, "tags-editor-chips"], ["class", "tag-editable", 4, "ngFor", "ngForOf"], ["class", "tags-empty-hint", 4, "ngIf"], [1, "tags-editor-input"], ["type", "text", "placeholder", "Type a tag and press Enter...", 1, "tag-text-input", 3, "ngModelChange", "keyup.enter", "ngModel"], ["kendoButton", "", "fillMode", "flat", 3, "click", "disabled"], [1, "tags-editor-footer"], ["kendoButton", "", "themeColor", "primary", 3, "click", "disabled"], ["class", "fas fa-spinner fa-spin", 4, "ngIf"], ["kendoButton", "", "fillMode", "flat", 3, "click"], [1, "tag-editable"], ["title", "Remove tag", 1, "tag-remove-btn", 3, "click"], [1, "fas", "fa-times"], [1, "tags-empty-hint"], [1, "fas", "fa-spinner", "fa-spin"], [1, "tab-badge"], ["role", "tab", "title", "Press 6", 1, "tab", 3, "click"], [1, "fas", "fa-terminal"], [1, "overview-tab"], [1, "result-hero"], [1, "result-icon-wrapper"], [1, "result-icon"], ["class", "result-pulse", 4, "ngIf"], [1, "result-text"], [1, "result-details"], [1, "result-score"], [1, "result-divider"], [1, "result-checks"], ["class", "check-results", 4, "ngIf"], [1, "comparison-section"], [1, "section-header"], [1, "fas", "fa-exchange-alt"], [1, "comparison-tabs"], [1, "comparison-tab", 3, "click"], [1, "fas", "fa-sign-in-alt"], [1, "fas", "fa-bullseye"], [1, "fas", "fa-check-square"], [1, "comparison-content"], ["language", "json", 3, "value", "readonly", "toolbar", "lineWrapping"], [1, "result-pulse"], [1, "check-results"], [1, "fas", "fa-tasks"], [1, "check-summary"], [1, "check-list"], ["class", "check-item", 3, "passed", "failed", "animation-delay", 4, "ngFor", "ngForOf"], [1, "check-item"], [1, "check-status"], [1, "fas"], [1, "check-content"], [1, "check-name"], ["class", "check-message", 4, "ngIf"], ["class", "check-weight", 4, "ngIf"], [1, "check-message"], [1, "check-weight"], [1, "weight-label"], [1, "details-tab"], [1, "details-grid"], [1, "detail-card"], [1, "detail-icon"], [1, "fas", "fa-fingerprint"], [1, "detail-content"], [1, "detail-label"], [1, "detail-value", "monospace"], ["class", "detail-card clickable", 3, "click", 4, "ngIf"], [1, "fas", "fa-tag"], [1, "detail-value"], [1, "fas", "fa-play-circle"], [1, "fas", "fa-stop-circle"], [1, "fas", "fa-hourglass-half"], ["class", "error-section", 4, "ngIf"], ["class", "result-details-section", 4, "ngIf"], [1, "detail-card", "clickable", 3, "click"], [1, "detail-value", "link"], [1, "fas", "fa-external-link-alt", "detail-action"], [1, "error-section"], [1, "section-header", "error"], [1, "error-content"], [3, "value", "readonly", "toolbar", "lineWrapping"], [1, "result-details-section"], [1, "fas", "fa-file-code"], [1, "result-details-content"], [1, "ai-runs-tab"], ["class", "loading-state", 4, "ngIf"], ["class", "ai-section", 4, "ngIf"], ["class", "empty-state", 4, "ngIf"], [1, "loading-state"], [1, "skeleton-list"], ["class", "skeleton-card", 4, "ngFor", "ngForOf"], [1, "skeleton-card"], [1, "skeleton-icon"], [1, "skeleton-content"], [1, "skeleton-line", "wide"], [1, "skeleton-line", "narrow"], [1, "ai-section"], [1, "count-badge"], [1, "ai-run-list"], ["class", "ai-run-card", 3, "click", 4, "ngFor", "ngForOf"], [1, "ai-run-card", 3, "click"], [1, "ai-run-icon", "agent"], [1, "ai-run-content"], [1, "ai-run-name"], [1, "ai-run-meta"], [1, "status-chip"], ["class", "cost-chip", 4, "ngIf"], [1, "fas", "fa-chevron-right", "ai-run-arrow"], [1, "cost-chip"], [1, "fas", "fa-comment-dots"], [1, "ai-run-icon", "prompt"], [1, "empty-state"], [1, "empty-icon"], [1, "feedback-tab"], ["class", "feedback-list", 4, "ngIf"], [1, "skeleton-avatar"], [1, "skeleton-line", "medium"], [1, "feedback-list"], ["class", "feedback-item", 4, "ngFor", "ngForOf"], [1, "feedback-item"], [1, "feedback-header"], [1, "feedback-user"], [1, "user-avatar"], [1, "user-name"], [1, "feedback-date"], [1, "feedback-body"], [1, "feedback-rating"], [1, "rating-stars"], ["class", "fas fa-star", 3, "filled", 4, "ngFor", "ngForOf"], [1, "rating-value"], ["class", "feedback-verdict", 4, "ngIf"], ["class", "feedback-comments", 4, "ngIf"], [1, "feedback-verdict"], [1, "verdict-badge"], [1, "feedback-comments"], [1, "execution-tab"], [3, "machineName", "machineId", "runByUserName", "runByUserEmail", "runContextDetailsJson"], [1, "log-tab"], [1, "log-header"], [1, "log-title"], [1, "log-actions"], ["kendoButton", "", "look", "flat", 3, "click"], [1, "fas", "fa-copy"], [1, "log-container"]], template: function TestRunFormComponentExtended_Template(rf, ctx) { if (rf & 1) {
1318
+ i0.ɵɵelementStart(0, "div", 0);
1319
+ i0.ɵɵtemplate(1, TestRunFormComponentExtended_div_1_Template, 7, 1, "div", 1);
1320
+ i0.ɵɵelementStart(2, "div", 2)(3, "nav", 3)(4, "ol")(5, "li")(6, "a", 4);
1321
+ i0.ɵɵlistener("click", function TestRunFormComponentExtended_Template_a_click_6_listener() { return ctx.navigateToTestingDashboard(); });
1322
+ i0.ɵɵelement(7, "i", 5);
1323
+ i0.ɵɵelementStart(8, "span", 6);
1324
+ i0.ɵɵtext(9, "Testing");
1325
+ i0.ɵɵelementEnd()()();
1326
+ i0.ɵɵtemplate(10, TestRunFormComponentExtended_li_10_Template, 6, 1, "li", 7);
1327
+ i0.ɵɵelementStart(11, "li", 8);
1328
+ i0.ɵɵelement(12, "i", 9);
1329
+ i0.ɵɵelementStart(13, "span");
1330
+ i0.ɵɵtext(14);
1331
+ i0.ɵɵelementEnd()()()();
1332
+ i0.ɵɵelementStart(15, "div", 10)(16, "div", 11)(17, "div", 12);
1333
+ i0.ɵɵelement(18, "i", 13);
1334
+ i0.ɵɵelementEnd();
1335
+ i0.ɵɵelementStart(19, "div", 14)(20, "h1");
1336
+ i0.ɵɵtext(21, " Test Run ");
1337
+ i0.ɵɵelementStart(22, "span", 15);
1338
+ i0.ɵɵtext(23);
755
1339
  i0.ɵɵelementEnd()();
756
- i0.ɵɵelementStart(7, "div", 5)(8, "div", 6)(9, "div", 7);
757
- i0.ɵɵelement(10, "i", 8);
1340
+ i0.ɵɵelementStart(24, "div", 16)(25, "span", 17);
1341
+ i0.ɵɵtext(26);
758
1342
  i0.ɵɵelementEnd();
759
- i0.ɵɵelementStart(11, "div", 9)(12, "h1");
760
- i0.ɵɵtext(13, "Test Run");
1343
+ i0.ɵɵtemplate(27, TestRunFormComponentExtended_span_27_Template, 3, 1, "span", 18)(28, TestRunFormComponentExtended_span_28_Template, 3, 0, "span", 18);
1344
+ i0.ɵɵelementEnd()()();
1345
+ i0.ɵɵelementStart(29, "div", 19)(30, "button", 20);
1346
+ i0.ɵɵlistener("click", function TestRunFormComponentExtended_Template_button_click_30_listener() { return ctx.reRunTest(); });
1347
+ i0.ɵɵelement(31, "i", 21);
1348
+ i0.ɵɵelementStart(32, "span", 22);
1349
+ i0.ɵɵtext(33, "Re-run");
1350
+ i0.ɵɵelementEnd()();
1351
+ i0.ɵɵelementStart(34, "button", 23);
1352
+ i0.ɵɵlistener("click", function TestRunFormComponentExtended_Template_button_click_34_listener() { return ctx.refresh(); });
1353
+ i0.ɵɵelement(35, "i", 24);
1354
+ i0.ɵɵelementStart(36, "span", 22);
1355
+ i0.ɵɵtext(37, "Refresh");
1356
+ i0.ɵɵelementEnd()()()();
1357
+ i0.ɵɵelementStart(38, "div", 25)(39, "div", 26)(40, "div", 27);
1358
+ i0.ɵɵelement(41, "i", 28);
761
1359
  i0.ɵɵelementEnd();
762
- i0.ɵɵelementStart(14, "div", 10)(15, "span", 11);
763
- i0.ɵɵelement(16, "i", 12);
764
- i0.ɵɵtext(17);
1360
+ i0.ɵɵelementStart(42, "div", 29)(43, "div", 30);
1361
+ i0.ɵɵtext(44, "Started");
765
1362
  i0.ɵɵelementEnd();
766
- i0.ɵɵtemplate(18, TestRunFormComponentExtended_span_18_Template, 2, 1, "span", 13);
1363
+ i0.ɵɵelementStart(45, "div", 31);
1364
+ i0.ɵɵtext(46);
1365
+ i0.ɵɵelementEnd();
1366
+ i0.ɵɵelementStart(47, "div", 32);
1367
+ i0.ɵɵtext(48);
1368
+ i0.ɵɵpipe(49, "date");
767
1369
  i0.ɵɵelementEnd()()();
768
- i0.ɵɵelementStart(19, "div", 14)(20, "button", 15);
769
- i0.ɵɵlistener("click", function TestRunFormComponentExtended_Template_button_click_20_listener() { return ctx.reRunTest(); });
770
- i0.ɵɵtext(21, " Re-run Test ");
1370
+ i0.ɵɵelementStart(50, "div", 26)(51, "div", 27);
1371
+ i0.ɵɵelement(52, "i", 33);
1372
+ i0.ɵɵelementEnd();
1373
+ i0.ɵɵelementStart(53, "div", 29)(54, "div", 30);
1374
+ i0.ɵɵtext(55, "Duration");
771
1375
  i0.ɵɵelementEnd();
772
- i0.ɵɵelementStart(22, "button", 16);
773
- i0.ɵɵlistener("click", function TestRunFormComponentExtended_Template_button_click_22_listener() { return ctx.refresh(); });
774
- i0.ɵɵtext(23, " Refresh ");
1376
+ i0.ɵɵelementStart(56, "div", 31);
1377
+ i0.ɵɵtext(57);
775
1378
  i0.ɵɵelementEnd()()();
776
- i0.ɵɵelementStart(24, "div", 17)(25, "div", 18)(26, "div", 19);
777
- i0.ɵɵtext(27, "Started");
1379
+ i0.ɵɵelementStart(58, "div", 26)(59, "div", 27);
1380
+ i0.ɵɵelement(60, "i", 34);
778
1381
  i0.ɵɵelementEnd();
779
- i0.ɵɵelementStart(28, "div", 20);
780
- i0.ɵɵtext(29);
781
- i0.ɵɵpipe(30, "date");
782
- i0.ɵɵelementEnd()();
783
- i0.ɵɵelementStart(31, "div", 18)(32, "div", 19);
784
- i0.ɵɵtext(33, "Completed");
1382
+ i0.ɵɵelementStart(61, "div", 29)(62, "div", 30);
1383
+ i0.ɵɵtext(63, "Score");
785
1384
  i0.ɵɵelementEnd();
786
- i0.ɵɵelementStart(34, "div", 20);
787
- i0.ɵɵtext(35);
788
- i0.ɵɵpipe(36, "date");
789
- i0.ɵɵelementEnd()();
790
- i0.ɵɵelementStart(37, "div", 18)(38, "div", 19);
791
- i0.ɵɵtext(39, "Duration");
1385
+ i0.ɵɵelementStart(64, "div", 31);
1386
+ i0.ɵɵtext(65);
792
1387
  i0.ɵɵelementEnd();
793
- i0.ɵɵelementStart(40, "div", 20);
794
- i0.ɵɵtext(41);
1388
+ i0.ɵɵtemplate(66, TestRunFormComponentExtended_div_66_Template, 2, 4, "div", 35);
795
1389
  i0.ɵɵelementEnd()();
796
- i0.ɵɵelementStart(42, "div", 18)(43, "div", 19);
797
- i0.ɵɵtext(44, "Score");
1390
+ i0.ɵɵelementStart(67, "div", 26)(68, "div", 27);
1391
+ i0.ɵɵelement(69, "i", 36);
798
1392
  i0.ɵɵelementEnd();
799
- i0.ɵɵelementStart(45, "div", 20);
800
- i0.ɵɵtext(46);
801
- i0.ɵɵelementEnd()();
802
- i0.ɵɵelementStart(47, "div", 18)(48, "div", 19);
803
- i0.ɵɵtext(49, "Cost");
1393
+ i0.ɵɵelementStart(70, "div", 29)(71, "div", 30);
1394
+ i0.ɵɵtext(72, "Checks");
804
1395
  i0.ɵɵelementEnd();
805
- i0.ɵɵelementStart(50, "div", 20);
806
- i0.ɵɵtext(51);
807
- i0.ɵɵelementEnd()()();
808
- i0.ɵɵelementStart(52, "div", 21)(53, "div", 22)(54, "span", 19);
809
- i0.ɵɵtext(55, "Checks:");
1396
+ i0.ɵɵelementStart(73, "div", 31);
1397
+ i0.ɵɵtext(74);
810
1398
  i0.ɵɵelementEnd();
811
- i0.ɵɵelementStart(56, "span", 20);
812
- i0.ɵɵtext(57);
1399
+ i0.ɵɵtemplate(75, TestRunFormComponentExtended_div_75_Template, 2, 4, "div", 35);
813
1400
  i0.ɵɵelementEnd()();
814
- i0.ɵɵelementStart(58, "div", 22)(59, "span", 19);
815
- i0.ɵɵtext(60, "Run By:");
1401
+ i0.ɵɵelementStart(76, "div", 26)(77, "div", 27);
1402
+ i0.ɵɵelement(78, "i", 37);
816
1403
  i0.ɵɵelementEnd();
817
- i0.ɵɵelementStart(61, "span", 20);
818
- i0.ɵɵtext(62);
1404
+ i0.ɵɵelementStart(79, "div", 29)(80, "div", 30);
1405
+ i0.ɵɵtext(81, "Cost");
1406
+ i0.ɵɵelementEnd();
1407
+ i0.ɵɵelementStart(82, "div", 31);
1408
+ i0.ɵɵtext(83);
1409
+ i0.ɵɵelementEnd()()()();
1410
+ i0.ɵɵtemplate(84, TestRunFormComponentExtended_div_84_Template, 4, 3, "div", 38)(85, TestRunFormComponentExtended_div_85_Template, 9, 2, "div", 39)(86, TestRunFormComponentExtended_div_86_Template, 19, 7, "div", 40);
1411
+ i0.ɵɵelementEnd();
1412
+ i0.ɵɵelementStart(87, "div", 41)(88, "div", 42)(89, "button", 43);
1413
+ i0.ɵɵlistener("click", function TestRunFormComponentExtended_Template_button_click_89_listener() { return ctx.changeTab("overview"); });
1414
+ i0.ɵɵelement(90, "i", 44);
1415
+ i0.ɵɵelementStart(91, "span");
1416
+ i0.ɵɵtext(92, "Overview");
819
1417
  i0.ɵɵelementEnd()();
820
- i0.ɵɵtemplate(63, TestRunFormComponentExtended_div_63_Template, 5, 2, "div", 23);
1418
+ i0.ɵɵelementStart(93, "button", 45);
1419
+ i0.ɵɵlistener("click", function TestRunFormComponentExtended_Template_button_click_93_listener() { return ctx.changeTab("details"); });
1420
+ i0.ɵɵelement(94, "i", 46);
1421
+ i0.ɵɵelementStart(95, "span");
1422
+ i0.ɵɵtext(96, "Details");
821
1423
  i0.ɵɵelementEnd()();
822
- i0.ɵɵelementStart(64, "div", 24)(65, "div", 25)(66, "button", 26);
823
- i0.ɵɵlistener("click", function TestRunFormComponentExtended_Template_button_click_66_listener() { return ctx.changeTab("overview"); });
824
- i0.ɵɵelement(67, "i", 27);
825
- i0.ɵɵelementStart(68, "span");
826
- i0.ɵɵtext(69, "Overview");
1424
+ i0.ɵɵelementStart(97, "button", 47);
1425
+ i0.ɵɵlistener("click", function TestRunFormComponentExtended_Template_button_click_97_listener() { return ctx.changeTab("ai-runs"); });
1426
+ i0.ɵɵelement(98, "i", 48);
1427
+ i0.ɵɵelementStart(99, "span");
1428
+ i0.ɵɵtext(100, "AI Runs");
1429
+ i0.ɵɵelementEnd();
1430
+ i0.ɵɵtemplate(101, TestRunFormComponentExtended_span_101_Template, 2, 1, "span", 49);
1431
+ i0.ɵɵelementEnd();
1432
+ i0.ɵɵelementStart(102, "button", 50);
1433
+ i0.ɵɵlistener("click", function TestRunFormComponentExtended_Template_button_click_102_listener() { return ctx.changeTab("feedback"); });
1434
+ i0.ɵɵelement(103, "i", 51);
1435
+ i0.ɵɵelementStart(104, "span");
1436
+ i0.ɵɵtext(105, "Feedback");
1437
+ i0.ɵɵelementEnd();
1438
+ i0.ɵɵtemplate(106, TestRunFormComponentExtended_span_106_Template, 2, 1, "span", 49);
1439
+ i0.ɵɵelementEnd();
1440
+ i0.ɵɵelementStart(107, "button", 52);
1441
+ i0.ɵɵlistener("click", function TestRunFormComponentExtended_Template_button_click_107_listener() { return ctx.changeTab("execution"); });
1442
+ i0.ɵɵelement(108, "i", 53);
1443
+ i0.ɵɵelementStart(109, "span");
1444
+ i0.ɵɵtext(110, "Execution");
827
1445
  i0.ɵɵelementEnd()();
828
- i0.ɵɵelementStart(70, "button", 26);
829
- i0.ɵɵlistener("click", function TestRunFormComponentExtended_Template_button_click_70_listener() { return ctx.changeTab("details"); });
830
- i0.ɵɵelement(71, "i", 28);
831
- i0.ɵɵelementStart(72, "span");
832
- i0.ɵɵtext(73, "Details");
1446
+ i0.ɵɵtemplate(111, TestRunFormComponentExtended_button_111_Template, 4, 3, "button", 54);
833
1447
  i0.ɵɵelementEnd()();
834
- i0.ɵɵelementStart(74, "button", 26);
835
- i0.ɵɵlistener("click", function TestRunFormComponentExtended_Template_button_click_74_listener() { return ctx.changeTab("ai-runs"); });
836
- i0.ɵɵelement(75, "i", 29);
837
- i0.ɵɵelementStart(76, "span");
838
- i0.ɵɵtext(77, "AI Runs");
1448
+ i0.ɵɵelementStart(112, "div", 55);
1449
+ i0.ɵɵtemplate(113, TestRunFormComponentExtended_div_113_Template, 34, 20, "div", 56)(114, TestRunFormComponentExtended_div_114_Template, 47, 15, "div", 57)(115, TestRunFormComponentExtended_div_115_Template, 5, 5, "div", 58)(116, TestRunFormComponentExtended_div_116_Template, 4, 4, "div", 59)(117, TestRunFormComponentExtended_div_117_Template, 2, 6, "div", 60)(118, TestRunFormComponentExtended_div_118_Template, 13, 5, "div", 61);
839
1450
  i0.ɵɵelementEnd();
840
- i0.ɵɵtemplate(78, TestRunFormComponentExtended_span_78_Template, 2, 1, "span", 30);
1451
+ i0.ɵɵelementStart(119, "div", 62);
1452
+ i0.ɵɵelement(120, "i", 63);
1453
+ i0.ɵɵelementStart(121, "div", 64)(122, "h4");
1454
+ i0.ɵɵtext(123, "Keyboard Shortcuts");
841
1455
  i0.ɵɵelementEnd();
842
- i0.ɵɵelementStart(79, "button", 26);
843
- i0.ɵɵlistener("click", function TestRunFormComponentExtended_Template_button_click_79_listener() { return ctx.changeTab("feedback"); });
844
- i0.ɵɵelement(80, "i", 31);
845
- i0.ɵɵelementStart(81, "span");
846
- i0.ɵɵtext(82, "Feedback");
1456
+ i0.ɵɵelementStart(124, "ul")(125, "li")(126, "kbd");
1457
+ i0.ɵɵtext(127, "1-6");
847
1458
  i0.ɵɵelementEnd();
848
- i0.ɵɵtemplate(83, TestRunFormComponentExtended_span_83_Template, 2, 1, "span", 30);
849
- i0.ɵɵelementEnd()()();
850
- i0.ɵɵelementStart(84, "div", 32);
851
- i0.ɵɵtemplate(85, TestRunFormComponentExtended_div_85_Template, 26, 19, "div", 33)(86, TestRunFormComponentExtended_div_86_Template, 66, 20, "div", 34)(87, TestRunFormComponentExtended_div_87_Template, 4, 3, "div", 35)(88, TestRunFormComponentExtended_div_88_Template, 3, 2, "div", 36);
852
- i0.ɵɵelementEnd()();
1459
+ i0.ɵɵtext(128, " Switch tabs");
1460
+ i0.ɵɵelementEnd();
1461
+ i0.ɵɵelementStart(129, "li")(130, "kbd");
1462
+ i0.ɵɵtext(131, "Cmd+R");
1463
+ i0.ɵɵelementEnd();
1464
+ i0.ɵɵtext(132, " Refresh");
1465
+ i0.ɵɵelementEnd();
1466
+ i0.ɵɵelementStart(133, "li")(134, "kbd");
1467
+ i0.ɵɵtext(135, "Cmd+Shift+R");
1468
+ i0.ɵɵelementEnd();
1469
+ i0.ɵɵtext(136, " Re-run test");
1470
+ i0.ɵɵelementEnd()()()()();
853
1471
  } if (rf & 2) {
854
- i0.ɵɵadvance(3);
855
- i0.ɵɵproperty("ngIf", ctx.test);
1472
+ i0.ɵɵclassProp("is-mobile", false);
1473
+ i0.ɵɵadvance();
1474
+ i0.ɵɵproperty("ngIf", ctx.error);
856
1475
  i0.ɵɵadvance();
1476
+ i0.ɵɵclassMap(ctx.getStatusClass());
1477
+ i0.ɵɵadvance(8);
857
1478
  i0.ɵɵproperty("ngIf", ctx.test);
858
- i0.ɵɵadvance(2);
1479
+ i0.ɵɵadvance(4);
859
1480
  i0.ɵɵtextInterpolate1("Run #", ctx.record.ID.substring(0, 8), "");
860
1481
  i0.ɵɵadvance(3);
861
1482
  i0.ɵɵstyleProp("background-color", ctx.getStatusColor());
862
- i0.ɵɵadvance(6);
863
- i0.ɵɵstyleProp("background-color", ctx.getStatusColor());
864
1483
  i0.ɵɵadvance();
865
1484
  i0.ɵɵproperty("ngClass", ctx.getStatusIcon());
1485
+ i0.ɵɵadvance(5);
1486
+ i0.ɵɵtextInterpolate1("#", ctx.record.ID.substring(0, 8), "");
1487
+ i0.ɵɵadvance(2);
1488
+ i0.ɵɵstyleProp("background-color", ctx.getStatusColor());
866
1489
  i0.ɵɵadvance();
867
1490
  i0.ɵɵtextInterpolate1(" ", ctx.record.Status, " ");
868
1491
  i0.ɵɵadvance();
869
1492
  i0.ɵɵproperty("ngIf", ctx.test);
1493
+ i0.ɵɵadvance();
1494
+ i0.ɵɵproperty("ngIf", ctx.autoRefreshEnabled);
1495
+ i0.ɵɵadvance(2);
1496
+ i0.ɵɵproperty("disabled", !ctx.record.TestID);
1497
+ i0.ɵɵadvance(4);
1498
+ i0.ɵɵproperty("disabled", ctx.isRefreshing);
1499
+ i0.ɵɵadvance();
1500
+ i0.ɵɵclassProp("fa-spin", ctx.isRefreshing);
870
1501
  i0.ɵɵadvance(11);
871
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(30, 33, ctx.record.StartedAt, "short"));
872
- i0.ɵɵadvance(6);
873
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(36, 36, ctx.record.CompletedAt, "short"));
874
- i0.ɵɵadvance(6);
1502
+ i0.ɵɵtextInterpolate(ctx.getRelativeTime(ctx.record.StartedAt));
1503
+ i0.ɵɵadvance(2);
1504
+ i0.ɵɵtextInterpolate(i0.ɵɵpipeBind2(49, 56, ctx.record.StartedAt, "short"));
1505
+ i0.ɵɵadvance(9);
875
1506
  i0.ɵɵtextInterpolate(ctx.calculateDuration());
876
- i0.ɵɵadvance(5);
1507
+ i0.ɵɵadvance(8);
877
1508
  i0.ɵɵtextInterpolate(ctx.formatScore(ctx.record.Score));
878
- i0.ɵɵadvance(5);
879
- i0.ɵɵtextInterpolate(ctx.formatCost(ctx.record.CostUSD));
880
- i0.ɵɵadvance(6);
1509
+ i0.ɵɵadvance();
1510
+ i0.ɵɵproperty("ngIf", ctx.record.Score != null);
1511
+ i0.ɵɵadvance(8);
881
1512
  i0.ɵɵtextInterpolate2("", ctx.record.PassedChecks, "/", ctx.record.TotalChecks, "");
882
- i0.ɵɵadvance(5);
883
- i0.ɵɵtextInterpolate(ctx.record.RunByUser);
884
1513
  i0.ɵɵadvance();
885
- i0.ɵɵproperty("ngIf", ctx.testSuiteRun);
1514
+ i0.ɵɵproperty("ngIf", ctx.record.TotalChecks);
1515
+ i0.ɵɵadvance(8);
1516
+ i0.ɵɵtextInterpolate(ctx.formatCost(ctx.record.CostUSD));
1517
+ i0.ɵɵadvance();
1518
+ i0.ɵɵproperty("ngIf", ctx.record.RunByUser || ctx.testSuiteRun || ctx.record.TargetLogEntityID);
1519
+ i0.ɵɵadvance();
1520
+ i0.ɵɵproperty("ngIf", !ctx.editingTags);
1521
+ i0.ɵɵadvance();
1522
+ i0.ɵɵproperty("ngIf", ctx.editingTags);
886
1523
  i0.ɵɵadvance(3);
887
1524
  i0.ɵɵclassProp("active", ctx.activeTab === "overview");
1525
+ i0.ɵɵattribute("aria-selected", ctx.activeTab === "overview");
888
1526
  i0.ɵɵadvance(4);
889
1527
  i0.ɵɵclassProp("active", ctx.activeTab === "details");
1528
+ i0.ɵɵattribute("aria-selected", ctx.activeTab === "details");
890
1529
  i0.ɵɵadvance(4);
891
1530
  i0.ɵɵclassProp("active", ctx.activeTab === "ai-runs");
1531
+ i0.ɵɵattribute("aria-selected", ctx.activeTab === "ai-runs");
892
1532
  i0.ɵɵadvance(4);
893
1533
  i0.ɵɵproperty("ngIf", ctx.aiRunsLoaded);
894
1534
  i0.ɵɵadvance();
895
1535
  i0.ɵɵclassProp("active", ctx.activeTab === "feedback");
1536
+ i0.ɵɵattribute("aria-selected", ctx.activeTab === "feedback");
896
1537
  i0.ɵɵadvance(4);
897
1538
  i0.ɵɵproperty("ngIf", ctx.feedbackLoaded);
1539
+ i0.ɵɵadvance();
1540
+ i0.ɵɵclassProp("active", ctx.activeTab === "execution");
1541
+ i0.ɵɵattribute("aria-selected", ctx.activeTab === "execution");
1542
+ i0.ɵɵadvance(4);
1543
+ i0.ɵɵproperty("ngIf", ctx.record.Log);
898
1544
  i0.ɵɵadvance(2);
899
1545
  i0.ɵɵproperty("ngIf", ctx.activeTab === "overview");
900
1546
  i0.ɵɵadvance();
@@ -903,7 +1549,11 @@ let TestRunFormComponentExtended = class TestRunFormComponentExtended extends Te
903
1549
  i0.ɵɵproperty("ngIf", ctx.activeTab === "ai-runs");
904
1550
  i0.ɵɵadvance();
905
1551
  i0.ɵɵproperty("ngIf", ctx.activeTab === "feedback");
906
- } }, dependencies: [i3.NgClass, i3.NgForOf, i3.NgIf, i4.ButtonComponent, i3.JsonPipe, i3.DatePipe], styles: [".test-run-form[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: #f8f9fa;\n}\n\n\n\n.test-run-header[_ngcontent-%COMP%] {\n background: white;\n border-bottom: 1px solid #e0e0e0;\n padding: 20px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n color: #666;\n margin-bottom: 16px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] a[_ngcontent-%COMP%] {\n color: #2196f3;\n text-decoration: none;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] a[_ngcontent-%COMP%]:hover {\n text-decoration: underline;\n}\n\n.header-content[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 20px;\n}\n\n.header-left[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n}\n\n.test-run-icon[_ngcontent-%COMP%] {\n width: 56px;\n height: 56px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-size: 24px;\n}\n\n.test-run-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 24px;\n font-weight: 600;\n color: #333;\n}\n\n.test-run-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 12px;\n border-radius: 12px;\n color: white;\n font-size: 12px;\n font-weight: 600;\n}\n\n.test-type[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #666;\n}\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.metrics-bar[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(5, 1fr);\n gap: 16px;\n margin-bottom: 16px;\n}\n\n.metric-card[_ngcontent-%COMP%] {\n background: #f5f7fa;\n border-radius: 8px;\n padding: 12px;\n text-align: center;\n}\n\n.metric-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: #999;\n margin-bottom: 4px;\n}\n\n.metric-value[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 600;\n color: #333;\n}\n\n.secondary-metrics[_ngcontent-%COMP%] {\n display: flex;\n gap: 24px;\n padding-top: 12px;\n border-top: 1px solid #e0e0e0;\n}\n\n.metric-item[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n font-size: 14px;\n}\n\n.metric-item[_ngcontent-%COMP%] .metric-label[_ngcontent-%COMP%] {\n color: #666;\n text-transform: none;\n letter-spacing: normal;\n}\n\n.metric-item[_ngcontent-%COMP%] .metric-value[_ngcontent-%COMP%] {\n color: #333;\n font-weight: 500;\n font-size: 14px;\n}\n\n.metric-item[_ngcontent-%COMP%] a[_ngcontent-%COMP%] {\n color: #2196f3;\n text-decoration: none;\n}\n\n.metric-item[_ngcontent-%COMP%] a[_ngcontent-%COMP%]:hover {\n text-decoration: underline;\n}\n\n\n\n.tabs-container[_ngcontent-%COMP%] {\n background: white;\n border-bottom: 1px solid #e0e0e0;\n}\n\n.tabs[_ngcontent-%COMP%] {\n display: flex;\n padding: 0 20px;\n overflow-x: auto;\n}\n\n.tab[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px 20px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: #666;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.tab[_ngcontent-%COMP%]:hover {\n color: #2196f3;\n background: rgba(33, 150, 243, 0.05);\n}\n\n.tab.active[_ngcontent-%COMP%] {\n color: #2196f3;\n border-bottom-color: #2196f3;\n}\n\n.tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n\n.tab-badge[_ngcontent-%COMP%] {\n background: #e0e0e0;\n color: #666;\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.tab.active[_ngcontent-%COMP%] .tab-badge[_ngcontent-%COMP%] {\n background: #e3f2fd;\n color: #2196f3;\n}\n\n\n\n.tab-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n}\n\n\n\n.overview-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n\n.result-hero[_ngcontent-%COMP%] {\n background: white;\n border-radius: 12px;\n padding: 32px;\n text-align: center;\n border: 3px solid #e0e0e0;\n}\n\n.result-hero.passed[_ngcontent-%COMP%] {\n background: #e8f5e9;\n border-color: #4caf50;\n}\n\n.result-hero.failed[_ngcontent-%COMP%] {\n background: #ffebee;\n border-color: #f44336;\n}\n\n.result-icon[_ngcontent-%COMP%] {\n font-size: 64px;\n margin-bottom: 16px;\n}\n\n.result-hero.passed[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%] {\n color: #4caf50;\n}\n\n.result-hero.failed[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%] {\n color: #f44336;\n}\n\n.result-text[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n font-size: 32px;\n font-weight: 700;\n color: #333;\n}\n\n.result-score[_ngcontent-%COMP%] {\n font-size: 20px;\n font-weight: 600;\n color: #666;\n margin-bottom: 8px;\n}\n\n.result-checks[_ngcontent-%COMP%] {\n font-size: 16px;\n color: #999;\n}\n\n.check-results[_ngcontent-%COMP%] {\n background: white;\n border-radius: 12px;\n padding: 20px;\n}\n\n.check-results[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 18px;\n font-weight: 600;\n color: #333;\n}\n\n.check-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.check-item[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n padding: 12px;\n border-radius: 8px;\n border: 2px solid #e0e0e0;\n}\n\n.check-item.passed[_ngcontent-%COMP%] {\n background: #f1f8f4;\n border-color: #c8e6c9;\n}\n\n.check-item.failed[_ngcontent-%COMP%] {\n background: #fef5f5;\n border-color: #ffcdd2;\n}\n\n.check-icon[_ngcontent-%COMP%] {\n font-size: 20px;\n flex-shrink: 0;\n}\n\n.check-item.passed[_ngcontent-%COMP%] .check-icon[_ngcontent-%COMP%] {\n color: #4caf50;\n}\n\n.check-item.failed[_ngcontent-%COMP%] .check-icon[_ngcontent-%COMP%] {\n color: #f44336;\n}\n\n.check-content[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.check-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: #333;\n margin-bottom: 4px;\n}\n\n.check-details[_ngcontent-%COMP%] {\n font-size: 13px;\n color: #666;\n line-height: 1.4;\n}\n\n.check-weight[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #999;\n margin-top: 4px;\n}\n\n.comparison-section[_ngcontent-%COMP%] {\n background: white;\n border-radius: 12px;\n padding: 20px;\n}\n\n.comparison-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 18px;\n font-weight: 600;\n color: #333;\n}\n\n.comparison-tabs[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n margin-bottom: 16px;\n border-bottom: 2px solid #e0e0e0;\n}\n\n.comparison-tab[_ngcontent-%COMP%] {\n padding: 10px 20px;\n border: none;\n background: transparent;\n color: #666;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n border-bottom: 3px solid transparent;\n margin-bottom: -2px;\n transition: all 0.2s ease;\n}\n\n.comparison-tab[_ngcontent-%COMP%]:hover {\n color: #2196f3;\n}\n\n.comparison-tab.active[_ngcontent-%COMP%] {\n color: #2196f3;\n border-bottom-color: #2196f3;\n}\n\n.comparison-content[_ngcontent-%COMP%] {\n background: #1e1e1e;\n border-radius: 8px;\n padding: 16px;\n max-height: 400px;\n overflow-y: auto;\n}\n\n.comparison-content[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] {\n margin: 0;\n font-family: 'Courier New', monospace;\n font-size: 13px;\n line-height: 1.5;\n color: #e0e0e0;\n white-space: pre-wrap;\n word-wrap: break-word;\n}\n\n\n\n.details-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n\n.details-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 16px;\n background: white;\n border-radius: 12px;\n padding: 20px;\n}\n\n.detail-item[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.detail-label[_ngcontent-%COMP%] {\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: #999;\n}\n\n.detail-value[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #333;\n word-wrap: break-word;\n}\n\n.detail-value[_ngcontent-%COMP%] a[_ngcontent-%COMP%] {\n color: #2196f3;\n text-decoration: none;\n}\n\n.detail-value[_ngcontent-%COMP%] a[_ngcontent-%COMP%]:hover {\n text-decoration: underline;\n}\n\n.error-message[_ngcontent-%COMP%], .result-details-json[_ngcontent-%COMP%] {\n background: white;\n border-radius: 12px;\n padding: 20px;\n}\n\n.error-message[_ngcontent-%COMP%] h4[_ngcontent-%COMP%], .result-details-json[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n font-size: 16px;\n font-weight: 600;\n color: #333;\n}\n\n.error-message[_ngcontent-%COMP%] pre[_ngcontent-%COMP%], .result-details-json[_ngcontent-%COMP%] pre[_ngcontent-%COMP%] {\n margin: 0;\n font-family: 'Courier New', monospace;\n font-size: 13px;\n line-height: 1.5;\n color: #333;\n white-space: pre-wrap;\n word-wrap: break-word;\n background: #f5f7fa;\n padding: 16px;\n border-radius: 8px;\n}\n\n\n\n.ai-runs-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n\n.ai-runs-section[_ngcontent-%COMP%] {\n background: white;\n border-radius: 12px;\n padding: 20px;\n}\n\n.ai-runs-section[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 16px 0;\n font-size: 18px;\n font-weight: 600;\n color: #333;\n}\n\n.ai-run-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.ai-run-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n background: #f8f9fa;\n border: 2px solid transparent;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.ai-run-card[_ngcontent-%COMP%]:hover {\n background: #e3f2fd;\n border-color: #90caf9;\n}\n\n.ai-run-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: #2196f3;\n color: white;\n border-radius: 8px;\n font-size: 18px;\n flex-shrink: 0;\n}\n\n.ai-run-icon.prompt[_ngcontent-%COMP%] {\n background: #9c27b0;\n}\n\n.ai-run-content[_ngcontent-%COMP%] {\n flex: 1;\n}\n\n.ai-run-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: #333;\n margin-bottom: 4px;\n}\n\n.ai-run-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n font-size: 12px;\n color: #666;\n}\n\n.ai-run-card[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n color: #999;\n font-size: 14px;\n}\n\n\n\n.feedback-tab[_ngcontent-%COMP%] {\n background: white;\n border-radius: 12px;\n padding: 20px;\n}\n\n.feedback-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.feedback-item[_ngcontent-%COMP%] {\n padding: 16px;\n background: #f8f9fa;\n border-radius: 8px;\n border: 1px solid #e0e0e0;\n}\n\n.feedback-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 12px;\n}\n\n.feedback-user[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 600;\n color: #333;\n}\n\n.feedback-date[_ngcontent-%COMP%] {\n font-size: 12px;\n color: #999;\n}\n\n.feedback-rating[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #666;\n margin-bottom: 8px;\n}\n\n.feedback-correct[_ngcontent-%COMP%] {\n font-size: 14px;\n color: #666;\n margin-bottom: 8px;\n}\n\n.feedback-comments[_ngcontent-%COMP%] {\n font-size: 14px;\n line-height: 1.5;\n color: #333;\n padding: 12px;\n background: white;\n border-radius: 6px;\n border-left: 3px solid #2196f3;\n}\n\n\n\n.no-data[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n color: #999;\n text-align: center;\n}\n\n.no-data[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 48px;\n margin-bottom: 16px;\n opacity: 0.3;\n}\n\n.no-data[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n}\n\n\n\n@media (max-width: 1200px) {\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: repeat(3, 1fr);\n }\n}\n\n@media (max-width: 768px) {\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .details-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .header-content[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n }\n\n .tabs[_ngcontent-%COMP%] {\n overflow-x: auto;\n }\n}"], changeDetection: 0 }); }
1552
+ i0.ɵɵadvance();
1553
+ i0.ɵɵproperty("ngIf", ctx.activeTab === "execution");
1554
+ i0.ɵɵadvance();
1555
+ i0.ɵɵproperty("ngIf", ctx.activeTab === "log");
1556
+ } }, dependencies: [i5.NgClass, i5.NgForOf, i5.NgIf, i6.DefaultValueAccessor, i6.NgControlStatus, i6.NgModel, i7.ButtonComponent, i8.CodeEditorComponent, i3.ExecutionContextComponent, i9.EntityLinkPillComponent, i5.DecimalPipe, i5.DatePipe], styles: ["\n\n\n\n\n\n\n\n[_nghost-%COMP%] {\n --test-primary: #2563eb;\n --test-primary-light: #3b82f6;\n --test-primary-dark: #1d4ed8;\n --test-success: #10b981;\n --test-success-light: #d1fae5;\n --test-error: #ef4444;\n --test-error-light: #fee2e2;\n --test-warning: #f59e0b;\n --test-warning-light: #fef3c7;\n --test-timeout: #f97316;\n --test-timeout-light: #ffedd5;\n --test-running: #3b82f6;\n --test-pending: #8b5cf6;\n --test-skipped: #6b7280;\n --test-bg: #f8fafc;\n --test-surface: #ffffff;\n --test-border: #e2e8f0;\n --test-text: #1e293b;\n --test-text-secondary: #64748b;\n --test-text-muted: #94a3b8;\n --test-radius-sm: 6px;\n --test-radius-md: 10px;\n --test-radius-lg: 16px;\n --test-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);\n --test-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);\n --test-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);\n --test-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n display: block;\n height: 100%;\n}\n\n\n\n.test-run-form[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--test-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n\n\n\n\n.error-banner[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 12px 20px;\n background: linear-gradient(135deg, var(--test-error) 0%, #dc2626 100%);\n color: white;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n animation: _ngcontent-%COMP%_slideDown 0.3s ease-out;\n}\n\n.error-banner[_ngcontent-%COMP%]:hover {\n background: linear-gradient(135deg, #dc2626 0%, #b91c1c 100%);\n}\n\n.error-banner[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 16px;\n}\n\n.retry-btn[_ngcontent-%COMP%] {\n background: rgba(255, 255, 255, 0.2);\n border: 1px solid rgba(255, 255, 255, 0.3);\n color: white;\n padding: 6px 12px;\n border-radius: var(--test-radius-sm);\n cursor: pointer;\n font-size: 12px;\n font-weight: 600;\n transition: var(--test-transition);\n}\n\n.retry-btn[_ngcontent-%COMP%]:hover {\n background: rgba(255, 255, 255, 0.3);\n}\n\n@keyframes _ngcontent-%COMP%_slideDown {\n from {\n transform: translateY(-100%);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n\n\n\n\n.test-run-header[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n padding: 20px;\n position: relative;\n}\n\n\n\n.breadcrumb[_ngcontent-%COMP%] {\n margin-bottom: 16px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] ol[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n list-style: none;\n margin: 0;\n padding: 0;\n font-size: 13px;\n flex-wrap: wrap;\n}\n\n.breadcrumb[_ngcontent-%COMP%] li[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] a[_ngcontent-%COMP%] {\n color: var(--test-primary);\n text-decoration: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n border-radius: var(--test-radius-sm);\n transition: var(--test-transition);\n}\n\n.breadcrumb[_ngcontent-%COMP%] a[_ngcontent-%COMP%]:hover {\n background: rgba(37, 99, 235, 0.1);\n text-decoration: none;\n}\n\n.breadcrumb[_ngcontent-%COMP%] .separator[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--test-text-muted);\n margin: 0 4px;\n}\n\n.breadcrumb[_ngcontent-%COMP%] .current[_ngcontent-%COMP%] {\n color: var(--test-text-secondary);\n font-weight: 500;\n}\n\n.breadcrumb-text[_ngcontent-%COMP%] {\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n\n\n.header-content[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 20px;\n gap: 16px;\n}\n\n.header-left[_ngcontent-%COMP%] {\n display: flex;\n gap: 16px;\n flex: 1;\n min-width: 0;\n}\n\n\n\n.status-indicator[_ngcontent-%COMP%] {\n width: 56px;\n height: 56px;\n border-radius: var(--test-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-size: 24px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.status-indicator[_ngcontent-%COMP%]:hover {\n transform: scale(1.05);\n}\n\n\n\n.test-run-info[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.test-run-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: clamp(18px, 4vw, 24px);\n font-weight: 700;\n color: var(--test-text);\n line-height: 1.2;\n word-wrap: break-word;\n}\n\n.test-run-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] .run-id[_ngcontent-%COMP%] {\n color: var(--test-text-secondary);\n font-weight: 500;\n}\n\n.test-run-meta[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n\n\n.status-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n color: white;\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n box-shadow: var(--test-shadow-sm);\n}\n\n\n\n.meta-item[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 14px;\n color: var(--test-text-secondary);\n}\n\n.meta-item[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n\n.header-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.header-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n white-space: nowrap;\n}\n\n.btn-text[_ngcontent-%COMP%] {\n margin-left: 6px;\n}\n\n\n\n\n\n.metrics-bar[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 12px;\n margin-bottom: 16px;\n}\n\n.metric-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 14px;\n transition: var(--test-transition);\n}\n\n.metric-card[_ngcontent-%COMP%]:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.metric-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-sm);\n color: var(--test-primary);\n font-size: 16px;\n flex-shrink: 0;\n}\n\n.metric-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.metric-label[_ngcontent-%COMP%] {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n margin-bottom: 4px;\n}\n\n.metric-value[_ngcontent-%COMP%] {\n font-size: 16px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.metric-detail[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--test-text-muted);\n margin-top: 2px;\n}\n\n\n\n.metric-progress[_ngcontent-%COMP%] {\n margin-top: 6px;\n height: 4px;\n background: var(--test-border);\n border-radius: 2px;\n overflow: hidden;\n}\n\n.progress-bar[_ngcontent-%COMP%] {\n height: 100%;\n border-radius: 2px;\n transition: width 0.5s ease-out;\n}\n\n\n\n.secondary-info[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n padding-top: 16px;\n border-top: 1px solid var(--test-border);\n flex-wrap: wrap;\n}\n\n.info-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: var(--test-text-secondary);\n padding: 6px 12px;\n background: var(--test-bg);\n border-radius: 20px;\n transition: var(--test-transition);\n}\n\n.info-chip[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n.info-chip.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.info-chip.clickable[_ngcontent-%COMP%]:hover {\n background: rgba(37, 99, 235, 0.1);\n color: var(--test-primary);\n}\n\n\n\n\n\n.tabs-container[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n.tabs[_ngcontent-%COMP%] {\n display: flex;\n padding: 0 20px;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n -ms-overflow-style: none;\n}\n\n.tabs[_ngcontent-%COMP%]::-webkit-scrollbar {\n display: none;\n}\n\n.tab[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 14px 18px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--test-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n white-space: nowrap;\n position: relative;\n}\n\n.tab[_ngcontent-%COMP%]:hover {\n color: var(--test-primary);\n background: rgba(37, 99, 235, 0.05);\n}\n\n.tab.active[_ngcontent-%COMP%] {\n color: var(--test-primary);\n border-bottom-color: var(--test-primary);\n font-weight: 600;\n}\n\n.tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 15px;\n}\n\n.tab-badge[_ngcontent-%COMP%] {\n background: var(--test-border);\n color: var(--test-text-secondary);\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n transition: var(--test-transition);\n}\n\n.tab.active[_ngcontent-%COMP%] .tab-badge[_ngcontent-%COMP%] {\n background: rgba(37, 99, 235, 0.15);\n color: var(--test-primary);\n}\n\n.shortcut-hint[_ngcontent-%COMP%] {\n font-size: 10px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n margin-left: 4px;\n font-family: -apple-system, BlinkMacSystemFont, sans-serif;\n}\n\n\n\n\n\n.tab-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n scroll-behavior: smooth;\n}\n\n\n\n\n\n.overview-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n\n\n.result-hero[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 32px;\n text-align: center;\n border: 2px solid var(--test-border);\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.result-hero.passed[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #ecfdf5 0%, var(--test-success-light) 100%);\n border-color: var(--test-success);\n}\n\n.result-hero.failed[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #fef2f2 0%, var(--test-error-light) 100%);\n border-color: var(--test-error);\n}\n\n.result-hero.error[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #fffbeb 0%, var(--test-warning-light) 100%);\n border-color: var(--test-warning);\n}\n\n.result-hero.timeout[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #fff7ed 0%, var(--test-timeout-light) 100%);\n border-color: var(--test-timeout);\n}\n\n.result-hero.running[_ngcontent-%COMP%], \n.result-hero.pending[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);\n border-color: var(--test-primary-light);\n}\n\n.result-icon-wrapper[_ngcontent-%COMP%] {\n position: relative;\n display: inline-block;\n margin-bottom: 16px;\n}\n\n.result-icon[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-surface);\n border-radius: 50%;\n font-size: 40px;\n margin: 0 auto;\n box-shadow: var(--test-shadow-md);\n}\n\n.result-hero.passed[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%] { color: var(--test-success); }\n.result-hero.failed[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%] { color: var(--test-error); }\n.result-hero.error[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%] { color: var(--test-warning); }\n.result-hero.timeout[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%] { color: var(--test-timeout); }\n.result-hero.running[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%], \n.result-hero.pending[_ngcontent-%COMP%] .result-icon[_ngcontent-%COMP%] { color: var(--test-primary); }\n\n.result-pulse[_ngcontent-%COMP%] {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 100px;\n height: 100px;\n border-radius: 50%;\n background: rgba(59, 130, 246, 0.2);\n animation: _ngcontent-%COMP%_pulse 2s ease-in-out infinite;\n}\n\n@keyframes _ngcontent-%COMP%_pulse {\n 0%, 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.5; }\n 50% { transform: translate(-50%, -50%) scale(1.2); opacity: 0; }\n}\n\n.result-text[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n font-size: clamp(24px, 5vw, 32px);\n font-weight: 800;\n color: var(--test-text);\n}\n\n.result-details[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.result-score[_ngcontent-%COMP%] {\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text-secondary);\n}\n\n.result-divider[_ngcontent-%COMP%] {\n color: var(--test-border);\n}\n\n.result-checks[_ngcontent-%COMP%] {\n font-size: 16px;\n color: var(--test-text-muted);\n}\n\n\n\n.section-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 16px;\n gap: 12px;\n}\n\n.section-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.section-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.section-header.error[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-error);\n}\n\n.check-summary[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--test-text-secondary);\n}\n\n\n\n.check-results[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.check-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.check-item[_ngcontent-%COMP%] {\n display: flex;\n gap: 12px;\n padding: 14px 16px;\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n transition: var(--test-transition);\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out backwards;\n}\n\n.check-item[_ngcontent-%COMP%]:hover {\n transform: translateX(4px);\n}\n\n.check-item.passed[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%);\n border-color: #86efac;\n}\n\n.check-item.failed[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #fef2f2 0%, #fee2e2 100%);\n border-color: #fca5a5;\n}\n\n.check-status[_ngcontent-%COMP%] {\n font-size: 20px;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n.check-item.passed[_ngcontent-%COMP%] .check-status[_ngcontent-%COMP%] { color: var(--test-success); }\n.check-item.failed[_ngcontent-%COMP%] .check-status[_ngcontent-%COMP%] { color: var(--test-error); }\n\n.check-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.check-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 4px;\n}\n\n.check-message[_ngcontent-%COMP%] {\n font-size: 13px;\n color: var(--test-text-secondary);\n line-height: 1.5;\n word-wrap: break-word;\n}\n\n.check-weight[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-muted);\n flex-shrink: 0;\n text-align: right;\n}\n\n.weight-label[_ngcontent-%COMP%] {\n font-weight: 500;\n}\n\n\n\n.comparison-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.comparison-tabs[_ngcontent-%COMP%] {\n display: flex;\n gap: 4px;\n margin-bottom: 16px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n padding: 4px;\n}\n\n.comparison-tab[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 10px 16px;\n border: none;\n background: transparent;\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n border-radius: var(--test-radius-sm);\n transition: var(--test-transition);\n}\n\n.comparison-tab[_ngcontent-%COMP%]:hover {\n color: var(--test-text);\n background: rgba(0, 0, 0, 0.05);\n}\n\n.comparison-tab.active[_ngcontent-%COMP%] {\n background: var(--test-surface);\n color: var(--test-primary);\n font-weight: 600;\n box-shadow: var(--test-shadow-sm);\n}\n\n.comparison-content[_ngcontent-%COMP%] {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n}\n\n\n\n\n\n.details-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.details-grid[_ngcontent-%COMP%] {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n gap: 12px;\n}\n\n.detail-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n transition: var(--test-transition);\n}\n\n.detail-card.clickable[_ngcontent-%COMP%] {\n cursor: pointer;\n}\n\n.detail-card.clickable[_ngcontent-%COMP%]:hover {\n background: rgba(37, 99, 235, 0.05);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n}\n\n.detail-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n color: var(--test-primary);\n font-size: 18px;\n flex-shrink: 0;\n}\n\n.detail-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.detail-label[_ngcontent-%COMP%] {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n margin-bottom: 4px;\n}\n\n.detail-value[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--test-text);\n word-wrap: break-word;\n font-weight: 500;\n}\n\n.detail-value.monospace[_ngcontent-%COMP%] {\n font-family: 'SF Mono', Monaco, 'Courier New', monospace;\n font-size: 12px;\n}\n\n.detail-value.link[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n.detail-action[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n font-size: 12px;\n transition: var(--test-transition);\n}\n\n.detail-card.clickable[_ngcontent-%COMP%]:hover .detail-action[_ngcontent-%COMP%] {\n color: var(--test-primary);\n}\n\n\n\n.error-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.error-content[_ngcontent-%COMP%] {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid #fca5a5;\n}\n\n\n\n.result-details-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.result-details-content[_ngcontent-%COMP%] {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n}\n\n\n\n\n\n.ai-runs-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.ai-section[_ngcontent-%COMP%] {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.count-badge[_ngcontent-%COMP%] {\n background: var(--test-bg);\n color: var(--test-text-secondary);\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.ai-run-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.ai-run-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.ai-run-card[_ngcontent-%COMP%]:hover {\n background: rgba(37, 99, 235, 0.05);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n box-shadow: var(--test-shadow-sm);\n}\n\n.ai-run-icon[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, var(--test-primary) 0%, var(--test-primary-dark) 100%);\n color: white;\n border-radius: var(--test-radius-md);\n font-size: 18px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-sm);\n}\n\n.ai-run-icon.agent[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, var(--test-primary) 0%, var(--test-primary-dark) 100%);\n}\n\n.ai-run-icon.prompt[_ngcontent-%COMP%] {\n background: linear-gradient(135deg, #9333ea 0%, #7c3aed 100%);\n}\n\n.ai-run-content[_ngcontent-%COMP%] {\n flex: 1;\n min-width: 0;\n}\n\n.ai-run-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 6px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.ai-run-meta[_ngcontent-%COMP%] {\n display: flex;\n gap: 10px;\n font-size: 12px;\n color: var(--test-text-secondary);\n flex-wrap: wrap;\n}\n\n.status-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-chip.complete[_ngcontent-%COMP%], \n.status-chip.completed[_ngcontent-%COMP%], \n.status-chip.passed[_ngcontent-%COMP%] {\n background: var(--test-success-light);\n color: #059669;\n}\n\n.status-chip.failed[_ngcontent-%COMP%], \n.status-chip.error[_ngcontent-%COMP%] {\n background: var(--test-error-light);\n color: #dc2626;\n}\n\n.status-chip.running[_ngcontent-%COMP%] {\n background: #dbeafe;\n color: var(--test-primary);\n}\n\n.cost-chip[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n color: var(--test-text-muted);\n}\n\n.ai-run-arrow[_ngcontent-%COMP%] {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.ai-run-card[_ngcontent-%COMP%]:hover .ai-run-arrow[_ngcontent-%COMP%] {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n\n\n\n\n.feedback-tab[_ngcontent-%COMP%] {\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.feedback-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.feedback-item[_ngcontent-%COMP%] {\n padding: 20px;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n border: 1px solid var(--test-border);\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.feedback-item[_ngcontent-%COMP%]:hover {\n border-color: var(--test-primary-light);\n}\n\n.feedback-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.feedback-user[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.user-avatar[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n color: var(--test-primary);\n font-size: 14px;\n}\n\n.user-name[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.feedback-date[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.feedback-body[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.feedback-rating[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.rating-stars[_ngcontent-%COMP%] {\n display: flex;\n gap: 2px;\n}\n\n.rating-stars[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n color: var(--test-border);\n}\n\n.rating-stars[_ngcontent-%COMP%] i.filled[_ngcontent-%COMP%] {\n color: #fbbf24;\n}\n\n.rating-value[_ngcontent-%COMP%] {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.feedback-verdict[_ngcontent-%COMP%] {\n display: flex;\n}\n\n.verdict-badge[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.verdict-badge.correct[_ngcontent-%COMP%] {\n background: var(--test-success-light);\n color: #059669;\n}\n\n.verdict-badge.incorrect[_ngcontent-%COMP%] {\n background: var(--test-error-light);\n color: #dc2626;\n}\n\n.feedback-comments[_ngcontent-%COMP%] {\n padding: 14px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n border-left: 3px solid var(--test-primary);\n}\n\n.feedback-comments[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n line-height: 1.6;\n color: var(--test-text);\n}\n\n\n\n\n\n.log-tab[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 0;\n height: 100%;\n animation: _ngcontent-%COMP%_fadeIn 0.3s ease-out;\n}\n\n.log-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n background: var(--test-surface);\n padding: 16px 20px;\n border-radius: var(--test-radius-lg) var(--test-radius-lg) 0 0;\n border: 1px solid var(--test-border);\n border-bottom: none;\n}\n\n.log-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.log-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--test-text-secondary);\n font-size: 16px;\n}\n\n.log-title[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 16px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.log-actions[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n}\n\n.log-container[_ngcontent-%COMP%] {\n flex: 1;\n border-radius: 0 0 var(--test-radius-lg) var(--test-radius-lg);\n overflow: hidden;\n min-height: 300px;\n border: 1px solid var(--test-border);\n border-top: none;\n}\n\n\n\n\n\n.loading-state[_ngcontent-%COMP%] {\n padding: 20px;\n}\n\n.skeleton-list[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.skeleton-card[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.skeleton-icon[_ngcontent-%COMP%], \n.skeleton-avatar[_ngcontent-%COMP%] {\n width: 44px;\n height: 44px;\n border-radius: var(--test-radius-md);\n background: linear-gradient(90deg, #e2e8f0 25%, #f1f5f9 50%, #e2e8f0 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n}\n\n.skeleton-avatar[_ngcontent-%COMP%] {\n border-radius: 50%;\n}\n\n.skeleton-content[_ngcontent-%COMP%] {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.skeleton-line[_ngcontent-%COMP%] {\n height: 14px;\n border-radius: 4px;\n background: linear-gradient(90deg, #e2e8f0 25%, #f1f5f9 50%, #e2e8f0 75%);\n background-size: 200% 100%;\n animation: _ngcontent-%COMP%_shimmer 1.5s infinite;\n}\n\n.skeleton-line.wide[_ngcontent-%COMP%] { width: 70%; }\n.skeleton-line.medium[_ngcontent-%COMP%] { width: 55%; }\n.skeleton-line.narrow[_ngcontent-%COMP%] { width: 40%; }\n\n@keyframes _ngcontent-%COMP%_shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n\n\n\n\n.empty-state[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 24px;\n text-align: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n}\n\n.empty-icon[_ngcontent-%COMP%] {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n margin-bottom: 20px;\n}\n\n.empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 36px;\n color: var(--test-text-muted);\n}\n\n.empty-state[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.empty-state[_ngcontent-%COMP%] p[_ngcontent-%COMP%] {\n margin: 0;\n font-size: 14px;\n color: var(--test-text-secondary);\n max-width: 300px;\n}\n\n\n\n\n\n.shortcuts-hint[_ngcontent-%COMP%] {\n position: fixed;\n bottom: 20px;\n right: 20px;\n z-index: 100;\n}\n\n.shortcuts-hint[_ngcontent-%COMP%] > i[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: 50%;\n color: var(--test-text-muted);\n font-size: 16px;\n cursor: pointer;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.shortcuts-hint[_ngcontent-%COMP%]:hover > i[_ngcontent-%COMP%] {\n color: var(--test-primary);\n border-color: var(--test-primary-light);\n}\n\n.shortcuts-popup[_ngcontent-%COMP%] {\n display: none;\n position: absolute;\n bottom: 50px;\n right: 0;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 16px;\n box-shadow: var(--test-shadow-lg);\n min-width: 200px;\n}\n\n.shortcuts-hint[_ngcontent-%COMP%]:hover .shortcuts-popup[_ngcontent-%COMP%] {\n display: block;\n animation: _ngcontent-%COMP%_fadeIn 0.2s ease-out;\n}\n\n.shortcuts-popup[_ngcontent-%COMP%] h4[_ngcontent-%COMP%] {\n margin: 0 0 12px 0;\n font-size: 14px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.shortcuts-popup[_ngcontent-%COMP%] ul[_ngcontent-%COMP%] {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.shortcuts-popup[_ngcontent-%COMP%] li[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 6px 0;\n font-size: 13px;\n color: var(--test-text-secondary);\n}\n\n.shortcuts-popup[_ngcontent-%COMP%] kbd[_ngcontent-%COMP%] {\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: 4px;\n padding: 2px 6px;\n font-family: -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 11px;\n color: var(--test-text);\n}\n\n\n\n\n\n@media (max-width: 1024px) {\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: repeat(3, 1fr);\n }\n\n .details-grid[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .shortcuts-hint[_ngcontent-%COMP%] {\n display: none;\n }\n}\n\n\n\n\n\n@media (max-width: 768px) {\n .test-run-form[_ngcontent-%COMP%] {\n height: auto;\n min-height: 100%;\n }\n\n .test-run-header[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .breadcrumb[_ngcontent-%COMP%] {\n margin-bottom: 12px;\n }\n\n .breadcrumb[_ngcontent-%COMP%] ol[_ngcontent-%COMP%] {\n font-size: 12px;\n }\n\n .header-content[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-left[_ngcontent-%COMP%] {\n width: 100%;\n }\n\n .status-indicator[_ngcontent-%COMP%] {\n width: 48px;\n height: 48px;\n font-size: 20px;\n }\n\n .test-run-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 18px;\n }\n\n .test-run-meta[_ngcontent-%COMP%] {\n gap: 8px;\n }\n\n .status-badge[_ngcontent-%COMP%] {\n padding: 4px 10px;\n font-size: 11px;\n }\n\n .header-actions[_ngcontent-%COMP%] {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n flex: 1;\n }\n\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: repeat(2, 1fr);\n gap: 10px;\n }\n\n .metric-card[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .metric-icon[_ngcontent-%COMP%] {\n width: 36px;\n height: 36px;\n font-size: 14px;\n }\n\n .metric-value[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .tabs[_ngcontent-%COMP%] {\n padding: 0 12px;\n }\n\n .tab[_ngcontent-%COMP%] {\n padding: 12px 14px;\n font-size: 13px;\n gap: 6px;\n }\n\n .tab[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .shortcut-hint[_ngcontent-%COMP%] {\n display: none;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n padding: 16px;\n }\n\n .result-hero[_ngcontent-%COMP%] {\n padding: 24px 20px;\n }\n\n .result-icon[_ngcontent-%COMP%] {\n width: 64px;\n height: 64px;\n font-size: 32px;\n }\n\n .result-text[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n font-size: 24px;\n }\n\n .result-score[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .check-results[_ngcontent-%COMP%], \n .comparison-section[_ngcontent-%COMP%], \n .ai-section[_ngcontent-%COMP%], \n .feedback-item[_ngcontent-%COMP%] {\n padding: 18px;\n }\n\n .check-item[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .comparison-tabs[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 4px;\n }\n\n .comparison-tab[_ngcontent-%COMP%] {\n text-align: center;\n }\n\n .details-grid[_ngcontent-%COMP%] {\n grid-template-columns: 1fr;\n }\n\n .detail-card[_ngcontent-%COMP%] {\n padding: 14px;\n }\n\n .ai-run-card[_ngcontent-%COMP%] {\n padding: 14px;\n }\n\n .ai-run-icon[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 16px;\n }\n\n .ai-run-meta[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 4px;\n }\n\n .feedback-header[_ngcontent-%COMP%] {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .log-header[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 12px;\n align-items: stretch;\n }\n\n .log-actions[_ngcontent-%COMP%] {\n justify-content: stretch;\n }\n\n .log-actions[_ngcontent-%COMP%] button[_ngcontent-%COMP%] {\n flex: 1;\n }\n\n .empty-state[_ngcontent-%COMP%] {\n padding: 40px 20px;\n }\n\n .empty-icon[_ngcontent-%COMP%] {\n width: 64px;\n height: 64px;\n }\n\n .empty-icon[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 28px;\n }\n}\n\n\n\n\n\n@media (max-width: 480px) {\n .test-run-header[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .header-left[_ngcontent-%COMP%] {\n gap: 12px;\n }\n\n .status-indicator[_ngcontent-%COMP%] {\n width: 40px;\n height: 40px;\n font-size: 18px;\n border-radius: 8px;\n }\n\n .test-run-info[_ngcontent-%COMP%] h1[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .metrics-bar[_ngcontent-%COMP%] {\n grid-template-columns: 1fr 1fr;\n }\n\n .metric-card[_ngcontent-%COMP%] {\n padding: 10px;\n flex-direction: column;\n text-align: center;\n }\n\n .metric-icon[_ngcontent-%COMP%] {\n margin-bottom: 8px;\n }\n\n .metric-label[_ngcontent-%COMP%] {\n font-size: 9px;\n }\n\n .metric-value[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .tabs[_ngcontent-%COMP%] {\n padding: 0 8px;\n }\n\n .tab[_ngcontent-%COMP%] {\n padding: 10px 12px;\n font-size: 12px;\n }\n\n .tab-badge[_ngcontent-%COMP%] {\n display: none;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .result-hero[_ngcontent-%COMP%] {\n padding: 20px 16px;\n }\n\n .result-icon[_ngcontent-%COMP%] {\n width: 56px;\n height: 56px;\n font-size: 28px;\n }\n\n .result-text[_ngcontent-%COMP%] h2[_ngcontent-%COMP%] {\n font-size: 20px;\n }\n\n .result-score[_ngcontent-%COMP%] {\n font-size: 14px;\n }\n\n .result-checks[_ngcontent-%COMP%] {\n font-size: 12px;\n }\n\n .section-header[_ngcontent-%COMP%] h3[_ngcontent-%COMP%] {\n font-size: 16px;\n }\n\n .check-item[_ngcontent-%COMP%] {\n flex-direction: column;\n gap: 8px;\n }\n\n .check-weight[_ngcontent-%COMP%] {\n text-align: left;\n }\n}\n\n\n\n\n\n@media (hover: none) and (pointer: coarse) {\n .tab[_ngcontent-%COMP%], \n .comparison-tab[_ngcontent-%COMP%], \n .ai-run-card[_ngcontent-%COMP%], \n .check-item[_ngcontent-%COMP%], \n .feedback-item[_ngcontent-%COMP%], \n .detail-card.clickable[_ngcontent-%COMP%] {\n -webkit-tap-highlight-color: transparent;\n }\n\n .ai-run-card[_ngcontent-%COMP%]:active, \n .detail-card.clickable[_ngcontent-%COMP%]:active {\n background: rgba(37, 99, 235, 0.1);\n transform: scale(0.98);\n }\n\n .tab[_ngcontent-%COMP%]:active {\n background: rgba(37, 99, 235, 0.1);\n }\n\n \n\n .tab[_ngcontent-%COMP%] {\n min-height: 48px;\n }\n\n .ai-run-card[_ngcontent-%COMP%], \n .detail-card[_ngcontent-%COMP%] {\n min-height: 64px;\n }\n}\n\n\n\n\n\n@media (prefers-contrast: high) {\n .status-badge[_ngcontent-%COMP%] {\n border: 2px solid currentColor;\n }\n\n .check-item[_ngcontent-%COMP%] {\n border-width: 2px;\n }\n\n .tab.active[_ngcontent-%COMP%] {\n border-bottom-width: 4px;\n }\n}\n\n\n\n\n\n@media (prefers-reduced-motion: reduce) {\n *[_ngcontent-%COMP%], \n *[_ngcontent-%COMP%]::before, \n *[_ngcontent-%COMP%]::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n\n .skeleton-icon[_ngcontent-%COMP%], \n .skeleton-avatar[_ngcontent-%COMP%], \n .skeleton-line[_ngcontent-%COMP%] {\n animation: none;\n background: #e2e8f0;\n }\n\n .result-pulse[_ngcontent-%COMP%] {\n animation: none;\n display: none;\n }\n}\n\n\n\n\n\n@media print {\n .test-run-form[_ngcontent-%COMP%] {\n background: white;\n height: auto;\n }\n\n .header-actions[_ngcontent-%COMP%], \n .tabs-container[_ngcontent-%COMP%], \n .shortcuts-hint[_ngcontent-%COMP%], \n .log-actions[_ngcontent-%COMP%] {\n display: none !important;\n }\n\n .tab-content[_ngcontent-%COMP%] {\n overflow: visible;\n padding: 0;\n }\n\n .result-hero[_ngcontent-%COMP%], \n .check-results[_ngcontent-%COMP%], \n .details-grid[_ngcontent-%COMP%], \n .ai-section[_ngcontent-%COMP%], \n .feedback-item[_ngcontent-%COMP%] {\n break-inside: avoid;\n box-shadow: none;\n border: 1px solid #ddd;\n }\n\n .comparison-content[_ngcontent-%COMP%], \n .log-container[_ngcontent-%COMP%] {\n max-height: none;\n overflow: visible;\n }\n}\n\n\n\n\n\n.tags-bar[_ngcontent-%COMP%] {\n margin-top: 16px;\n padding: 8px 14px;\n background: linear-gradient(135deg, rgba(37, 99, 235, 0.04) 0%, rgba(37, 99, 235, 0.08) 100%);\n border: 1px solid rgba(37, 99, 235, 0.15);\n border-radius: 8px;\n max-width: 600px;\n}\n\n.tags-bar-content[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.tags-bar-label[_ngcontent-%COMP%] {\n color: var(--test-text-secondary);\n font-size: 14px;\n}\n\n.tags-bar-label[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n opacity: 0.6;\n}\n\n.tags-bar-chips[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n flex: 1;\n}\n\n.tag-inline[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n background: rgba(37, 99, 235, 0.1);\n color: var(--test-primary);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n letter-spacing: 0.01em;\n}\n\n.tags-bar-empty[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-secondary);\n opacity: 0.7;\n flex: 1;\n}\n\n.tags-bar-edit[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n background: transparent;\n border: 1px dashed var(--test-border);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n color: var(--test-text-secondary);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.tags-bar-edit[_ngcontent-%COMP%]:hover {\n border-color: var(--test-primary);\n color: var(--test-primary);\n background: rgba(37, 99, 235, 0.05);\n}\n\n.tags-bar-edit[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 10px;\n}\n\n\n\n\n\n.tags-editor-panel[_ngcontent-%COMP%] {\n margin-top: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-primary);\n border-radius: var(--test-radius-md);\n overflow: hidden;\n box-shadow: 0 4px 12px rgba(37, 99, 235, 0.1);\n max-width: 600px;\n}\n\n.tags-editor-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n padding: 12px 16px;\n background: rgba(37, 99, 235, 0.08);\n border-bottom: 1px solid rgba(37, 99, 235, 0.2);\n}\n\n.tags-editor-title[_ngcontent-%COMP%] {\n font-size: 13px;\n font-weight: 600;\n color: var(--test-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.tags-editor-body[_ngcontent-%COMP%] {\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.tags-editor-chips[_ngcontent-%COMP%] {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n min-height: 32px;\n}\n\n.tag-editable[_ngcontent-%COMP%] {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 8px 5px 12px;\n background: var(--test-surface);\n border: 1px solid var(--test-primary);\n color: var(--test-primary);\n border-radius: 14px;\n font-size: 12px;\n font-weight: 500;\n}\n\n.tag-remove-btn[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n background: transparent;\n border: none;\n color: var(--test-primary);\n cursor: pointer;\n border-radius: 50%;\n font-size: 9px;\n opacity: 0.6;\n transition: var(--test-transition);\n}\n\n.tag-remove-btn[_ngcontent-%COMP%]:hover {\n opacity: 1;\n background: var(--test-error-light);\n color: var(--test-error);\n}\n\n.tags-empty-hint[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--test-text-secondary);\n font-style: italic;\n padding: 4px 0;\n}\n\n.tags-editor-input[_ngcontent-%COMP%] {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.tag-text-input[_ngcontent-%COMP%] {\n flex: 1;\n padding: 10px 14px;\n border: 1px solid var(--test-border);\n border-radius: 8px;\n font-size: 13px;\n background: var(--test-bg);\n}\n\n.tag-text-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--test-primary);\n background: var(--test-surface);\n box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);\n}\n\n.tag-text-input[_ngcontent-%COMP%]::placeholder {\n color: var(--test-text-secondary);\n opacity: 0.6;\n}\n\n.tags-editor-footer[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-start;\n gap: 8px;\n padding: 12px 16px;\n background: var(--test-bg);\n border-top: 1px solid var(--test-border);\n}\n\n\n\n@media (max-width: 768px) {\n .tags-bar[_ngcontent-%COMP%] {\n padding: 8px 12px;\n }\n\n .tags-bar-content[_ngcontent-%COMP%] {\n gap: 8px;\n }\n\n .tag-inline[_ngcontent-%COMP%] {\n padding: 3px 8px;\n font-size: 10px;\n }\n\n .tags-editor-panel[_ngcontent-%COMP%] {\n margin-top: 12px;\n }\n\n .tags-editor-body[_ngcontent-%COMP%] {\n padding: 12px;\n }\n\n .tags-editor-footer[_ngcontent-%COMP%] {\n padding: 10px 12px;\n }\n}"], changeDetection: 0 }); }
907
1557
  };
908
1558
  TestRunFormComponentExtended = __decorate([
909
1559
  RegisterClass(BaseFormComponent, 'MJ: Test Runs')
@@ -911,9 +1561,12 @@ TestRunFormComponentExtended = __decorate([
911
1561
  export { TestRunFormComponentExtended };
912
1562
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TestRunFormComponentExtended, [{
913
1563
  type: Component,
914
- args: [{ selector: 'mj-test-run-form', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"test-run-form\">\n <!-- Header Section -->\n <div class=\"test-run-header\">\n <div class=\"breadcrumb\">\n <a href=\"javascript:void(0)\" (click)=\"openTest()\" *ngIf=\"test\">\n <i class=\"fas fa-flask\"></i> {{ test.Name }}\n </a>\n <i class=\"fas fa-chevron-right\" *ngIf=\"test\"></i>\n <span>Run #{{ record.ID.substring(0, 8) }}</span>\n </div>\n\n <div class=\"header-content\">\n <div class=\"header-left\">\n <div class=\"test-run-icon\" [style.background-color]=\"getStatusColor()\">\n <i class=\"fas fa-flask\"></i>\n </div>\n <div class=\"test-run-info\">\n <h1>Test Run</h1>\n <div class=\"test-run-meta\">\n <span class=\"status-badge\" [style.background-color]=\"getStatusColor()\">\n <i class=\"fas\" [ngClass]=\"getStatusIcon()\"></i>\n {{ record.Status }}\n </span>\n <span class=\"test-type\" *ngIf=\"test\">{{ test.Type }}</span>\n </div>\n </div>\n </div>\n <div class=\"header-actions\">\n <button kendoButton (click)=\"reRunTest()\" icon=\"refresh\">\n Re-run Test\n </button>\n <button kendoButton (click)=\"refresh()\" icon=\"sync\">\n Refresh\n </button>\n </div>\n </div>\n\n <!-- Metrics Bar -->\n <div class=\"metrics-bar\">\n <div class=\"metric-card\">\n <div class=\"metric-label\">Started</div>\n <div class=\"metric-value\">{{ record.StartedAt | date:'short' }}</div>\n </div>\n <div class=\"metric-card\">\n <div class=\"metric-label\">Completed</div>\n <div class=\"metric-value\">{{ record.CompletedAt | date:'short' }}</div>\n </div>\n <div class=\"metric-card\">\n <div class=\"metric-label\">Duration</div>\n <div class=\"metric-value\">{{ calculateDuration() }}</div>\n </div>\n <div class=\"metric-card\">\n <div class=\"metric-label\">Score</div>\n <div class=\"metric-value\">{{ formatScore(record.Score) }}</div>\n </div>\n <div class=\"metric-card\">\n <div class=\"metric-label\">Cost</div>\n <div class=\"metric-value\">{{ formatCost(record.CostUSD) }}</div>\n </div>\n </div>\n\n <!-- Secondary Metrics -->\n <div class=\"secondary-metrics\">\n <div class=\"metric-item\">\n <span class=\"metric-label\">Checks:</span>\n <span class=\"metric-value\">{{ record.PassedChecks }}/{{ record.TotalChecks }}</span>\n </div>\n <div class=\"metric-item\">\n <span class=\"metric-label\">Run By:</span>\n <span class=\"metric-value\">{{ record.RunByUser }}</span>\n </div>\n <div class=\"metric-item\" *ngIf=\"testSuiteRun\">\n <span class=\"metric-label\">Part of Suite:</span>\n <a href=\"javascript:void(0)\" (click)=\"openTestSuiteRun()\">\n {{ testSuiteRun.ID }} (Seq: {{ record.Sequence }})\n </a>\n </div>\n </div>\n </div>\n\n <!-- Tabs -->\n <div class=\"tabs-container\">\n <div class=\"tabs\">\n <button class=\"tab\" [class.active]=\"activeTab === 'overview'\" (click)=\"changeTab('overview')\">\n <i class=\"fas fa-th-large\"></i>\n <span>Overview</span>\n </button>\n <button class=\"tab\" [class.active]=\"activeTab === 'details'\" (click)=\"changeTab('details')\">\n <i class=\"fas fa-list\"></i>\n <span>Details</span>\n </button>\n <button class=\"tab\" [class.active]=\"activeTab === 'ai-runs'\" (click)=\"changeTab('ai-runs')\">\n <i class=\"fas fa-robot\"></i>\n <span>AI Runs</span>\n <span class=\"tab-badge\" *ngIf=\"aiRunsLoaded\">{{ aiAgentRuns.length + aiPromptRuns.length }}</span>\n </button>\n <button class=\"tab\" [class.active]=\"activeTab === 'feedback'\" (click)=\"changeTab('feedback')\">\n <i class=\"fas fa-comments\"></i>\n <span>Feedback</span>\n <span class=\"tab-badge\" *ngIf=\"feedbackLoaded\">{{ feedbacks.length }}</span>\n </button>\n </div>\n </div>\n\n <!-- Tab Content -->\n <div class=\"tab-content\">\n <!-- Overview Tab -->\n <div class=\"overview-tab\" *ngIf=\"activeTab === 'overview'\">\n <!-- Result Hero -->\n <div class=\"result-hero\" [class.passed]=\"record.Status === 'Passed'\" [class.failed]=\"record.Status === 'Failed'\">\n <div class=\"result-icon\">\n <i class=\"fas\" [ngClass]=\"getStatusIcon()\"></i>\n </div>\n <div class=\"result-text\">\n <h2>TEST {{ record.Status.toUpperCase() }}</h2>\n <div class=\"result-score\">Score: {{ formatScore(record.Score) }} / 1.0000</div>\n <div class=\"result-checks\">{{ record.PassedChecks }} of {{ record.TotalChecks }} checks passed</div>\n </div>\n </div>\n\n <!-- Check Results -->\n <div class=\"check-results\" *ngIf=\"getCheckResults().length > 0\">\n <h3>Check Results</h3>\n <div class=\"check-list\">\n <div class=\"check-item\" *ngFor=\"let check of getCheckResults()\" [class.passed]=\"check.passed\" [class.failed]=\"!check.passed\">\n <div class=\"check-icon\">\n <i class=\"fas\" [class.fa-check-circle]=\"check.passed\" [class.fa-times-circle]=\"!check.passed\"></i>\n </div>\n <div class=\"check-content\">\n <div class=\"check-name\">{{ check.name }}</div>\n <div class=\"check-details\">{{ check.message }}</div>\n <div class=\"check-weight\" *ngIf=\"check.weight\">Weight: {{ check.weight }}</div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Input / Expected / Actual Comparison -->\n <div class=\"comparison-section\">\n <h3>Data Comparison</h3>\n <div class=\"comparison-tabs\">\n <button class=\"comparison-tab\" [class.active]=\"comparisonView === 'input'\" (click)=\"setComparisonView('input')\">\n Input\n </button>\n <button class=\"comparison-tab\" [class.active]=\"comparisonView === 'expected'\" (click)=\"setComparisonView('expected')\">\n Expected\n </button>\n <button class=\"comparison-tab\" [class.active]=\"comparisonView === 'actual'\" (click)=\"setComparisonView('actual')\">\n Actual\n </button>\n </div>\n <div class=\"comparison-content\">\n <pre>{{ getComparisonData() | json }}</pre>\n </div>\n </div>\n </div>\n\n <!-- Details Tab -->\n <div class=\"details-tab\" *ngIf=\"activeTab === 'details'\">\n <div class=\"details-grid\">\n <div class=\"detail-item\">\n <div class=\"detail-label\">Test Run ID</div>\n <div class=\"detail-value\">{{ record.ID }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Test</div>\n <div class=\"detail-value\">\n <a href=\"javascript:void(0)\" (click)=\"openTest()\" *ngIf=\"test\">{{ test.Name }}</a>\n </div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Status</div>\n <div class=\"detail-value\">{{ record.Status }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Target Type</div>\n <div class=\"detail-value\">{{ record.TargetType || 'N/A' }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Started At</div>\n <div class=\"detail-value\">{{ record.StartedAt | date:'medium' }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Completed At</div>\n <div class=\"detail-value\">{{ record.CompletedAt | date:'medium' }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Duration</div>\n <div class=\"detail-value\">{{ calculateDuration() }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Score</div>\n <div class=\"detail-value\">{{ formatScore(record.Score) }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Cost</div>\n <div class=\"detail-value\">{{ formatCost(record.CostUSD) }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Passed Checks</div>\n <div class=\"detail-value\">{{ record.PassedChecks }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Failed Checks</div>\n <div class=\"detail-value\">{{ record.FailedChecks }}</div>\n </div>\n <div class=\"detail-item\">\n <div class=\"detail-label\">Total Checks</div>\n <div class=\"detail-value\">{{ record.TotalChecks }}</div>\n </div>\n </div>\n\n <div class=\"error-message\" *ngIf=\"record.ErrorMessage\">\n <h4>Error Message</h4>\n <pre>{{ record.ErrorMessage }}</pre>\n </div>\n\n <div class=\"result-details-json\" *ngIf=\"record.ResultDetails\">\n <h4>Full Result Details (JSON)</h4>\n <pre>{{ parsedData.resultDetails | json }}</pre>\n </div>\n </div>\n\n <!-- AI Runs Tab -->\n <div class=\"ai-runs-tab\" *ngIf=\"activeTab === 'ai-runs'\">\n <div class=\"ai-runs-section\" *ngIf=\"aiAgentRuns.length > 0\">\n <h3>AI Agent Runs ({{ aiAgentRuns.length }})</h3>\n <div class=\"ai-run-list\">\n <div class=\"ai-run-card\" *ngFor=\"let run of aiAgentRuns\" (click)=\"openAIAgentRun(run.ID)\">\n <div class=\"ai-run-icon\">\n <i class=\"fas fa-robot\"></i>\n </div>\n <div class=\"ai-run-content\">\n <div class=\"ai-run-name\">{{ run.Agent }}</div>\n <div class=\"ai-run-meta\">\n <span>{{ run.Status }}</span>\n <span *ngIf=\"run.TotalCost\">${{ run.TotalCost }}</span>\n </div>\n </div>\n <i class=\"fas fa-external-link-alt\"></i>\n </div>\n </div>\n </div>\n\n <div class=\"ai-runs-section\" *ngIf=\"aiPromptRuns.length > 0\">\n <h3>AI Prompt Runs ({{ aiPromptRuns.length }})</h3>\n <div class=\"ai-run-list\">\n <div class=\"ai-run-card\" *ngFor=\"let run of aiPromptRuns\" (click)=\"openAIPromptRun(run.ID)\">\n <div class=\"ai-run-icon prompt\">\n <i class=\"fas fa-comment-dots\"></i>\n </div>\n <div class=\"ai-run-content\">\n <div class=\"ai-run-name\">{{ run.Prompt || run.Model }}</div>\n <div class=\"ai-run-meta\">\n <span *ngIf=\"run.TotalCost\">${{ run.TotalCost }}</span>\n </div>\n </div>\n <i class=\"fas fa-external-link-alt\"></i>\n </div>\n </div>\n </div>\n\n <div class=\"no-data\" *ngIf=\"aiRunsLoaded && aiAgentRuns.length === 0 && aiPromptRuns.length === 0\">\n <i class=\"fas fa-inbox\"></i>\n <p>No AI runs associated with this test execution</p>\n </div>\n </div>\n\n <!-- Feedback Tab -->\n <div class=\"feedback-tab\" *ngIf=\"activeTab === 'feedback'\">\n <div class=\"feedback-list\" *ngIf=\"feedbacks.length > 0\">\n <div class=\"feedback-item\" *ngFor=\"let feedback of feedbacks\">\n <div class=\"feedback-header\">\n <div class=\"feedback-user\">\n <i class=\"fas fa-user\"></i>\n {{ feedback.ReviewerUserID }}\n </div>\n <div class=\"feedback-date\">\n {{ feedback.__mj_CreatedAt | date:'medium' }}\n </div>\n </div>\n <div class=\"feedback-rating\">\n Rating: {{ feedback.Rating }}/10\n </div>\n <div class=\"feedback-correct\" *ngIf=\"feedback.IsCorrect !== null\">\n Automated Result: {{ feedback.IsCorrect ? 'Correct' : 'Incorrect' }}\n </div>\n <div class=\"feedback-comments\" *ngIf=\"feedback.CorrectionSummary\">\n {{ feedback.CorrectionSummary }}\n </div>\n </div>\n </div>\n\n <div class=\"no-data\" *ngIf=\"feedbackLoaded && feedbacks.length === 0\">\n <i class=\"fas fa-inbox\"></i>\n <p>No feedback submitted for this test run</p>\n </div>\n </div>\n </div>\n</div>\n", styles: [".test-run-form {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: #f8f9fa;\n}\n\n/* Header */\n.test-run-header {\n background: white;\n border-bottom: 1px solid #e0e0e0;\n padding: 20px;\n}\n\n.breadcrumb {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 13px;\n color: #666;\n margin-bottom: 16px;\n}\n\n.breadcrumb a {\n color: #2196f3;\n text-decoration: none;\n display: flex;\n align-items: center;\n gap: 6px;\n}\n\n.breadcrumb a:hover {\n text-decoration: underline;\n}\n\n.header-content {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 20px;\n}\n\n.header-left {\n display: flex;\n gap: 16px;\n}\n\n.test-run-icon {\n width: 56px;\n height: 56px;\n border-radius: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-size: 24px;\n}\n\n.test-run-info h1 {\n margin: 0 0 8px 0;\n font-size: 24px;\n font-weight: 600;\n color: #333;\n}\n\n.test-run-meta {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 12px;\n border-radius: 12px;\n color: white;\n font-size: 12px;\n font-weight: 600;\n}\n\n.test-type {\n font-size: 14px;\n color: #666;\n}\n\n.header-actions {\n display: flex;\n gap: 8px;\n}\n\n.metrics-bar {\n display: grid;\n grid-template-columns: repeat(5, 1fr);\n gap: 16px;\n margin-bottom: 16px;\n}\n\n.metric-card {\n background: #f5f7fa;\n border-radius: 8px;\n padding: 12px;\n text-align: center;\n}\n\n.metric-label {\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: #999;\n margin-bottom: 4px;\n}\n\n.metric-value {\n font-size: 16px;\n font-weight: 600;\n color: #333;\n}\n\n.secondary-metrics {\n display: flex;\n gap: 24px;\n padding-top: 12px;\n border-top: 1px solid #e0e0e0;\n}\n\n.metric-item {\n display: flex;\n gap: 8px;\n font-size: 14px;\n}\n\n.metric-item .metric-label {\n color: #666;\n text-transform: none;\n letter-spacing: normal;\n}\n\n.metric-item .metric-value {\n color: #333;\n font-weight: 500;\n font-size: 14px;\n}\n\n.metric-item a {\n color: #2196f3;\n text-decoration: none;\n}\n\n.metric-item a:hover {\n text-decoration: underline;\n}\n\n/* Tabs */\n.tabs-container {\n background: white;\n border-bottom: 1px solid #e0e0e0;\n}\n\n.tabs {\n display: flex;\n padding: 0 20px;\n overflow-x: auto;\n}\n\n.tab {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 16px 20px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: #666;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.tab:hover {\n color: #2196f3;\n background: rgba(33, 150, 243, 0.05);\n}\n\n.tab.active {\n color: #2196f3;\n border-bottom-color: #2196f3;\n}\n\n.tab i {\n font-size: 16px;\n}\n\n.tab-badge {\n background: #e0e0e0;\n color: #666;\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n}\n\n.tab.active .tab-badge {\n background: #e3f2fd;\n color: #2196f3;\n}\n\n/* Tab Content */\n.tab-content {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* Overview Tab */\n.overview-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n\n.result-hero {\n background: white;\n border-radius: 12px;\n padding: 32px;\n text-align: center;\n border: 3px solid #e0e0e0;\n}\n\n.result-hero.passed {\n background: #e8f5e9;\n border-color: #4caf50;\n}\n\n.result-hero.failed {\n background: #ffebee;\n border-color: #f44336;\n}\n\n.result-icon {\n font-size: 64px;\n margin-bottom: 16px;\n}\n\n.result-hero.passed .result-icon {\n color: #4caf50;\n}\n\n.result-hero.failed .result-icon {\n color: #f44336;\n}\n\n.result-text h2 {\n margin: 0 0 12px 0;\n font-size: 32px;\n font-weight: 700;\n color: #333;\n}\n\n.result-score {\n font-size: 20px;\n font-weight: 600;\n color: #666;\n margin-bottom: 8px;\n}\n\n.result-checks {\n font-size: 16px;\n color: #999;\n}\n\n.check-results {\n background: white;\n border-radius: 12px;\n padding: 20px;\n}\n\n.check-results h3 {\n margin: 0 0 16px 0;\n font-size: 18px;\n font-weight: 600;\n color: #333;\n}\n\n.check-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.check-item {\n display: flex;\n gap: 12px;\n padding: 12px;\n border-radius: 8px;\n border: 2px solid #e0e0e0;\n}\n\n.check-item.passed {\n background: #f1f8f4;\n border-color: #c8e6c9;\n}\n\n.check-item.failed {\n background: #fef5f5;\n border-color: #ffcdd2;\n}\n\n.check-icon {\n font-size: 20px;\n flex-shrink: 0;\n}\n\n.check-item.passed .check-icon {\n color: #4caf50;\n}\n\n.check-item.failed .check-icon {\n color: #f44336;\n}\n\n.check-content {\n flex: 1;\n}\n\n.check-name {\n font-size: 14px;\n font-weight: 600;\n color: #333;\n margin-bottom: 4px;\n}\n\n.check-details {\n font-size: 13px;\n color: #666;\n line-height: 1.4;\n}\n\n.check-weight {\n font-size: 12px;\n color: #999;\n margin-top: 4px;\n}\n\n.comparison-section {\n background: white;\n border-radius: 12px;\n padding: 20px;\n}\n\n.comparison-section h3 {\n margin: 0 0 16px 0;\n font-size: 18px;\n font-weight: 600;\n color: #333;\n}\n\n.comparison-tabs {\n display: flex;\n gap: 8px;\n margin-bottom: 16px;\n border-bottom: 2px solid #e0e0e0;\n}\n\n.comparison-tab {\n padding: 10px 20px;\n border: none;\n background: transparent;\n color: #666;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n border-bottom: 3px solid transparent;\n margin-bottom: -2px;\n transition: all 0.2s ease;\n}\n\n.comparison-tab:hover {\n color: #2196f3;\n}\n\n.comparison-tab.active {\n color: #2196f3;\n border-bottom-color: #2196f3;\n}\n\n.comparison-content {\n background: #1e1e1e;\n border-radius: 8px;\n padding: 16px;\n max-height: 400px;\n overflow-y: auto;\n}\n\n.comparison-content pre {\n margin: 0;\n font-family: 'Courier New', monospace;\n font-size: 13px;\n line-height: 1.5;\n color: #e0e0e0;\n white-space: pre-wrap;\n word-wrap: break-word;\n}\n\n/* Details Tab */\n.details-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n\n.details-grid {\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n gap: 16px;\n background: white;\n border-radius: 12px;\n padding: 20px;\n}\n\n.detail-item {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n\n.detail-label {\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: #999;\n}\n\n.detail-value {\n font-size: 14px;\n color: #333;\n word-wrap: break-word;\n}\n\n.detail-value a {\n color: #2196f3;\n text-decoration: none;\n}\n\n.detail-value a:hover {\n text-decoration: underline;\n}\n\n.error-message, .result-details-json {\n background: white;\n border-radius: 12px;\n padding: 20px;\n}\n\n.error-message h4, .result-details-json h4 {\n margin: 0 0 12px 0;\n font-size: 16px;\n font-weight: 600;\n color: #333;\n}\n\n.error-message pre, .result-details-json pre {\n margin: 0;\n font-family: 'Courier New', monospace;\n font-size: 13px;\n line-height: 1.5;\n color: #333;\n white-space: pre-wrap;\n word-wrap: break-word;\n background: #f5f7fa;\n padding: 16px;\n border-radius: 8px;\n}\n\n/* AI Runs Tab */\n.ai-runs-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n}\n\n.ai-runs-section {\n background: white;\n border-radius: 12px;\n padding: 20px;\n}\n\n.ai-runs-section h3 {\n margin: 0 0 16px 0;\n font-size: 18px;\n font-weight: 600;\n color: #333;\n}\n\n.ai-run-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.ai-run-card {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 16px;\n background: #f8f9fa;\n border: 2px solid transparent;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s ease;\n}\n\n.ai-run-card:hover {\n background: #e3f2fd;\n border-color: #90caf9;\n}\n\n.ai-run-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: #2196f3;\n color: white;\n border-radius: 8px;\n font-size: 18px;\n flex-shrink: 0;\n}\n\n.ai-run-icon.prompt {\n background: #9c27b0;\n}\n\n.ai-run-content {\n flex: 1;\n}\n\n.ai-run-name {\n font-size: 14px;\n font-weight: 600;\n color: #333;\n margin-bottom: 4px;\n}\n\n.ai-run-meta {\n display: flex;\n gap: 12px;\n font-size: 12px;\n color: #666;\n}\n\n.ai-run-card > i {\n color: #999;\n font-size: 14px;\n}\n\n/* Feedback Tab */\n.feedback-tab {\n background: white;\n border-radius: 12px;\n padding: 20px;\n}\n\n.feedback-list {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.feedback-item {\n padding: 16px;\n background: #f8f9fa;\n border-radius: 8px;\n border: 1px solid #e0e0e0;\n}\n\n.feedback-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 12px;\n}\n\n.feedback-user {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 14px;\n font-weight: 600;\n color: #333;\n}\n\n.feedback-date {\n font-size: 12px;\n color: #999;\n}\n\n.feedback-rating {\n font-size: 14px;\n color: #666;\n margin-bottom: 8px;\n}\n\n.feedback-correct {\n font-size: 14px;\n color: #666;\n margin-bottom: 8px;\n}\n\n.feedback-comments {\n font-size: 14px;\n line-height: 1.5;\n color: #333;\n padding: 12px;\n background: white;\n border-radius: 6px;\n border-left: 3px solid #2196f3;\n}\n\n/* No Data State */\n.no-data {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 20px;\n color: #999;\n text-align: center;\n}\n\n.no-data i {\n font-size: 48px;\n margin-bottom: 16px;\n opacity: 0.3;\n}\n\n.no-data p {\n margin: 0;\n font-size: 14px;\n}\n\n/* Responsive */\n@media (max-width: 1200px) {\n .metrics-bar {\n grid-template-columns: repeat(3, 1fr);\n }\n}\n\n@media (max-width: 768px) {\n .metrics-bar {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .details-grid {\n grid-template-columns: 1fr;\n }\n\n .header-content {\n flex-direction: column;\n gap: 16px;\n }\n\n .tabs {\n overflow-x: auto;\n }\n}\n"] }]
915
- }], () => [{ type: i0.ElementRef }, { type: i1.SharedService }, { type: i2.Router }, { type: i2.ActivatedRoute }, { type: i0.ChangeDetectorRef }], null); })();
916
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestRunFormComponentExtended, { className: "TestRunFormComponentExtended", filePath: "src/lib/custom/Tests/test-run-form.component.ts", lineNumber: 26 }); })();
1564
+ args: [{ selector: 'mj-test-run-form', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"test-run-form\" [class.is-mobile]=\"false\">\n <!-- Error State -->\n <div class=\"error-banner\" *ngIf=\"error\" (click)=\"retryLoad()\">\n <i class=\"fas fa-exclamation-triangle\"></i>\n <span>{{ error }}</span>\n <button class=\"retry-btn\">\n <i class=\"fas fa-redo\"></i> Retry\n </button>\n </div>\n\n <!-- Header Section -->\n <div class=\"test-run-header\" [class]=\"getStatusClass()\">\n <!-- Breadcrumb Navigation -->\n <nav class=\"breadcrumb\" aria-label=\"Breadcrumb\">\n <ol>\n <li>\n <a href=\"javascript:void(0)\" (click)=\"navigateToTestingDashboard()\">\n <i class=\"fas fa-vial\"></i>\n <span class=\"breadcrumb-text\">Testing</span>\n </a>\n </li>\n <li *ngIf=\"test\">\n <i class=\"fas fa-chevron-right separator\"></i>\n <a href=\"javascript:void(0)\" (click)=\"openTest()\">\n <i class=\"fas fa-flask\"></i>\n <span class=\"breadcrumb-text\">{{ test.Name }}</span>\n </a>\n </li>\n <li class=\"current\">\n <i class=\"fas fa-chevron-right separator\"></i>\n <span>Run #{{ record.ID.substring(0, 8) }}</span>\n </li>\n </ol>\n </nav>\n\n <div class=\"header-content\">\n <div class=\"header-left\">\n <!-- Status Indicator -->\n <div class=\"status-indicator\" [style.background-color]=\"getStatusColor()\">\n <i class=\"fas\" [ngClass]=\"getStatusIcon()\"></i>\n </div>\n\n <div class=\"test-run-info\">\n <h1>\n Test Run\n <span class=\"run-id\">#{{ record.ID.substring(0, 8) }}</span>\n </h1>\n <div class=\"test-run-meta\">\n <span class=\"status-badge\" [style.background-color]=\"getStatusColor()\">\n {{ record.Status }}\n </span>\n <span class=\"meta-item\" *ngIf=\"test\">\n <i class=\"fas fa-flask\"></i>\n {{ test.Type }}\n </span>\n <span class=\"meta-item\" *ngIf=\"autoRefreshEnabled\">\n <i class=\"fas fa-sync-alt fa-spin\"></i>\n Auto-refreshing\n </span>\n </div>\n </div>\n </div>\n\n <div class=\"header-actions\">\n <button kendoButton (click)=\"reRunTest()\" [disabled]=\"!record.TestID\" title=\"Re-run this test (Cmd+Shift+R)\">\n <i class=\"fas fa-redo\"></i>\n <span class=\"btn-text\">Re-run</span>\n </button>\n <button kendoButton (click)=\"refresh()\" [disabled]=\"isRefreshing\" title=\"Refresh (Cmd+R)\">\n <i class=\"fas fa-sync-alt\" [class.fa-spin]=\"isRefreshing\"></i>\n <span class=\"btn-text\">Refresh</span>\n </button>\n </div>\n </div>\n\n <!-- Metrics Bar -->\n <div class=\"metrics-bar\">\n <div class=\"metric-card\">\n <div class=\"metric-icon\">\n <i class=\"fas fa-clock\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-label\">Started</div>\n <div class=\"metric-value\">{{ getRelativeTime(record.StartedAt) }}</div>\n <div class=\"metric-detail\">{{ record.StartedAt | date:'short' }}</div>\n </div>\n </div>\n\n <div class=\"metric-card\">\n <div class=\"metric-icon\">\n <i class=\"fas fa-stopwatch\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-label\">Duration</div>\n <div class=\"metric-value\">{{ calculateDuration() }}</div>\n </div>\n </div>\n\n <div class=\"metric-card\">\n <div class=\"metric-icon\">\n <i class=\"fas fa-star\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-label\">Score</div>\n <div class=\"metric-value\">{{ formatScore(record.Score) }}</div>\n <div class=\"metric-progress\" *ngIf=\"record.Score != null\">\n <div class=\"progress-bar\" [style.width.%]=\"getScorePercentage()\" [style.background-color]=\"getStatusColor()\"></div>\n </div>\n </div>\n </div>\n\n <div class=\"metric-card\">\n <div class=\"metric-icon\">\n <i class=\"fas fa-check-double\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-label\">Checks</div>\n <div class=\"metric-value\">{{ record.PassedChecks }}/{{ record.TotalChecks }}</div>\n <div class=\"metric-progress\" *ngIf=\"record.TotalChecks\">\n <div class=\"progress-bar\" [style.width.%]=\"getPassRatePercentage()\" [style.background-color]=\"getStatusColor()\"></div>\n </div>\n </div>\n </div>\n\n <div class=\"metric-card\">\n <div class=\"metric-icon\">\n <i class=\"fas fa-dollar-sign\"></i>\n </div>\n <div class=\"metric-content\">\n <div class=\"metric-label\">Cost</div>\n <div class=\"metric-value\">{{ formatCost(record.CostUSD) }}</div>\n </div>\n </div>\n </div>\n\n <!-- Secondary Info -->\n <div class=\"secondary-info\" *ngIf=\"record.RunByUser || testSuiteRun || record.TargetLogEntityID\">\n <span class=\"info-chip\" *ngIf=\"record.RunByUser\">\n <i class=\"fas fa-user\"></i>\n {{ record.RunByUser }}\n </span>\n <span class=\"info-chip clickable\" *ngIf=\"testSuiteRun\" (click)=\"openTestSuiteRun()\">\n <i class=\"fas fa-layer-group\"></i>\n Part of Suite Run (Seq: {{ record.Sequence }})\n </span>\n <!-- Target Entity Link Pill -->\n <mj-entity-link-pill\n *ngIf=\"record.TargetLogEntityID && record.TargetLogID\"\n [entityName]=\"record.TargetLogEntity\"\n [recordId]=\"record.TargetLogID\">\n </mj-entity-link-pill>\n </div>\n\n <!-- Tags Section - Sleek inline design -->\n <div class=\"tags-bar\" *ngIf=\"!editingTags\">\n <div class=\"tags-bar-content\">\n <span class=\"tags-bar-label\"><i class=\"fas fa-tags\"></i></span>\n <div class=\"tags-bar-chips\" *ngIf=\"tags.length > 0\">\n <span class=\"tag-inline\" *ngFor=\"let tag of tags\">{{ tag }}</span>\n </div>\n <span class=\"tags-bar-empty\" *ngIf=\"tags.length === 0\">No tags</span>\n <button class=\"tags-bar-edit\" (click)=\"startEditingTags()\" title=\"Edit tags\">\n <i class=\"fas fa-plus\"></i> Add\n </button>\n </div>\n </div>\n\n <!-- Tags Editor - Expanded when editing -->\n <div class=\"tags-editor-panel\" *ngIf=\"editingTags\">\n <div class=\"tags-editor-header\">\n <span class=\"tags-editor-title\"><i class=\"fas fa-tags\"></i> Edit Tags</span>\n </div>\n <div class=\"tags-editor-body\">\n <div class=\"tags-editor-chips\">\n <span class=\"tag-editable\" *ngFor=\"let tag of tags\">\n {{ tag }}\n <button class=\"tag-remove-btn\" (click)=\"removeTag(tag)\" title=\"Remove tag\">\n <i class=\"fas fa-times\"></i>\n </button>\n </span>\n <span class=\"tags-empty-hint\" *ngIf=\"tags.length === 0\">No tags yet</span>\n </div>\n <div class=\"tags-editor-input\">\n <input type=\"text\"\n [(ngModel)]=\"newTag\"\n placeholder=\"Type a tag and press Enter...\"\n (keyup.enter)=\"addTag()\"\n class=\"tag-text-input\" />\n <button kendoButton (click)=\"addTag()\" [disabled]=\"!newTag.trim()\" fillMode=\"flat\">\n <i class=\"fas fa-plus\"></i>\n </button>\n </div>\n </div>\n <div class=\"tags-editor-footer\">\n <button kendoButton (click)=\"saveTags()\" themeColor=\"primary\" [disabled]=\"savingTags\">\n <i class=\"fas fa-spinner fa-spin\" *ngIf=\"savingTags\"></i>\n {{ savingTags ? 'Saving...' : 'Save' }}\n </button>\n <button kendoButton (click)=\"cancelEditingTags()\" fillMode=\"flat\">Cancel</button>\n </div>\n </div>\n </div>\n\n <!-- Tabs -->\n <div class=\"tabs-container\">\n <div class=\"tabs\" role=\"tablist\">\n <button class=\"tab\" [class.active]=\"activeTab === 'overview'\" (click)=\"changeTab('overview')\"\n role=\"tab\" [attr.aria-selected]=\"activeTab === 'overview'\" title=\"Press 1\">\n <i class=\"fas fa-chart-pie\"></i>\n <span>Overview</span>\n </button>\n <button class=\"tab\" [class.active]=\"activeTab === 'details'\" (click)=\"changeTab('details')\"\n role=\"tab\" [attr.aria-selected]=\"activeTab === 'details'\" title=\"Press 2\">\n <i class=\"fas fa-info-circle\"></i>\n <span>Details</span>\n </button>\n <button class=\"tab\" [class.active]=\"activeTab === 'ai-runs'\" (click)=\"changeTab('ai-runs')\"\n role=\"tab\" [attr.aria-selected]=\"activeTab === 'ai-runs'\" title=\"Press 3\">\n <i class=\"fas fa-robot\"></i>\n <span>AI Runs</span>\n <span class=\"tab-badge\" *ngIf=\"aiRunsLoaded\">{{ aiAgentRuns.length + aiPromptRuns.length }}</span>\n </button>\n <button class=\"tab\" [class.active]=\"activeTab === 'feedback'\" (click)=\"changeTab('feedback')\"\n role=\"tab\" [attr.aria-selected]=\"activeTab === 'feedback'\" title=\"Press 4\">\n <i class=\"fas fa-comments\"></i>\n <span>Feedback</span>\n <span class=\"tab-badge\" *ngIf=\"feedbackLoaded\">{{ feedbacks.length }}</span>\n </button>\n <button class=\"tab\" [class.active]=\"activeTab === 'execution'\" (click)=\"changeTab('execution')\"\n role=\"tab\" [attr.aria-selected]=\"activeTab === 'execution'\" title=\"Press 5\">\n <i class=\"fas fa-microchip\"></i>\n <span>Execution</span>\n </button>\n <button class=\"tab\" [class.active]=\"activeTab === 'log'\" (click)=\"changeTab('log')\" *ngIf=\"record.Log\"\n role=\"tab\" [attr.aria-selected]=\"activeTab === 'log'\" title=\"Press 6\">\n <i class=\"fas fa-terminal\"></i>\n <span>Log</span>\n </button>\n </div>\n </div>\n\n <!-- Tab Content -->\n <div class=\"tab-content\">\n <!-- Overview Tab -->\n <div class=\"overview-tab\" *ngIf=\"activeTab === 'overview'\" [@fadeIn]>\n <!-- Result Hero -->\n <div class=\"result-hero\" [class]=\"getStatusClass()\">\n <div class=\"result-icon-wrapper\">\n <div class=\"result-icon\">\n <i class=\"fas\" [ngClass]=\"getStatusIcon()\"></i>\n </div>\n <div class=\"result-pulse\" *ngIf=\"record.Status === 'Running'\"></div>\n </div>\n <div class=\"result-text\">\n <h2>TEST {{ record.Status.toUpperCase() }}</h2>\n <div class=\"result-details\">\n <span class=\"result-score\">Score: {{ formatScore(record.Score) }}</span>\n <span class=\"result-divider\">|</span>\n <span class=\"result-checks\">{{ record.PassedChecks }} of {{ record.TotalChecks }} checks passed</span>\n </div>\n </div>\n </div>\n\n <!-- Check Results -->\n <div class=\"check-results\" *ngIf=\"getCheckResults().length > 0\">\n <div class=\"section-header\">\n <h3><i class=\"fas fa-tasks\"></i> Check Results</h3>\n <span class=\"check-summary\">{{ record.PassedChecks }} passed, {{ record.FailedChecks }} failed</span>\n </div>\n <div class=\"check-list\">\n <div class=\"check-item\" *ngFor=\"let check of getCheckResults(); let i = index\"\n [class.passed]=\"check.passed\" [class.failed]=\"!check.passed\"\n [style.animation-delay.ms]=\"i * 50\">\n <div class=\"check-status\">\n <i class=\"fas\" [class.fa-check-circle]=\"check.passed\" [class.fa-times-circle]=\"!check.passed\"></i>\n </div>\n <div class=\"check-content\">\n <div class=\"check-name\">{{ check.name }}</div>\n <div class=\"check-message\" *ngIf=\"check.message\">{{ check.message }}</div>\n </div>\n <div class=\"check-weight\" *ngIf=\"check.weight\">\n <span class=\"weight-label\">Weight:</span> {{ check.weight }}\n </div>\n </div>\n </div>\n </div>\n\n <!-- Data Comparison -->\n <div class=\"comparison-section\">\n <div class=\"section-header\">\n <h3><i class=\"fas fa-exchange-alt\"></i> Data Comparison</h3>\n </div>\n <div class=\"comparison-tabs\">\n <button class=\"comparison-tab\" [class.active]=\"comparisonView === 'input'\" (click)=\"setComparisonView('input')\">\n <i class=\"fas fa-sign-in-alt\"></i> Input\n </button>\n <button class=\"comparison-tab\" [class.active]=\"comparisonView === 'expected'\" (click)=\"setComparisonView('expected')\">\n <i class=\"fas fa-bullseye\"></i> Expected\n </button>\n <button class=\"comparison-tab\" [class.active]=\"comparisonView === 'actual'\" (click)=\"setComparisonView('actual')\">\n <i class=\"fas fa-check-square\"></i> Actual\n </button>\n </div>\n <div class=\"comparison-content\">\n <mj-code-editor\n [value]=\"getComparisonData()\"\n language=\"json\"\n [readonly]=\"true\"\n [toolbar]=\"jsonToolbar\"\n [lineWrapping]=\"true\">\n </mj-code-editor>\n </div>\n </div>\n </div>\n\n <!-- Details Tab -->\n <div class=\"details-tab\" *ngIf=\"activeTab === 'details'\" [@fadeIn]>\n <div class=\"details-grid\">\n <div class=\"detail-card\">\n <div class=\"detail-icon\"><i class=\"fas fa-fingerprint\"></i></div>\n <div class=\"detail-content\">\n <div class=\"detail-label\">Test Run ID</div>\n <div class=\"detail-value monospace\">{{ record.ID }}</div>\n </div>\n </div>\n\n <div class=\"detail-card clickable\" *ngIf=\"test\" (click)=\"openTest()\">\n <div class=\"detail-icon\"><i class=\"fas fa-flask\"></i></div>\n <div class=\"detail-content\">\n <div class=\"detail-label\">Test</div>\n <div class=\"detail-value link\">{{ test.Name }}</div>\n </div>\n <i class=\"fas fa-external-link-alt detail-action\"></i>\n </div>\n\n <div class=\"detail-card\">\n <div class=\"detail-icon\"><i class=\"fas fa-tag\"></i></div>\n <div class=\"detail-content\">\n <div class=\"detail-label\">Target Type</div>\n <div class=\"detail-value\">{{ record.TargetType || 'N/A' }}</div>\n </div>\n </div>\n\n <div class=\"detail-card\">\n <div class=\"detail-icon\"><i class=\"fas fa-play-circle\"></i></div>\n <div class=\"detail-content\">\n <div class=\"detail-label\">Started At</div>\n <div class=\"detail-value\">{{ record.StartedAt | date:'medium' }}</div>\n </div>\n </div>\n\n <div class=\"detail-card\">\n <div class=\"detail-icon\"><i class=\"fas fa-stop-circle\"></i></div>\n <div class=\"detail-content\">\n <div class=\"detail-label\">Completed At</div>\n <div class=\"detail-value\">{{ record.CompletedAt | date:'medium' }}</div>\n </div>\n </div>\n\n <div class=\"detail-card\">\n <div class=\"detail-icon\"><i class=\"fas fa-hourglass-half\"></i></div>\n <div class=\"detail-content\">\n <div class=\"detail-label\">Duration</div>\n <div class=\"detail-value\">{{ calculateDuration() }}</div>\n </div>\n </div>\n </div>\n\n <!-- Error Message -->\n <div class=\"error-section\" *ngIf=\"record.ErrorMessage\">\n <div class=\"section-header error\">\n <h3><i class=\"fas fa-exclamation-triangle\"></i> Error Message</h3>\n </div>\n <div class=\"error-content\">\n <mj-code-editor\n [value]=\"record.ErrorMessage\"\n [readonly]=\"true\"\n [toolbar]=\"jsonToolbar\"\n [lineWrapping]=\"true\">\n </mj-code-editor>\n </div>\n </div>\n\n <!-- Result Details -->\n <div class=\"result-details-section\" *ngIf=\"parsedData.resultDetails\">\n <div class=\"section-header\">\n <h3><i class=\"fas fa-file-code\"></i> Result Details</h3>\n </div>\n <div class=\"result-details-content\">\n <mj-code-editor\n [value]=\"getFormattedResultDetails()\"\n language=\"json\"\n [readonly]=\"true\"\n [toolbar]=\"jsonToolbar\"\n [lineWrapping]=\"true\">\n </mj-code-editor>\n </div>\n </div>\n </div>\n\n <!-- AI Runs Tab -->\n <div class=\"ai-runs-tab\" *ngIf=\"activeTab === 'ai-runs'\" [@fadeIn]>\n <!-- Loading State -->\n <div class=\"loading-state\" *ngIf=\"loadingAIRuns\">\n <div class=\"skeleton-list\">\n <div class=\"skeleton-card\" *ngFor=\"let i of [1,2,3]\">\n <div class=\"skeleton-icon\"></div>\n <div class=\"skeleton-content\">\n <div class=\"skeleton-line wide\"></div>\n <div class=\"skeleton-line narrow\"></div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- AI Agent Runs -->\n <div class=\"ai-section\" *ngIf=\"!loadingAIRuns && aiAgentRuns.length > 0\">\n <div class=\"section-header\">\n <h3><i class=\"fas fa-robot\"></i> AI Agent Runs</h3>\n <span class=\"count-badge\">{{ aiAgentRuns.length }}</span>\n </div>\n <div class=\"ai-run-list\">\n <div class=\"ai-run-card\" *ngFor=\"let run of aiAgentRuns\" (click)=\"openAIAgentRun(run.ID)\">\n <div class=\"ai-run-icon agent\">\n <i class=\"fas fa-robot\"></i>\n </div>\n <div class=\"ai-run-content\">\n <div class=\"ai-run-name\">{{ run.Agent }}</div>\n <div class=\"ai-run-meta\">\n <span class=\"status-chip\" [class]=\"run.Status.toLowerCase()\">{{ run.Status }}</span>\n <span *ngIf=\"run.TotalCost\" class=\"cost-chip\">\n <i class=\"fas fa-dollar-sign\"></i> {{ run.TotalCost | number:'1.4-4' }}\n </span>\n </div>\n </div>\n <i class=\"fas fa-chevron-right ai-run-arrow\"></i>\n </div>\n </div>\n </div>\n\n <!-- AI Prompt Runs -->\n <div class=\"ai-section\" *ngIf=\"!loadingAIRuns && aiPromptRuns.length > 0\">\n <div class=\"section-header\">\n <h3><i class=\"fas fa-comment-dots\"></i> AI Prompt Runs</h3>\n <span class=\"count-badge\">{{ aiPromptRuns.length }}</span>\n </div>\n <div class=\"ai-run-list\">\n <div class=\"ai-run-card\" *ngFor=\"let run of aiPromptRuns\" (click)=\"openAIPromptRun(run.ID)\">\n <div class=\"ai-run-icon prompt\">\n <i class=\"fas fa-comment-dots\"></i>\n </div>\n <div class=\"ai-run-content\">\n <div class=\"ai-run-name\">{{ run.Prompt || run.Model }}</div>\n <div class=\"ai-run-meta\">\n <span *ngIf=\"run.TotalCost\" class=\"cost-chip\">\n <i class=\"fas fa-dollar-sign\"></i> {{ run.TotalCost | number:'1.4-4' }}\n </span>\n </div>\n </div>\n <i class=\"fas fa-chevron-right ai-run-arrow\"></i>\n </div>\n </div>\n </div>\n\n <!-- Empty State -->\n <div class=\"empty-state\" *ngIf=\"aiRunsLoaded && aiAgentRuns.length === 0 && aiPromptRuns.length === 0\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-robot\"></i>\n </div>\n <h3>No AI Runs</h3>\n <p>This test execution didn't involve any AI agent or prompt runs.</p>\n </div>\n </div>\n\n <!-- Feedback Tab -->\n <div class=\"feedback-tab\" *ngIf=\"activeTab === 'feedback'\" [@fadeIn]>\n <!-- Loading State -->\n <div class=\"loading-state\" *ngIf=\"loadingFeedback\">\n <div class=\"skeleton-list\">\n <div class=\"skeleton-card\" *ngFor=\"let i of [1,2]\">\n <div class=\"skeleton-avatar\"></div>\n <div class=\"skeleton-content\">\n <div class=\"skeleton-line wide\"></div>\n <div class=\"skeleton-line narrow\"></div>\n <div class=\"skeleton-line medium\"></div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Feedback List -->\n <div class=\"feedback-list\" *ngIf=\"!loadingFeedback && feedbacks.length > 0\">\n <div class=\"feedback-item\" *ngFor=\"let feedback of feedbacks\">\n <div class=\"feedback-header\">\n <div class=\"feedback-user\">\n <div class=\"user-avatar\">\n <i class=\"fas fa-user\"></i>\n </div>\n <span class=\"user-name\">{{ feedback.ReviewerUser }}</span>\n </div>\n <div class=\"feedback-date\">\n {{ getRelativeTime(feedback.__mj_CreatedAt) }}\n </div>\n </div>\n <div class=\"feedback-body\">\n <div class=\"feedback-rating\">\n <div class=\"rating-stars\">\n <i class=\"fas fa-star\" *ngFor=\"let s of [1,2,3,4,5,6,7,8,9,10]\"\n [class.filled]=\"s <= (feedback.Rating || 0)\"></i>\n </div>\n <span class=\"rating-value\">{{ feedback.Rating }}/10</span>\n </div>\n <div class=\"feedback-verdict\" *ngIf=\"feedback.IsCorrect !== null\">\n <span class=\"verdict-badge\" [class.correct]=\"feedback.IsCorrect\" [class.incorrect]=\"!feedback.IsCorrect\">\n <i class=\"fas\" [class.fa-check]=\"feedback.IsCorrect\" [class.fa-times]=\"!feedback.IsCorrect\"></i>\n {{ feedback.IsCorrect ? 'Marked Correct' : 'Marked Incorrect' }}\n </span>\n </div>\n <div class=\"feedback-comments\" *ngIf=\"feedback.CorrectionSummary\">\n <p>{{ feedback.CorrectionSummary }}</p>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Empty State -->\n <div class=\"empty-state\" *ngIf=\"feedbackLoaded && feedbacks.length === 0\">\n <div class=\"empty-icon\">\n <i class=\"fas fa-comments\"></i>\n </div>\n <h3>No Feedback Yet</h3>\n <p>No one has reviewed this test run yet. Be the first to provide feedback!</p>\n </div>\n </div>\n\n <!-- Execution Context Tab -->\n <div class=\"execution-tab\" *ngIf=\"activeTab === 'execution'\" [@fadeIn]>\n <mj-execution-context\n [machineName]=\"record.MachineName\"\n [machineId]=\"record.MachineID\"\n [runByUserName]=\"record.RunByUserName\"\n [runByUserEmail]=\"record.RunByUserEmail\"\n [runContextDetailsJson]=\"record.RunContextDetails\">\n </mj-execution-context>\n </div>\n\n <!-- Execution Log Tab -->\n <div class=\"log-tab\" *ngIf=\"activeTab === 'log'\" [@fadeIn]>\n <div class=\"log-header\">\n <div class=\"log-title\">\n <i class=\"fas fa-terminal\"></i>\n <h3>Execution Log</h3>\n </div>\n <div class=\"log-actions\">\n <button kendoButton (click)=\"copyLogToClipboard()\" look=\"flat\">\n <i class=\"fas fa-copy\"></i>\n <span class=\"btn-text\">Copy</span>\n </button>\n </div>\n </div>\n <div class=\"log-container\">\n <mj-code-editor\n [value]=\"record.Log || ''\"\n [readonly]=\"true\"\n [toolbar]=\"jsonToolbar\"\n [lineWrapping]=\"true\">\n </mj-code-editor>\n </div>\n </div>\n </div>\n\n <!-- Keyboard Shortcuts Help (shown on hover of ? icon) -->\n <div class=\"shortcuts-hint\" title=\"Keyboard Shortcuts\">\n <i class=\"fas fa-keyboard\"></i>\n <div class=\"shortcuts-popup\">\n <h4>Keyboard Shortcuts</h4>\n <ul>\n <li><kbd>1-6</kbd> Switch tabs</li>\n <li><kbd>Cmd+R</kbd> Refresh</li>\n <li><kbd>Cmd+Shift+R</kbd> Re-run test</li>\n </ul>\n </div>\n </div>\n</div>\n", styles: ["/* ===========================\n Test Run Form - World-Class UX\n Premium Testing Dashboard Styles\n =========================== */\n\n/* CSS Custom Properties for Theming - using :host for Angular encapsulation */\n:host {\n --test-primary: #2563eb;\n --test-primary-light: #3b82f6;\n --test-primary-dark: #1d4ed8;\n --test-success: #10b981;\n --test-success-light: #d1fae5;\n --test-error: #ef4444;\n --test-error-light: #fee2e2;\n --test-warning: #f59e0b;\n --test-warning-light: #fef3c7;\n --test-timeout: #f97316;\n --test-timeout-light: #ffedd5;\n --test-running: #3b82f6;\n --test-pending: #8b5cf6;\n --test-skipped: #6b7280;\n --test-bg: #f8fafc;\n --test-surface: #ffffff;\n --test-border: #e2e8f0;\n --test-text: #1e293b;\n --test-text-secondary: #64748b;\n --test-text-muted: #94a3b8;\n --test-radius-sm: 6px;\n --test-radius-md: 10px;\n --test-radius-lg: 16px;\n --test-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);\n --test-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);\n --test-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);\n --test-transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n display: block;\n height: 100%;\n}\n\n/* Base Container */\n.test-run-form {\n display: flex;\n flex-direction: column;\n height: 100%;\n background: var(--test-bg);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n/* ===========================\n Error Banner\n =========================== */\n.error-banner {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 12px 20px;\n background: linear-gradient(135deg, var(--test-error) 0%, #dc2626 100%);\n color: white;\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n animation: slideDown 0.3s ease-out;\n}\n\n.error-banner:hover {\n background: linear-gradient(135deg, #dc2626 0%, #b91c1c 100%);\n}\n\n.error-banner i {\n font-size: 16px;\n}\n\n.retry-btn {\n background: rgba(255, 255, 255, 0.2);\n border: 1px solid rgba(255, 255, 255, 0.3);\n color: white;\n padding: 6px 12px;\n border-radius: var(--test-radius-sm);\n cursor: pointer;\n font-size: 12px;\n font-weight: 600;\n transition: var(--test-transition);\n}\n\n.retry-btn:hover {\n background: rgba(255, 255, 255, 0.3);\n}\n\n@keyframes slideDown {\n from {\n transform: translateY(-100%);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n/* ===========================\n Header Section\n =========================== */\n.test-run-header {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n padding: 20px;\n position: relative;\n}\n\n/* Breadcrumb */\n.breadcrumb {\n margin-bottom: 16px;\n}\n\n.breadcrumb ol {\n display: flex;\n align-items: center;\n gap: 4px;\n list-style: none;\n margin: 0;\n padding: 0;\n font-size: 13px;\n flex-wrap: wrap;\n}\n\n.breadcrumb li {\n display: flex;\n align-items: center;\n gap: 4px;\n}\n\n.breadcrumb a {\n color: var(--test-primary);\n text-decoration: none;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 4px 8px;\n border-radius: var(--test-radius-sm);\n transition: var(--test-transition);\n}\n\n.breadcrumb a:hover {\n background: rgba(37, 99, 235, 0.1);\n text-decoration: none;\n}\n\n.breadcrumb .separator {\n font-size: 10px;\n color: var(--test-text-muted);\n margin: 0 4px;\n}\n\n.breadcrumb .current {\n color: var(--test-text-secondary);\n font-weight: 500;\n}\n\n.breadcrumb-text {\n max-width: 200px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* Header Content */\n.header-content {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n margin-bottom: 20px;\n gap: 16px;\n}\n\n.header-left {\n display: flex;\n gap: 16px;\n flex: 1;\n min-width: 0;\n}\n\n/* Status Indicator */\n.status-indicator {\n width: 56px;\n height: 56px;\n border-radius: var(--test-radius-md);\n display: flex;\n align-items: center;\n justify-content: center;\n color: white;\n font-size: 24px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.status-indicator:hover {\n transform: scale(1.05);\n}\n\n/* Test Run Info */\n.test-run-info {\n flex: 1;\n min-width: 0;\n}\n\n.test-run-info h1 {\n margin: 0 0 8px 0;\n font-size: clamp(18px, 4vw, 24px);\n font-weight: 700;\n color: var(--test-text);\n line-height: 1.2;\n word-wrap: break-word;\n}\n\n.test-run-info h1 .run-id {\n color: var(--test-text-secondary);\n font-weight: 500;\n}\n\n.test-run-meta {\n display: flex;\n align-items: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n/* Status Badge */\n.status-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 14px;\n border-radius: 20px;\n color: white;\n font-size: 12px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n box-shadow: var(--test-shadow-sm);\n}\n\n/* Meta Item */\n.meta-item {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 14px;\n color: var(--test-text-secondary);\n}\n\n.meta-item i {\n font-size: 12px;\n}\n\n/* Header Actions */\n.header-actions {\n display: flex;\n gap: 8px;\n flex-shrink: 0;\n}\n\n.header-actions button {\n white-space: nowrap;\n}\n\n.btn-text {\n margin-left: 6px;\n}\n\n/* ===========================\n Metrics Bar\n =========================== */\n.metrics-bar {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));\n gap: 12px;\n margin-bottom: 16px;\n}\n\n.metric-card {\n display: flex;\n align-items: center;\n gap: 12px;\n background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 14px;\n transition: var(--test-transition);\n}\n\n.metric-card:hover {\n transform: translateY(-2px);\n box-shadow: var(--test-shadow-md);\n}\n\n.metric-icon {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-sm);\n color: var(--test-primary);\n font-size: 16px;\n flex-shrink: 0;\n}\n\n.metric-content {\n flex: 1;\n min-width: 0;\n}\n\n.metric-label {\n font-size: 10px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n margin-bottom: 4px;\n}\n\n.metric-value {\n font-size: 16px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.metric-detail {\n font-size: 11px;\n color: var(--test-text-muted);\n margin-top: 2px;\n}\n\n/* Progress bar in metric card */\n.metric-progress {\n margin-top: 6px;\n height: 4px;\n background: var(--test-border);\n border-radius: 2px;\n overflow: hidden;\n}\n\n.progress-bar {\n height: 100%;\n border-radius: 2px;\n transition: width 0.5s ease-out;\n}\n\n/* Secondary Info */\n.secondary-info {\n display: flex;\n gap: 12px;\n padding-top: 16px;\n border-top: 1px solid var(--test-border);\n flex-wrap: wrap;\n}\n\n.info-chip {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n font-size: 13px;\n color: var(--test-text-secondary);\n padding: 6px 12px;\n background: var(--test-bg);\n border-radius: 20px;\n transition: var(--test-transition);\n}\n\n.info-chip i {\n font-size: 12px;\n}\n\n.info-chip.clickable {\n cursor: pointer;\n}\n\n.info-chip.clickable:hover {\n background: rgba(37, 99, 235, 0.1);\n color: var(--test-primary);\n}\n\n/* ===========================\n Tabs Navigation\n =========================== */\n.tabs-container {\n background: var(--test-surface);\n border-bottom: 1px solid var(--test-border);\n position: sticky;\n top: 0;\n z-index: 10;\n}\n\n.tabs {\n display: flex;\n padding: 0 20px;\n overflow-x: auto;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n -ms-overflow-style: none;\n}\n\n.tabs::-webkit-scrollbar {\n display: none;\n}\n\n.tab {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 14px 18px;\n border: none;\n background: transparent;\n border-bottom: 3px solid transparent;\n color: var(--test-text-secondary);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: var(--test-transition);\n white-space: nowrap;\n position: relative;\n}\n\n.tab:hover {\n color: var(--test-primary);\n background: rgba(37, 99, 235, 0.05);\n}\n\n.tab.active {\n color: var(--test-primary);\n border-bottom-color: var(--test-primary);\n font-weight: 600;\n}\n\n.tab i {\n font-size: 15px;\n}\n\n.tab-badge {\n background: var(--test-border);\n color: var(--test-text-secondary);\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n transition: var(--test-transition);\n}\n\n.tab.active .tab-badge {\n background: rgba(37, 99, 235, 0.15);\n color: var(--test-primary);\n}\n\n.shortcut-hint {\n font-size: 10px;\n color: var(--test-text-muted);\n background: var(--test-bg);\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n margin-left: 4px;\n font-family: -apple-system, BlinkMacSystemFont, sans-serif;\n}\n\n/* ===========================\n Tab Content Area\n =========================== */\n.tab-content {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n scroll-behavior: smooth;\n}\n\n/* ===========================\n Overview Tab\n =========================== */\n.overview-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: fadeIn 0.3s ease-out;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* Result Hero Card */\n.result-hero {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 32px;\n text-align: center;\n border: 2px solid var(--test-border);\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.result-hero.passed {\n background: linear-gradient(135deg, #ecfdf5 0%, var(--test-success-light) 100%);\n border-color: var(--test-success);\n}\n\n.result-hero.failed {\n background: linear-gradient(135deg, #fef2f2 0%, var(--test-error-light) 100%);\n border-color: var(--test-error);\n}\n\n.result-hero.error {\n background: linear-gradient(135deg, #fffbeb 0%, var(--test-warning-light) 100%);\n border-color: var(--test-warning);\n}\n\n.result-hero.timeout {\n background: linear-gradient(135deg, #fff7ed 0%, var(--test-timeout-light) 100%);\n border-color: var(--test-timeout);\n}\n\n.result-hero.running,\n.result-hero.pending {\n background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);\n border-color: var(--test-primary-light);\n}\n\n.result-icon-wrapper {\n position: relative;\n display: inline-block;\n margin-bottom: 16px;\n}\n\n.result-icon {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-surface);\n border-radius: 50%;\n font-size: 40px;\n margin: 0 auto;\n box-shadow: var(--test-shadow-md);\n}\n\n.result-hero.passed .result-icon { color: var(--test-success); }\n.result-hero.failed .result-icon { color: var(--test-error); }\n.result-hero.error .result-icon { color: var(--test-warning); }\n.result-hero.timeout .result-icon { color: var(--test-timeout); }\n.result-hero.running .result-icon,\n.result-hero.pending .result-icon { color: var(--test-primary); }\n\n.result-pulse {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 100px;\n height: 100px;\n border-radius: 50%;\n background: rgba(59, 130, 246, 0.2);\n animation: pulse 2s ease-in-out infinite;\n}\n\n@keyframes pulse {\n 0%, 100% { transform: translate(-50%, -50%) scale(1); opacity: 0.5; }\n 50% { transform: translate(-50%, -50%) scale(1.2); opacity: 0; }\n}\n\n.result-text h2 {\n margin: 0 0 12px 0;\n font-size: clamp(24px, 5vw, 32px);\n font-weight: 800;\n color: var(--test-text);\n}\n\n.result-details {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.result-score {\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text-secondary);\n}\n\n.result-divider {\n color: var(--test-border);\n}\n\n.result-checks {\n font-size: 16px;\n color: var(--test-text-muted);\n}\n\n/* Section Headers */\n.section-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 16px;\n gap: 12px;\n}\n\n.section-header h3 {\n margin: 0;\n font-size: 18px;\n font-weight: 700;\n color: var(--test-text);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.section-header h3 i {\n color: var(--test-primary);\n}\n\n.section-header.error h3 i {\n color: var(--test-error);\n}\n\n.check-summary {\n font-size: 13px;\n color: var(--test-text-secondary);\n}\n\n/* Check Results Section */\n.check-results {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.check-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.check-item {\n display: flex;\n gap: 12px;\n padding: 14px 16px;\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n transition: var(--test-transition);\n animation: fadeIn 0.3s ease-out backwards;\n}\n\n.check-item:hover {\n transform: translateX(4px);\n}\n\n.check-item.passed {\n background: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%);\n border-color: #86efac;\n}\n\n.check-item.failed {\n background: linear-gradient(135deg, #fef2f2 0%, #fee2e2 100%);\n border-color: #fca5a5;\n}\n\n.check-status {\n font-size: 20px;\n flex-shrink: 0;\n margin-top: 2px;\n}\n\n.check-item.passed .check-status { color: var(--test-success); }\n.check-item.failed .check-status { color: var(--test-error); }\n\n.check-content {\n flex: 1;\n min-width: 0;\n}\n\n.check-name {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 4px;\n}\n\n.check-message {\n font-size: 13px;\n color: var(--test-text-secondary);\n line-height: 1.5;\n word-wrap: break-word;\n}\n\n.check-weight {\n font-size: 12px;\n color: var(--test-text-muted);\n flex-shrink: 0;\n text-align: right;\n}\n\n.weight-label {\n font-weight: 500;\n}\n\n/* Comparison Section */\n.comparison-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.comparison-tabs {\n display: flex;\n gap: 4px;\n margin-bottom: 16px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n padding: 4px;\n}\n\n.comparison-tab {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 10px 16px;\n border: none;\n background: transparent;\n color: var(--test-text-secondary);\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n border-radius: var(--test-radius-sm);\n transition: var(--test-transition);\n}\n\n.comparison-tab:hover {\n color: var(--test-text);\n background: rgba(0, 0, 0, 0.05);\n}\n\n.comparison-tab.active {\n background: var(--test-surface);\n color: var(--test-primary);\n font-weight: 600;\n box-shadow: var(--test-shadow-sm);\n}\n\n.comparison-content {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n}\n\n/* ===========================\n Details Tab\n =========================== */\n.details-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: fadeIn 0.3s ease-out;\n}\n\n.details-grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n gap: 12px;\n}\n\n.detail-card {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n transition: var(--test-transition);\n}\n\n.detail-card.clickable {\n cursor: pointer;\n}\n\n.detail-card.clickable:hover {\n background: rgba(37, 99, 235, 0.05);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n}\n\n.detail-icon {\n width: 44px;\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n color: var(--test-primary);\n font-size: 18px;\n flex-shrink: 0;\n}\n\n.detail-content {\n flex: 1;\n min-width: 0;\n}\n\n.detail-label {\n font-size: 11px;\n font-weight: 700;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: var(--test-text-muted);\n margin-bottom: 4px;\n}\n\n.detail-value {\n font-size: 14px;\n color: var(--test-text);\n word-wrap: break-word;\n font-weight: 500;\n}\n\n.detail-value.monospace {\n font-family: 'SF Mono', Monaco, 'Courier New', monospace;\n font-size: 12px;\n}\n\n.detail-value.link {\n color: var(--test-primary);\n}\n\n.detail-action {\n color: var(--test-text-muted);\n font-size: 12px;\n transition: var(--test-transition);\n}\n\n.detail-card.clickable:hover .detail-action {\n color: var(--test-primary);\n}\n\n/* Error Section */\n.error-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.error-content {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid #fca5a5;\n}\n\n/* Result Details Section */\n.result-details-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.result-details-content {\n border-radius: var(--test-radius-md);\n overflow: hidden;\n border: 1px solid var(--test-border);\n}\n\n/* ===========================\n AI Runs Tab\n =========================== */\n.ai-runs-tab {\n display: flex;\n flex-direction: column;\n gap: 20px;\n animation: fadeIn 0.3s ease-out;\n}\n\n.ai-section {\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n padding: 24px;\n box-shadow: var(--test-shadow-sm);\n}\n\n.count-badge {\n background: var(--test-bg);\n color: var(--test-text-secondary);\n padding: 4px 10px;\n border-radius: 12px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.ai-run-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n}\n\n.ai-run-card {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.ai-run-card:hover {\n background: rgba(37, 99, 235, 0.05);\n border-color: var(--test-primary-light);\n transform: translateX(4px);\n box-shadow: var(--test-shadow-sm);\n}\n\n.ai-run-icon {\n width: 44px;\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, var(--test-primary) 0%, var(--test-primary-dark) 100%);\n color: white;\n border-radius: var(--test-radius-md);\n font-size: 18px;\n flex-shrink: 0;\n box-shadow: var(--test-shadow-sm);\n}\n\n.ai-run-icon.agent {\n background: linear-gradient(135deg, var(--test-primary) 0%, var(--test-primary-dark) 100%);\n}\n\n.ai-run-icon.prompt {\n background: linear-gradient(135deg, #9333ea 0%, #7c3aed 100%);\n}\n\n.ai-run-content {\n flex: 1;\n min-width: 0;\n}\n\n.ai-run-name {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n margin-bottom: 6px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.ai-run-meta {\n display: flex;\n gap: 10px;\n font-size: 12px;\n color: var(--test-text-secondary);\n flex-wrap: wrap;\n}\n\n.status-chip {\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n}\n\n.status-chip.complete,\n.status-chip.completed,\n.status-chip.passed {\n background: var(--test-success-light);\n color: #059669;\n}\n\n.status-chip.failed,\n.status-chip.error {\n background: var(--test-error-light);\n color: #dc2626;\n}\n\n.status-chip.running {\n background: #dbeafe;\n color: var(--test-primary);\n}\n\n.cost-chip {\n display: inline-flex;\n align-items: center;\n gap: 2px;\n color: var(--test-text-muted);\n}\n\n.ai-run-arrow {\n color: var(--test-text-muted);\n font-size: 14px;\n transition: var(--test-transition);\n}\n\n.ai-run-card:hover .ai-run-arrow {\n color: var(--test-primary);\n transform: translateX(2px);\n}\n\n/* ===========================\n Feedback Tab\n =========================== */\n.feedback-tab {\n animation: fadeIn 0.3s ease-out;\n}\n\n.feedback-list {\n display: flex;\n flex-direction: column;\n gap: 16px;\n}\n\n.feedback-item {\n padding: 20px;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n border: 1px solid var(--test-border);\n box-shadow: var(--test-shadow-sm);\n transition: var(--test-transition);\n}\n\n.feedback-item:hover {\n border-color: var(--test-primary-light);\n}\n\n.feedback-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 16px;\n flex-wrap: wrap;\n gap: 8px;\n}\n\n.feedback-user {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.user-avatar {\n width: 36px;\n height: 36px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n color: var(--test-primary);\n font-size: 14px;\n}\n\n.user-name {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.feedback-date {\n font-size: 12px;\n color: var(--test-text-muted);\n}\n\n.feedback-body {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.feedback-rating {\n display: flex;\n align-items: center;\n gap: 12px;\n}\n\n.rating-stars {\n display: flex;\n gap: 2px;\n}\n\n.rating-stars i {\n font-size: 14px;\n color: var(--test-border);\n}\n\n.rating-stars i.filled {\n color: #fbbf24;\n}\n\n.rating-value {\n font-size: 14px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.feedback-verdict {\n display: flex;\n}\n\n.verdict-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 6px 12px;\n border-radius: 20px;\n font-size: 12px;\n font-weight: 600;\n}\n\n.verdict-badge.correct {\n background: var(--test-success-light);\n color: #059669;\n}\n\n.verdict-badge.incorrect {\n background: var(--test-error-light);\n color: #dc2626;\n}\n\n.feedback-comments {\n padding: 14px;\n background: var(--test-bg);\n border-radius: var(--test-radius-md);\n border-left: 3px solid var(--test-primary);\n}\n\n.feedback-comments p {\n margin: 0;\n font-size: 14px;\n line-height: 1.6;\n color: var(--test-text);\n}\n\n/* ===========================\n Log Tab\n =========================== */\n.log-tab {\n display: flex;\n flex-direction: column;\n gap: 0;\n height: 100%;\n animation: fadeIn 0.3s ease-out;\n}\n\n.log-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n background: var(--test-surface);\n padding: 16px 20px;\n border-radius: var(--test-radius-lg) var(--test-radius-lg) 0 0;\n border: 1px solid var(--test-border);\n border-bottom: none;\n}\n\n.log-title {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n\n.log-title i {\n color: var(--test-text-secondary);\n font-size: 16px;\n}\n\n.log-title h3 {\n margin: 0;\n font-size: 16px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.log-actions {\n display: flex;\n gap: 8px;\n}\n\n.log-container {\n flex: 1;\n border-radius: 0 0 var(--test-radius-lg) var(--test-radius-lg);\n overflow: hidden;\n min-height: 300px;\n border: 1px solid var(--test-border);\n border-top: none;\n}\n\n/* ===========================\n Loading States & Skeletons\n =========================== */\n.loading-state {\n padding: 20px;\n}\n\n.skeleton-list {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.skeleton-card {\n display: flex;\n align-items: center;\n gap: 14px;\n padding: 16px;\n background: var(--test-surface);\n border-radius: var(--test-radius-md);\n border: 1px solid var(--test-border);\n}\n\n.skeleton-icon,\n.skeleton-avatar {\n width: 44px;\n height: 44px;\n border-radius: var(--test-radius-md);\n background: linear-gradient(90deg, #e2e8f0 25%, #f1f5f9 50%, #e2e8f0 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-avatar {\n border-radius: 50%;\n}\n\n.skeleton-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.skeleton-line {\n height: 14px;\n border-radius: 4px;\n background: linear-gradient(90deg, #e2e8f0 25%, #f1f5f9 50%, #e2e8f0 75%);\n background-size: 200% 100%;\n animation: shimmer 1.5s infinite;\n}\n\n.skeleton-line.wide { width: 70%; }\n.skeleton-line.medium { width: 55%; }\n.skeleton-line.narrow { width: 40%; }\n\n@keyframes shimmer {\n 0% { background-position: 200% 0; }\n 100% { background-position: -200% 0; }\n}\n\n/* ===========================\n Empty States\n =========================== */\n.empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 60px 24px;\n text-align: center;\n background: var(--test-surface);\n border-radius: var(--test-radius-lg);\n}\n\n.empty-icon {\n width: 80px;\n height: 80px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-bg);\n border-radius: 50%;\n margin-bottom: 20px;\n}\n\n.empty-icon i {\n font-size: 36px;\n color: var(--test-text-muted);\n}\n\n.empty-state h3 {\n margin: 0 0 8px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--test-text);\n}\n\n.empty-state p {\n margin: 0;\n font-size: 14px;\n color: var(--test-text-secondary);\n max-width: 300px;\n}\n\n/* ===========================\n Keyboard Shortcuts Help\n =========================== */\n.shortcuts-hint {\n position: fixed;\n bottom: 20px;\n right: 20px;\n z-index: 100;\n}\n\n.shortcuts-hint > i {\n width: 40px;\n height: 40px;\n display: flex;\n align-items: center;\n justify-content: center;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: 50%;\n color: var(--test-text-muted);\n font-size: 16px;\n cursor: pointer;\n box-shadow: var(--test-shadow-md);\n transition: var(--test-transition);\n}\n\n.shortcuts-hint:hover > i {\n color: var(--test-primary);\n border-color: var(--test-primary-light);\n}\n\n.shortcuts-popup {\n display: none;\n position: absolute;\n bottom: 50px;\n right: 0;\n background: var(--test-surface);\n border: 1px solid var(--test-border);\n border-radius: var(--test-radius-md);\n padding: 16px;\n box-shadow: var(--test-shadow-lg);\n min-width: 200px;\n}\n\n.shortcuts-hint:hover .shortcuts-popup {\n display: block;\n animation: fadeIn 0.2s ease-out;\n}\n\n.shortcuts-popup h4 {\n margin: 0 0 12px 0;\n font-size: 14px;\n font-weight: 700;\n color: var(--test-text);\n}\n\n.shortcuts-popup ul {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.shortcuts-popup li {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 6px 0;\n font-size: 13px;\n color: var(--test-text-secondary);\n}\n\n.shortcuts-popup kbd {\n background: var(--test-bg);\n border: 1px solid var(--test-border);\n border-radius: 4px;\n padding: 2px 6px;\n font-family: -apple-system, BlinkMacSystemFont, sans-serif;\n font-size: 11px;\n color: var(--test-text);\n}\n\n/* ===========================\n Responsive Design - Tablet\n =========================== */\n@media (max-width: 1024px) {\n .metrics-bar {\n grid-template-columns: repeat(3, 1fr);\n }\n\n .details-grid {\n grid-template-columns: repeat(2, 1fr);\n }\n\n .shortcuts-hint {\n display: none;\n }\n}\n\n/* ===========================\n Responsive Design - Mobile\n =========================== */\n@media (max-width: 768px) {\n .test-run-form {\n height: auto;\n min-height: 100%;\n }\n\n .test-run-header {\n padding: 16px;\n }\n\n .breadcrumb {\n margin-bottom: 12px;\n }\n\n .breadcrumb ol {\n font-size: 12px;\n }\n\n .header-content {\n flex-direction: column;\n gap: 16px;\n }\n\n .header-left {\n width: 100%;\n }\n\n .status-indicator {\n width: 48px;\n height: 48px;\n font-size: 20px;\n }\n\n .test-run-info h1 {\n font-size: 18px;\n }\n\n .test-run-meta {\n gap: 8px;\n }\n\n .status-badge {\n padding: 4px 10px;\n font-size: 11px;\n }\n\n .header-actions {\n width: 100%;\n justify-content: stretch;\n }\n\n .header-actions button {\n flex: 1;\n }\n\n .metrics-bar {\n grid-template-columns: repeat(2, 1fr);\n gap: 10px;\n }\n\n .metric-card {\n padding: 12px;\n }\n\n .metric-icon {\n width: 36px;\n height: 36px;\n font-size: 14px;\n }\n\n .metric-value {\n font-size: 14px;\n }\n\n .tabs {\n padding: 0 12px;\n }\n\n .tab {\n padding: 12px 14px;\n font-size: 13px;\n gap: 6px;\n }\n\n .tab i {\n font-size: 14px;\n }\n\n .shortcut-hint {\n display: none;\n }\n\n .tab-content {\n padding: 16px;\n }\n\n .result-hero {\n padding: 24px 20px;\n }\n\n .result-icon {\n width: 64px;\n height: 64px;\n font-size: 32px;\n }\n\n .result-text h2 {\n font-size: 24px;\n }\n\n .result-score {\n font-size: 16px;\n }\n\n .check-results,\n .comparison-section,\n .ai-section,\n .feedback-item {\n padding: 18px;\n }\n\n .check-item {\n padding: 12px;\n }\n\n .comparison-tabs {\n flex-direction: column;\n gap: 4px;\n }\n\n .comparison-tab {\n text-align: center;\n }\n\n .details-grid {\n grid-template-columns: 1fr;\n }\n\n .detail-card {\n padding: 14px;\n }\n\n .ai-run-card {\n padding: 14px;\n }\n\n .ai-run-icon {\n width: 40px;\n height: 40px;\n font-size: 16px;\n }\n\n .ai-run-meta {\n flex-direction: column;\n gap: 4px;\n }\n\n .feedback-header {\n flex-direction: column;\n align-items: flex-start;\n }\n\n .log-header {\n flex-direction: column;\n gap: 12px;\n align-items: stretch;\n }\n\n .log-actions {\n justify-content: stretch;\n }\n\n .log-actions button {\n flex: 1;\n }\n\n .empty-state {\n padding: 40px 20px;\n }\n\n .empty-icon {\n width: 64px;\n height: 64px;\n }\n\n .empty-icon i {\n font-size: 28px;\n }\n}\n\n/* ===========================\n Responsive Design - Small Mobile\n =========================== */\n@media (max-width: 480px) {\n .test-run-header {\n padding: 12px;\n }\n\n .header-left {\n gap: 12px;\n }\n\n .status-indicator {\n width: 40px;\n height: 40px;\n font-size: 18px;\n border-radius: 8px;\n }\n\n .test-run-info h1 {\n font-size: 16px;\n }\n\n .metrics-bar {\n grid-template-columns: 1fr 1fr;\n }\n\n .metric-card {\n padding: 10px;\n flex-direction: column;\n text-align: center;\n }\n\n .metric-icon {\n margin-bottom: 8px;\n }\n\n .metric-label {\n font-size: 9px;\n }\n\n .metric-value {\n font-size: 14px;\n }\n\n .tabs {\n padding: 0 8px;\n }\n\n .tab {\n padding: 10px 12px;\n font-size: 12px;\n }\n\n .tab-badge {\n display: none;\n }\n\n .tab-content {\n padding: 12px;\n }\n\n .result-hero {\n padding: 20px 16px;\n }\n\n .result-icon {\n width: 56px;\n height: 56px;\n font-size: 28px;\n }\n\n .result-text h2 {\n font-size: 20px;\n }\n\n .result-score {\n font-size: 14px;\n }\n\n .result-checks {\n font-size: 12px;\n }\n\n .section-header h3 {\n font-size: 16px;\n }\n\n .check-item {\n flex-direction: column;\n gap: 8px;\n }\n\n .check-weight {\n text-align: left;\n }\n}\n\n/* ===========================\n Touch Device Optimizations\n =========================== */\n@media (hover: none) and (pointer: coarse) {\n .tab,\n .comparison-tab,\n .ai-run-card,\n .check-item,\n .feedback-item,\n .detail-card.clickable {\n -webkit-tap-highlight-color: transparent;\n }\n\n .ai-run-card:active,\n .detail-card.clickable:active {\n background: rgba(37, 99, 235, 0.1);\n transform: scale(0.98);\n }\n\n .tab:active {\n background: rgba(37, 99, 235, 0.1);\n }\n\n /* Larger touch targets */\n .tab {\n min-height: 48px;\n }\n\n .ai-run-card,\n .detail-card {\n min-height: 64px;\n }\n}\n\n/* ===========================\n High Contrast Mode\n =========================== */\n@media (prefers-contrast: high) {\n .status-badge {\n border: 2px solid currentColor;\n }\n\n .check-item {\n border-width: 2px;\n }\n\n .tab.active {\n border-bottom-width: 4px;\n }\n}\n\n/* ===========================\n Reduced Motion\n =========================== */\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n\n .skeleton-icon,\n .skeleton-avatar,\n .skeleton-line {\n animation: none;\n background: #e2e8f0;\n }\n\n .result-pulse {\n animation: none;\n display: none;\n }\n}\n\n/* ===========================\n Print Styles\n =========================== */\n@media print {\n .test-run-form {\n background: white;\n height: auto;\n }\n\n .header-actions,\n .tabs-container,\n .shortcuts-hint,\n .log-actions {\n display: none !important;\n }\n\n .tab-content {\n overflow: visible;\n padding: 0;\n }\n\n .result-hero,\n .check-results,\n .details-grid,\n .ai-section,\n .feedback-item {\n break-inside: avoid;\n box-shadow: none;\n border: 1px solid #ddd;\n }\n\n .comparison-content,\n .log-container {\n max-height: none;\n overflow: visible;\n }\n}\n\n/* ===========================\n Tags Bar - Sleek Inline Display\n =========================== */\n.tags-bar {\n margin-top: 16px;\n padding: 8px 14px;\n background: linear-gradient(135deg, rgba(37, 99, 235, 0.04) 0%, rgba(37, 99, 235, 0.08) 100%);\n border: 1px solid rgba(37, 99, 235, 0.15);\n border-radius: 8px;\n max-width: 600px;\n}\n\n.tags-bar-content {\n display: flex;\n align-items: center;\n gap: 10px;\n flex-wrap: wrap;\n}\n\n.tags-bar-label {\n color: var(--test-text-secondary);\n font-size: 14px;\n}\n\n.tags-bar-label i {\n opacity: 0.6;\n}\n\n.tags-bar-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n flex: 1;\n}\n\n.tag-inline {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n background: rgba(37, 99, 235, 0.1);\n color: var(--test-primary);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n letter-spacing: 0.01em;\n}\n\n.tags-bar-empty {\n font-size: 12px;\n color: var(--test-text-secondary);\n opacity: 0.7;\n flex: 1;\n}\n\n.tags-bar-edit {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 4px 10px;\n background: transparent;\n border: 1px dashed var(--test-border);\n border-radius: 12px;\n font-size: 11px;\n font-weight: 500;\n color: var(--test-text-secondary);\n cursor: pointer;\n transition: var(--test-transition);\n}\n\n.tags-bar-edit:hover {\n border-color: var(--test-primary);\n color: var(--test-primary);\n background: rgba(37, 99, 235, 0.05);\n}\n\n.tags-bar-edit i {\n font-size: 10px;\n}\n\n/* ===========================\n Tags Editor Panel - Expanded Edit Mode\n =========================== */\n.tags-editor-panel {\n margin-top: 16px;\n background: var(--test-surface);\n border: 1px solid var(--test-primary);\n border-radius: var(--test-radius-md);\n overflow: hidden;\n box-shadow: 0 4px 12px rgba(37, 99, 235, 0.1);\n max-width: 600px;\n}\n\n.tags-editor-header {\n display: flex;\n align-items: center;\n padding: 12px 16px;\n background: rgba(37, 99, 235, 0.08);\n border-bottom: 1px solid rgba(37, 99, 235, 0.2);\n}\n\n.tags-editor-title {\n font-size: 13px;\n font-weight: 600;\n color: var(--test-primary);\n display: flex;\n align-items: center;\n gap: 8px;\n}\n\n.tags-editor-body {\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.tags-editor-chips {\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n min-height: 32px;\n}\n\n.tag-editable {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 8px 5px 12px;\n background: var(--test-surface);\n border: 1px solid var(--test-primary);\n color: var(--test-primary);\n border-radius: 14px;\n font-size: 12px;\n font-weight: 500;\n}\n\n.tag-remove-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n background: transparent;\n border: none;\n color: var(--test-primary);\n cursor: pointer;\n border-radius: 50%;\n font-size: 9px;\n opacity: 0.6;\n transition: var(--test-transition);\n}\n\n.tag-remove-btn:hover {\n opacity: 1;\n background: var(--test-error-light);\n color: var(--test-error);\n}\n\n.tags-empty-hint {\n font-size: 12px;\n color: var(--test-text-secondary);\n font-style: italic;\n padding: 4px 0;\n}\n\n.tags-editor-input {\n display: flex;\n gap: 8px;\n align-items: center;\n}\n\n.tag-text-input {\n flex: 1;\n padding: 10px 14px;\n border: 1px solid var(--test-border);\n border-radius: 8px;\n font-size: 13px;\n background: var(--test-bg);\n}\n\n.tag-text-input:focus {\n outline: none;\n border-color: var(--test-primary);\n background: var(--test-surface);\n box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);\n}\n\n.tag-text-input::placeholder {\n color: var(--test-text-secondary);\n opacity: 0.6;\n}\n\n.tags-editor-footer {\n display: flex;\n justify-content: flex-start;\n gap: 8px;\n padding: 12px 16px;\n background: var(--test-bg);\n border-top: 1px solid var(--test-border);\n}\n\n/* Mobile Responsive for Tags */\n@media (max-width: 768px) {\n .tags-bar {\n padding: 8px 12px;\n }\n\n .tags-bar-content {\n gap: 8px;\n }\n\n .tag-inline {\n padding: 3px 8px;\n font-size: 10px;\n }\n\n .tags-editor-panel {\n margin-top: 12px;\n }\n\n .tags-editor-body {\n padding: 12px;\n }\n\n .tags-editor-footer {\n padding: 10px 12px;\n }\n}\n"] }]
1565
+ }], () => [{ type: i0.ElementRef }, { type: i1.SharedService }, { type: i2.Router }, { type: i2.ActivatedRoute }, { type: i0.ChangeDetectorRef }, { type: i3.TestingDialogService }, { type: i1.NavigationService }, { type: i4.ApplicationManager }, { type: i0.ViewContainerRef }], { handleKeyboardShortcut: [{
1566
+ type: HostListener,
1567
+ args: ['document:keydown', ['$event']]
1568
+ }] }); })();
1569
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TestRunFormComponentExtended, { className: "TestRunFormComponentExtended", filePath: "src/lib/custom/Tests/test-run-form.component.ts", lineNumber: 36 }); })();
917
1570
  export function LoadTestRunFormComponentExtended() {
918
1571
  // Prevents tree-shaking
919
1572
  }